CW32

无刷电机是一种新型的电机,其特点是不需要刷子进行转子与定子的电接触。相比于传统电机,无刷电机具有更高的效率、更小的体积和更长的寿命。本文将从工作原理、组成结构和与传统电机的区别三个方面来详细介绍无刷电机的特点。

1.png

2.png

图1 网上的无刷电机

首先,无刷电机的工作原理是基于电磁感应和电子控制。无刷电机的转子是由永磁体组成,定子则是由线圈组成。当电流通过定子线圈时,会产生一个磁场,这个磁场会与转子永磁体的磁场相互作用,从而使转子开始旋转。在转子旋转的同时,电子控制器会监测转子的位置和速度,并控制定子线圈的电流,从而保证电机的稳定运行。

其次,无刷电机的组成结构也有所不同。传统电机的转子是由电刷和电极组成,而无刷电机的转子则是由永磁体和磁传感器组成。此外,无刷电机还需要电子控制器来控制电流和转子的位置和速度。这些特殊的组成结构使得无刷电机具有更高的效率和更长的寿命。

最后,无刷电机与传统电机的区别在于其效率、体积和寿命。无刷电机的效率比传统电机高出约10%至20%,这是由于无刷电机不需要电刷进行转子与定子的电接触,从而减少了摩擦和能量损失。此外,无刷电机的体积也比传统电机小,这是由于无刷电机的转子不需要电刷,从而减少了转子的体积。最后,无刷电机的寿命也比传统电机长,这是由于无刷电机不需要电刷进行电接触,从而减少了电刷的磨损和寿命。

3.png

图2 无刷直流电机结构示意图

综上所述,无刷电机具有高效、小巧和长寿命等特点。随着无刷电机技术的不断发展,无刷电机将在越来越多的领域得到应用,如电动汽车、无人机、机器人等。

所以在各个行业运用无刷电机会越来越多,本次会用基于CW32芯片之下开发一款可以应用于大多数场景的一款水泵。现在对于水泵要求越来越高,所以我们改进水泵的工作模式,使水泵工作于最优工作点,降低功耗,就能实现水泵系统的节能,即节约电能和水能,给企业带来效益,同时也能提升竞争力。

在系统中,水泵的运行是靠无刷直流电机来带动的。本课题研究的目的是设计一套基于 CW32 的无位置传感器无刷直流电机控制系统(方波控制模式),既可以改进水泵的工作模式,使水泵工作点最优;又可以使水泵电机结构简单,控制方式更为灵活。以此将整个系统加入各个不同场景中,让CW32低功耗的优点,能让水泵共更加节能,高效。

本文设计一个小型水泵循环控制系统,该系统中带动水泵运行的电机的额定电压是48V,额定功率为500W。控制系统是基于CW32处理器,采用反电势过零检测方法对转子位置进行检测,从而实现对电机的换向控制。水泵控制系统中,采用无位置传感器无刷直流电机来带动水泵运行,不但缩小了水泵体积,而且增强了水泵运行时电机的抗干扰性和稳定可靠性。使水泵工作于最优工作点,尽可能使运行功率降低,改变了水泵一直满功率运行的状况,降低了功耗,实现了水泵系统的节能。

来源:CW32生态社区

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 49

资料链接如下:

BD网盘链接:

https://pan.baidu.com/s/1IsFqi-bdPQcilu71JMrsVA 

提取码:n99y

1. DS1302是一款集成了实时时钟(RTC)功能的芯片。RTC是一种能够精确测量和跟踪时间的电子设备,可以提供准确的日期和时间信息。DS1302实时时钟芯片由Maxim Integrated(美信半导体)生产,具有以下主要特点:

①时钟精度:DS1302采用32.768kHz的晶体振荡器来提供基准时钟信号。它具有较高的时钟精度,使得它可以提供准确的时间信息,每月的时间偏差非常小。

②时钟和日历功能:DS1302可以跟踪秒、分钟、小时、日期、月份和年份。它提供了完整的时钟和日历功能,可以准确地记录时间和日期。

③低功耗设计:DS1302芯片采用了低功耗设计,因此在电池供电时可以提供长时间的运行时间。

④数据保持功能:DS1302具有数据保持功能,使得即使在电源断电的情况下,时钟和日历数据仍然可以得到保持,确保数据的可靠性和连续性。

⑤简化的接口:DS1302通过串行接口(2线或3线),与微控制器或其他外部设备进行通信。这种简化的接口使得它更容易与其他系统集成,实现实时时钟功能。

DS1302实时时钟芯片被广泛应用于各种应用领域,如电子设备、仪器仪表、自动化系统、安防系统等需要准确时间信息的场合。它的易用性、低功耗以及稳定的性能使得它成为常用的实时时钟解决方案之一。

2.本实验用到了CW32 Cortex-M实训套件实验箱、DS1302实时时钟模块及Keil5开发环境。

1.png

CW32 Cortex-M实训套件

2.png

DS1302实时时钟模块实物

3.png

DS1302原理图

3.DS1302具体工作原理可观看视频,或参考以下链接中的文章

https://blog.csdn.net/u013184273/article/details/78843881

4.核心代码

/*
用TFT屏幕显示年、月、日、星期、时、分、秒
显示界面如下:
----------------
DS1302 Real Time 

Year :xxxx
Month:xx
Day  :xx
Week :xx
xx:xx:xx

----------------
*/

#include "main.h"
#include "config.h"
#include "Ds1302.h"        //DS1302底层驱动代码
#include "Lcd_Driver.h"
#include "LCD_calculate.h"

char strings[2];         //储存要显示的数字

int main()
{  
    u8 value = 0;   
    
    RCC_Configuration(); //配置时钟   
    
    Lcd_Init();  
    Lcd_Clear(GRAY0);   
    
    Ds1302_GPIO_Init();  //GPIO配置 
    
    //  Ds1302_Config(23,7,7,5,14,58,55); //初始化DS1302,2023年7月7日星期五23点59分55秒   

    Gui_DrawFont_GBK16(0,0,WHITE,RED,"DS1302 Real Time"); //显示界面  
    Gui_DrawFont_GBK16(0,32,WHITE,RED,"Year :20  ");  
    Gui_DrawFont_GBK16(0,48,WHITE,RED,"Month:    ");  
    Gui_DrawFont_GBK16(0,64,WHITE,RED,"Day  :    ");  
    Gui_DrawFont_GBK16(0,80,WHITE,RED,"Week :    ");  
    Gui_DrawFont_GBK16(0,96,WHITE,RED,"  :  :    ");   

    while(1)  
    {        
        Ds1302_GetHour(&value);                  //小时    
        sprintf(strings,"%d",value/10);    
        Gui_DrawFont_GBK16(0,96,WHITE,RED,strings);    
        sprintf(strings,"%d",value%10);    
        Gui_DrawFont_GBK16(8,96,WHITE,RED,strings);     
    
        Ds1302_GetMinite(&value);                //分钟    
        sprintf(strings,"%d",value/10);    
        Gui_DrawFont_GBK16(24,96,WHITE,RED,strings);    
        sprintf(strings,"%d",value%10);    
        Gui_DrawFont_GBK16(32,96,WHITE,RED,strings);     
        
        Ds1302_GetSecond(&value);                //秒钟    
        sprintf(strings,"%d",value/10);    
        Gui_DrawFont_GBK16(48,96,WHITE,RED,strings);    
        sprintf(strings,"%d",value%10);    
        Gui_DrawFont_GBK16(56,96,WHITE,RED,strings);       
    
        Ds1302_GetDay(&value);                  //星期    
        sprintf(strings,"%d",value/10);    
        Gui_DrawFont_GBK16(40+8,80,WHITE,RED,strings);    
        sprintf(strings,"%d",value%10);    
        Gui_DrawFont_GBK16(48+8,80,WHITE,RED,strings);     
    
        Ds1302_GetDate(&value);                 //日期    
        sprintf(strings,"%d",value/10);    
        Gui_DrawFont_GBK16(32+16,64,WHITE,RED,strings);    
        sprintf(strings,"%d",value%10);    
        Gui_DrawFont_GBK16(40+16,64,WHITE,RED,strings);    
       
        Ds1302_GetMonth(&value);                //月份    
        sprintf(strings,"%d",value/10);    
        Gui_DrawFont_GBK16(48,48,WHITE,RED,strings);    
        sprintf(strings,"%d",value%10);    
        Gui_DrawFont_GBK16(55,48,WHITE,RED,strings);     
    
        Ds1302_GetYear(&value);                 //年份    
        sprintf(strings,"%d",value/10);    
        Gui_DrawFont_GBK16(56+8,32,WHITE,RED,strings);    
        sprintf(strings,"%d",value%10);    
        Gui_DrawFont_GBK16(64+8,32,WHITE,RED,strings);  
    }
}

5.实验最终现象

把程序下载进DS1302模块,DS1302经过程序初始化后将开始计时。

4.png

实验箱接线 

5.png

显示时间   

 6.png

断电30s重新上电  

来源:CW32生态社区

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 6

1.利用NTC热敏电阻来采集温度具有高灵敏度、快速响应、宽温度测量范围和成本效益高等优势,这使得它成为许多应用中常用的温度传感器之一。

本期视频就来讲解基于CW32热敏电阻采集温度的应用。

资料链接如下:

BD网盘链接:

https://pan.baidu.com/s/1BBQ_7AmfirJPsXr2zxaOJw

提取码:6bc3

2.本实验用到了CW32 Cortex-M实训套件实验箱、NTC热敏电阻及Keil5开发环境。

1.png

CW32 Cortex-M实训套件

2.png

NTC热敏电阻实物

3.png

热敏电阻原理图

4.png

热敏电阻主要技术参数

5.png

6.png

7.png

3.NTC具体原理可观看视频,或参考以下链接中的文章

https://zhuanlan.zhihu.com/p/179181715

4.核心代码

/*

用TFT屏幕显示

1.热敏电阻的阻值

2.转换得到的温度

显示界面如下

-----------------------        
    NTC
  R:****   
  Tempture:****
-----------------------
*/

#include "main.h"
#include "table.h"   //阻温表
#include "config.h"
#include "LCD_calculate.h"
#include "Lcd_Driver.h"

char temp[10];  
unsigned char cnt = 0;
float dat_AD = 0;  //ADC采集电压
int R = 0;  //电阻值
float tempture = 0; //温度

void ADC_Configuration(void); // ADC初始化配置
float Get_ADC(void);  //采集电压值

int main()
{    
   unsigned char max,min,mid;    
   unsigned  int temp;  
   char strings[10];
  
  RCC_Configuration(); //时钟配置  A
  DC_Configuration(); //ADC配置
  
  Lcd_Init();          //TFT屏初始化配置  
  Lcd_Clear(GRAY0);    //清屏操作
  
  Gui_DrawFont_GBK16(0,0,WHITE,RED,"       NTC      "); //第一行:ADC TEST:  
  Gui_DrawFont_GBK16(0,32,WHITE,RED,"R:");             //第二行:R:  
  Gui_DrawFont_GBK16(0,48,WHITE,RED,"Temperature:"); //第三行:Temperature:
  
  while(1)  
  {        
     dat_AD = Get_ADC()*3.3/4095;  //单片机的参考电压为3.3V,12位的ADC    
     R = dat_AD*10000/(5-dat_AD);//VCC接5V,测得VCC实际电压值为4.58V,更为精准
    
    max = 97;  //温度上限97    
    min = 0;   //温度下限0
    
    while(1)   //二分查找法    
    {      
        mid = ( max + min ) / 2;      
        if( Table[mid] < R ) max = mid;      
        else min = mid;      
        if( (max-min) <= 1 ) break;    
    }
    
    if ( max == min ) tempture = min * 10;    
    else    
    {      
        temp = ( Table[min] - Table[max] ) / 10;  //计算温度的小数部分      
        temp = ( Table[min] - R ) / temp;           
        tempture = temp;       
        tempture = 10 * min + tempture;  //扩大十倍,方便计算    
    }    
    tempture /= 10;
    
    sprintf(strings,"%d",R);  //TFT显示阻值    
    Gui_DrawFont_GBK16(16,32,WHITE,RED,strings);    
    Gui_DrawFont_GBK16(48,32,WHITE,RED,"          ");
    
    sprintf(strings,"%.1f",tempture);    
    Gui_DrawFont_GBK16(96,48,WHITE,RED,strings); //TFT显示温度
    
    delay_ms(500);  
    }
}
float Get_ADC() //ADC采集
{  
   unsigned int temp_dat_adc = 0;
  ADC_SoftwareStartConvCmd(ENABLE);  
  while(ADC_GetITStatus(ADC_IT_EOC))  
  {    
      ADC_ClearITPendingBit(ADC_IT_EOC);          
      temp_dat_adc=ADC_GetConversionValue();        
  }  
  return   (float)temp_dat_adc;
}

5.实验最终现象

8.png

实验接线箱

9.jpg

来源:CW32生态社区

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 22

前言 

CW32 电容式触摸按键设计指南向客户提供一种利用 CW32 内部资源结合软件编程实现电容式触摸按键有效 触摸检测的方法。本指南的内容重点在于工作原理、软件检测过程以及调试指引。 

利用芯源半导体的 CW32 系列小规模 MCU 的 IO、比较器、定时器、高速高精度内置 RC 时钟源以及高算力 等功能,通过检测电路端子电容的微小变化和波动,实现电容式触摸按键功能。其外围电路简单,占用资源 比例不高,非常有利于用户在节约 BOM 成本的前提下拓展功能。结合适当的工业化设计,触摸按键比接触 式按键更美观、耐磨的同时,还具有防水、抗干扰、寿命长等多种优势。 

通过本文,您会了解到如何利用内置电压比较器和内置定时器及软件配合,实现灵活方便的按键检测。本文 在介绍标准演示板(如下图)和演示软件的性能参数的同时,还会给出详细的调试建议以及设计参数选择倾 向分析,用以帮助客户快速而自信地完成设计并实施调试。

1.png

1、 电容触摸检测基本原理

独立于电路的金属部件都能够作为电容触摸传感器使用,其原理在于金属部件附近存在手指时,相当于增加 了金属部件对地的旁路电容。因此,利用 CW32 系列 MCU 的 IO 口对金属部件充电,并检测电容放电时间的 变化,理论上能够辨别金属部件附近是否存在手指按压动作。当无手指存在时,金属部件的电容为 Cp,其放 电时间为 t1;当存在手指时,增加的旁路电容为 Cx,此时的放电时间为 t2,如下图所示,可以看出两者之间 的放电时间是不一样的:

2.png

2、 基于 CW32F003 的触摸按键方案简介

由于 CW32F003 集成了电压比较器 VC 和定时器,因此触摸按键方案可以通过软件来实现,其实现的原来框 图如下所示:

3.png

其过程如下:

1. GTIM 配置为门控计数方式,计数源为芯片内部的 PCLK 时钟。 

2. VC 比较器的同相端配置为按键的接口,反相段配置为参考,参考的来源为芯片的 VCC 通过内部电阻网 络分压得到,VC 比较器输出极性不反转。

3. GPIO 口配置为数字输出,输出高电平对电容充电。由于电容容值比较小,充电电流较大(图中红色箭 头所示),电容上的电压很快达到 VCC。

4. GTIM的计数器 CNT清 0,GPIO口配置为输入高阻态,电容上的电荷基本通过 R泄放(图中蓝色箭头所示), 需要一定的时间,此时电容上的电压要比 VC 比较器的反相端的电压高,VC 输出高电平,是 GTIM 的门 控信号有效,GTIM 进行计数。 

5. 当电容上的电压降低到比 VC 比较器的反相端的参考电压低时,VC 输出低电平,GTIM 停止计数,同时 VC 比较将产生一个中断信号,此时读取 GTIM 的 CNT 的计数值,和判决门限比较可以判断是否发生触 摸按键的事件。如下图所示:

4.png

3、 电容触摸检测电路软件过程

在范例程序中,软件定时(用定时器中断实现)对每个被测 IO 充电并检测放电时间 N 次,N 次循环检测后, 将统计结果提交滤波器状态机,得到按键当前状态。每次检测的具体过程如下: 

1. 将 IO 口置高 2 个机器周期,此时金属部件及电容 C 对 GND 的电压被充高到 VCC。 

2. 将 IO 口配置为电压比较器输入模式,此时 IO 口状态切换为高阻输入状态,金属部件及电容 C 通过对 GND 的旁路电阻 R 放电,端子电压变化曲线为标准的 RC 放电曲线。 

3. 软件记录循环定时器(GTIM 最高主频运行)的当前值,并等待电压比较器的输出翻转(电压比较器被 配置为与某电压门限比较)。

4. 电压比较器输出翻转后立即记录循环定时器当前值,并结合前次记录的时间记录输出结果。触摸检测过程的相关代码如下:

uint32_t TouchKey_GetValue(uint8_t key, uint8_t ref) 
{ 
    uint32_t CurTime; 
    //VC1  切换通道 
    CW_VC1->CR0_f.INP = key;       // 设置按键通道 
    CW_VC1->DIV_f.DIV = ref;     // 设置按键比较的参考比例 
    // 获取放电时间 
    CW_GPIOB->DIR &= ~((1UL<<8)>>key);   // 按键端口输出,对电容充电 
    __NOP(); 
    __NOP(); 
    CW_GTIM->CNT = 0x0000;        // 计数器清零 
    CW_GPIOB->DIR |= ((1UL<<8)>>key);   // 按键端口输入高阻 
    while((CW_VC1->SR_f.FLTV) == 1 );     // 等到放电到比较点 
    CurTime = CW_GTIM->CNT;        // 获取放电时间 
    return CurTime; 
}

4、 触摸参数及选型倾向 

为了保证检测流程顺利执行,需要选择每一个触摸按键的基础电容 C 和放电电阻 R 以及比较器参考门限 V。DEMO 中,这三个参数一般为 C=4.7pF,R=51KΩ,V=9/64 VDD。

C 和 R 的值,以及比较器参考门限 V 均可根据实际电路测试结果进行调整,调整考量如下: 

1. C 的容量增加会令放电时间更长,在检测程序中将会需要更多的机器周期等待比较器翻转。

2. C 的容量增加会显著增强电路稳定性但对检测灵敏度没有大的影响。 

3. R 的阻值增加会令放电时间更长,在检测程序中将会需要更多的机器周期等待比较器翻转。 

4. R 的阻值增加会降低电路稳定性(高阻易受环境干扰)但对检测灵敏度有明显帮助。 

5. 比较器参考门限 V 过高会降低检测灵敏度,但能节约检测时间。门限 V 过低会削弱抗干扰能力并浪费检 测时间。

5、 调试指引及性能参考 

5.1 示例软件框架介绍 

示例软件占用 1 个基本定时器,利用定时中断并在中断服务程序中执行按键检测过程、定时周期 10 毫秒。每次进入中断服务程序后,顺序扫描 M 个触摸按键的 RC 响应。 

顺序扫描 N 次后,将 RC 响应结果数据提交滤波器状态机。

滤波器状态机输出按键状态结果。

5.2 调试工具 TD_GetBaseResponseRCT 的使用 

示例软件提供一组标定工具来测量当前环境的 RC 响应,执行过程如下:

1. 在没有手指按下的情况下,执行 TD_GetBaseResponseRCT,函数的参数用于选择对应 IO,返回值作 为该按键的基础时长 TB。 

2. 在有手指按下的情况下,执行 TD_GetBaseResponseRCT,函数的参数用于选择对应 IO,返回值作为 该按键的信号时长 TS。 

注 1:每一个按键(IO)的 TB和 TS都应被单独收集并作为滤波器状态机的参数使用。 

注 2:各种温湿度条件下的 TB和 TS都应该在实验室中被采集并用于影响滤波器状态机的参数。 

注 3:比较器门限 V 也是可以针对每一个触摸按键单独选择的,如果某个按键的 TB和 TS无法实现明显的差异, 调节 C、R 和 V 将是唯一有效的途径。 

另:由于本例利用了高阻态 及小信号检测技术,触摸按键的布线要求尽量保持独立性,其金属部件、与 IO 的连线以及 RC 电路周围要尽量避免与其它电路并列共存,否则将大幅提高参数选择及调试难度直至无法完成。

5.3 性能参考

5.png

来源:武汉芯源半导体

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 17

模数转换器(ADC)的主要功能是将模拟量转换为数字量,方便MCU进行处理。下面以CW32L083为例介绍CW系列的模数转换器的特点和功能,并提供演示实例。

一、概述

CW32L083 内部集成一个 12 位精度、最高 1M SPS 转换速度的逐次逼近型模数转换器 (SAR ADC),最多可将 16 路模拟信号转换为数字信号。现实世界中的绝大多数信号都是模拟量,如光、电、声、图像信号等,都要由 ADC 转换成数字信号,才能由 MCU 进行数字化处理。

二、主要特性

• 12 位精度 

• 可编程转换速度,最高达 1M SPS 

• 16 路输入转换通道:13 路外部引脚输入 - 内置温度传感器 - 内置 BGR 1.2V 基准 - 1/3 VDDA 电源电压 

• 4 路参考电压源(Vref):- VDDA 电源电压 - ExRef(PB00)引脚电压 - 内置 1.5V 参考电压 - 内置 2.5V 参考电压 

• 采样电压输入范围:0 ~ Vref

 多种转换模式,全部支持转换累加功能 - 单次转换 - 多次转换 - 连续转换 - 序列扫描转换 - 序列断续转换 

• 支持单通道、序列通道两种通道选择,最大同时支持 8 个序列 

• 支持输入通道电压阈值监测

• 内置信号跟随器,可转换高阻抗输入信号 

• 支持片内外设自动触发 ADC 转换 

• 支持 ADC 转换完成触发 DMA

三、转换时序

ADC 的转换时序如下图所示:

1.png


向 ADC 控制寄存器 ADC_CR0 的 EN 位域写入 1,使能 ADC 模块。 

ADC_CR0.EN 由 0 变为 1 约 40μs 后 ADC_ISR.READY 标志位置 1,表示模拟电路初始化完成,可以开始进行 ADC 转换。 

向 ADC 启动寄存器 ADC_START 的 START 位域写入 1,启动 ADC 转换,转换完成后硬件自动清零。 

ADC 工作时钟 ADCCLK,由系统时钟 PCLK 经预分频器分频得到,通过控制寄存器 ADC_CR0 的 CLK 位域可选择 1 ~ 128 分频


四、工作模式

ADC 控制寄存器 ADC_CR0 的 MODE 位域配置 ADC 工作模式


启动 ADC 转换,可通过向 ADC 启动寄存器 ADC_START 的 START 位域写 1;也可通过其他外设来触发。

2.png

五、实际案例

GTIM1定时器定时1S,定时器1S中断触发启动ADC转换,采样AIN1,并通过GTIM2以PWM方波输出ADC采样值:PWM占空比50%,周期为1Hz-5000Hz,对应ADC的0-4095采样值。

1.配置ADC测试IO口

void ADC_PortInit(void) 
{ 
    REGBITS_SET(CW_SYSCTRL->AHBEN, SYSCTRL_AHBEN_GPIOA_Msk); //打开GPIO时钟 
    REGBITS_SET(CW_SYSCTRL->APBEN2, SYSCTRL_APBEN2_ADC_Msk); //打开ADC时钟 
    PA01_ANALOG_ENABLE();//set PA01 as AIN1 INPUT 
}

2.LED初始化

void LED_Init(void) 
{ 
    GPIO_InitTypeDef GPIO_InitStructure = {0}; 
    REGBITS_SET(CW_SYSCTRL->AHBEN, SYSCTRL_AHBEN_GPIOC_Msk); //打开GPIO时钟 
    /* Configure the GPIO_LED pin */ 
    GPIO_InitStructure.Pins = GPIO_PIN_2 | GPIO_PIN_3; 
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; 
    GPIO_Init(CW_GPIOC, &GPIO_InitStructure); 
    PC02_SETLOW();//LEDs are off. PC03_SETLOW(); 
}

3.PWM IO初始化

void PWM_PortInit(void) 
{ 
    GPIO_InitTypeDef GPIO_InitStructure = {0}; 
    /* PA5 PWM 输出 */ 
    __RCC_GPIOA_CLK_ENABLE(); 
    /* Configure the PWM output pin */ 
    GPIO_InitStructure.Pins = GPIO_PIN_5; 
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; 
    GPIO_Init(CW_GPIOA, &GPIO_InitStructure); 
    PA05_AFx_GTIM2CH1(); 
}

4.GTIM初始化

void GTIM_Init(void) 
{ 
    GTIM_InitTypeDef GTIM_InitStruct = {0}; 
    
    //REGBITS_SET(CW_SYSCTRL->APBEN1, SYSCTRL_APBEN1_GTIM1_Msk); //打开GTIM1 
    __RCC_GTIM1_CLK_ENABLE(); //打开GTIM1时钟 GTIM_InitStruct.Mode = GTIM_MODE_TIME;
    GTIM_InitStruct.OneShotMode = GTIM_COUNT_CONTINUE; 
    GTIM_InitStruct.Prescaler = GTIM_PRESCALER_DIV1024; 
    GTIM_InitStruct.ReloadValue = 62499ul; //T=1s. 
    GTIM_InitStruct.ToggleOutState = DISABLE; 
    GTIM_TimeBaseInit(CW_GTIM1, &GTIM_InitStruct); 
    GTIM_ITConfig(CW_GTIM1, GTIM_IT_OV, ENABLE); 
    NVIC_ClearPendingIRQ(GTIM1_IRQn); 
    NVIC_EnableIRQ(GTIM1_IRQn);
    NVIC_SetPriority(GTIM1_IRQn, 0x03); 
    
    __RCC_GTIM2_CLK_ENABLE();//打开GTIM2时钟 
    GTIM_InitStruct.ReloadValue = 0xFFFFu; 
    GTIM_InitStruct.ToggleOutState = ENABLE;
    GTIM_TimeBaseInit(CW_GTIM2, &GTIM_InitStruct); 
    valuePeriod = GTIM_InitStruct.ReloadValue; 
    valuePosWidth = valuePeriod >> 1u; 
    GTIM_OCInit(CW_GTIM2, GTIM_CHANNEL1, GTIM_OC_OUTPUT_PWM_HIGH); 
    GTIM_SetCompare1(CW_GTIM2, valuePosWidth); 
    GTIM_Cmd(CW_GTIM2, ENABLE); 
}

5.主程序main

uint16_t valueAdc; 
uint32_t valueAdcAcc; 
volatile uint8_t gFlagIrq; 
uint16_t gCntEoc = 0; 
uint8_t cntSample; 
float fTsDegree; 
uint32_t valuePeriod; 
uint32_t valuePosWidth; 
uint32_t valueReload = 0xFFFFu; 
int main(void) 
{   
    uint8_t res; 
    ADC_InitTypeDef ADC_InitStructure = {0}; 
    ADC_WdtTypeDef ADC_WdtStructure = {0};
    ADC_SingleChTypeDef ADC_SingleChStructure = {0}; 
    RCC_HSI_Enable(RCC_HSIOSC_DIV6);     //以下从HSI切换到PLL 
    RCC_PLL_Enable(RCC_PLLSOURCE_HSI, 8000000UL, RCC_PLL_MUL_8); 
    //开启PLL,PLL源为HSI 
    __RCC_FLASH_CLK_ENABLE();//打开FLASH时钟 
    FLASH_SetLatency(FLASH_Latency_3); 
    res = RCC_SysClk_Switch(RCC_SYSCLKSRC_PLL); //切换系统时钟到PLL:64MHz。 
    ADC_PortInit();//配置ADC测试IO口 
    LED_Init();//LED初始化 
    PWM_PortInit();
    GTIM_Init(); 
    ADC_StructInit(&ADC_InitStructure); //ADC默认值初始化 
    ADC_WdtInit(&ADC_WdtStructure); //ADC模拟看门狗通道初始化 
    ADC_InitStructure.ADC_ClkDiv = ADC_Clk_Div128;    //ADCCLK:500KHz. 
    ADC_InitStructure.ADC_InBufEn = ADC_BufEnable; 
    ADC_InitStructure.ADC_SampleTime = ADC_SampTime10Clk; 
    ADC_SingleChStructure.ADC_DiscardEn = ADC_DiscardNull; //配置单通道转换模式
    ADC_SingleChStructure.ADC_Chmux = ADC_ExInputCH1; //选择ADC转换通道 
    ADC_SingleChStructure.ADC_InitStruct = ADC_InitStructure; 
    ADC_SingleChStructure.ADC_WdtStruct = ADC_WdtStructure; 
    ADC_SingleChOneModeCfg(&ADC_SingleChStructure); 
    ADC_ITConfig(ADC_IT_EOC, ENABLE); 
    ADC_EnableIrq(ADC_INT_PRIORITY);
    ADC_ClearITPendingAll(); 
    ADC_Enable();//ADC使能 
    ADC_ExtTrigCfg(ADC_TRIG_GTIM1, ENABLE); //ADC外部中断触发源配置 
    GTIM_Cmd(CW_GTIM1, ENABLE);
    while (1) 
    { 
        while (!(gFlagIrq & ADC_ISR_EOC_Msk)); 
        gFlagIrq = 0u; PC03_TOG(); 
        valueAdc = ADC_GetConversionValue(); 
        valueReload = ((4095u * 125000ul) / (4999u * valueAdc + 4095u) + 1) >> 1; 
        GTIM_SetCounterValue(CW_GTIM2, 0u);     //reset. 
        GTIM_SetReloadValue(CW_GTIM2, valueReload); 
        GTIM_SetCompare1(CW_GTIM2, valuePosWidth); //等待ADC外部中断触发源启动下一次ADC转换 
    } 
}

6.实验展示

通用定时器GTIM1定时1s自动触发ADC模块进行转换,ADC通道为AIN1:PA01。

通用定时器GTIM2将AIN1的ADC采样值转换成频率可变的PWM方波,占空比50%,使用PA05作为PWM输出。ADC采样值为0时,PWM方波频率为1Hz;ADC采样值为4095时,PWM方波频率为5KHz。

3.png

来源:武汉芯源半导体

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 31

别家MCU的工作电压范围常见的是2.4V~3.6V或者1.8V~5.5V。咱们这个CW32系列设计的是1.65V~5.5V是怎么考虑的?

兼容5V电平是目前国产MCU的工作电压范围的发展趋势,让客户可以随意选择合适的工作电压,以方便与外围器件接口。这也主要得益于华虹宏力相关工艺制程能够提供支持这个电压范围的Pad Stack。

但是与别家不同的是,CW32设计团队拥有独立自主的设计能力和完备的质量管理体系,有能力提供更宽的工作电压范围。CW32系列MCU,特别是CW32L这样的低功耗MCU,采用1.65V这样的设计,可以实现与一些1.8V电压系统的直接兼容连接.

毕竟芯片设计可以保证1.65V供电正常工作,实际测试验证电压更是低至1.60V,这样的工作环境下,别家1.8V~5.5V的芯片设计在仅供电1.8V的时候用到了工作电压下限了,在遇到干扰的时候怕是不稳定。

除了低电压下限问题以外,还有什么好处或者缺点呢?

如此宽的工作电压范围,也是同时为实现超强抗干扰性能服务的。CW32系列MCU能够在工作中自动适应工作电压的动态变化,还可以显著延长电池供电系统的电池使用寿命。

如果一定要说有什么不好,也不妨说出来,兼容5伏的Pad Stack一般信号输入输出的速度不会如3.3伏或者更低的逻辑电平那样快,满足十几二十兆的速度就是够用的了,毕竟在工控和低功耗的场合,这样的使用场景不会很广的,基本都够用。

有些MCU芯片是支持3.3伏供电但是容忍5伏输入的,CW32有这个功能吗?

CW32系列没有这个功能,一般建议客户如果要连接5伏信号给MCU,就将MCU的电源供电直接给到5伏,这样就不需要有这个功能了。另外,就算是别家MCU具备这种5伏容忍功能的情况下,别家MCU的供应商也是不推荐这么用的,毕竟信号电平不同,还需要处理电源上电顺序,不是一个安全简易的设计风格。

所以说,支持1.65V的最低工作电压的MCU,CW32是唯一的一家吗?

技术都是在不断进步的,目前CW32能够确保这一技术要点。客户可能不一定用得到,也许客户的供电电压就是一个可以保证的3.3V或者5V。

但是我们不要忘了,业界最宽的工作电压范围,表征的是CW32的设计团队是一个不断进取的独立设计团队,在确保安全的前提下致力于为客户提供更可靠的技术和产品。这本身就说明CW32系列拥有高远的技术目标,不会满足于现有水平,在各个技术领域都敢于破局、甘当先锋。

来源:CW32生态社区

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 70

CW32的LVD低电压检测器适用于监测VDDA电源电压或外部引脚输入电压,当被监测电压与LVD阈值的比较结果满足触发的条件时,LVD将会产生中断或者复位信号,通常用来处理一些紧急任务。LVD产生的中断或复位标志,只能通过软件程序清零,并且只有当中断或复位标志被清零后,在再次达到触发条件时,LVD才能再次产生中断或复位信号。在本文中以CW32L083系列为例,介绍LVD的基本功能和使用例程。

LVD的基本功能介绍:

1、4路监测电压源

VDDA电源电压,PA00引脚输入,PB00引脚输入,PB11引脚输入

2、16阶阈值电压,范围2.02V-3.76V

3、3种触发条件,可以组合使用

电平触发:电压低于阈值

下降沿触发:电压跌落到阈值以下的下降沿

上升沿触发:电压回升到阈值以上的上升沿

4、可触发产生中断或复位信号,二者不能同时产生

5、8阶滤波可配置

6、支持迟滞功能

7、支持低功耗模式下运行,中断唤醒MCU

1.png

通过LVD的控制寄存器LVD_CR0的SOURCE位域来选择LVD模块监控的电压(VDDA电源/ PA00引脚/PB00引脚/PB11引脚),在监测外部引脚电压时,需将对应的GPIO端口配置为模拟输入模式(GPIOx_ANALOG.PINy = 1)。

LVD的比较结果可以从PA01/PA08/PC12/PE02/PF02脚输出,在此之前,需将对应的GPIO口配置为数字输出模式,同时选择端口位LVDOUT复用功能。

LVD 内置的电压比较器具有迟滞功能,只有当被监测电压高于或低于阈值电压达到 20mV 时,比较器输出信号才会发生翻转,可避免当 LVD 的监测电压在阈值电压附近时,电压比较器的输出结果发生频繁翻转,增强系统抗干扰能力。具体波形如下图所示:

2.png

LVD的阈值电压根据LVD控制寄存器LVD_CR0的VTH位控制。

3.png

LVD支持数字滤波功能,可以增强系统的鲁棒性(系统在一定的参数抖动下,维持起某些性能的特性),可以将LVD电压比较的输出结果信号进行数字滤波,小于滤波宽度的信号被滤除,不会被触发中断或复位,如下图所示,图中两处噪音或其他信号就被滤除了。

4.png

通过设置控制寄存器LVD_CR1的FLTEN位域,可以使能数字滤波模块,当将该位设置为1的时候,会使能数字滤波模块。

通过设置控制寄存器 LVD_CR1 的 FLTCLK 位域可以选择数字滤波的时钟:

• FLTCLK 位为 1,选择 HSIOSC 作为滤波时钟 

• FLTCLK 位为 0,选择内置 RC 振荡器时钟作为滤波时钟,其频率约 150kHz

控制寄存器 LVD_CR1 的 FLTTIME 位域用于选择数字滤波的时钟个数,如下表所示:

5.png

从 LVD 状态寄存器 LVD_SR 的 FLTV 位域,可以读出经 LVD 数字滤波后的信号电平;当 GPIO 的功能复用为 LVD_OUT 时,数字滤波后的信号就可以从 GPIO 输出,以方便观察测量。

LVD 支持在低功耗模式下工作,中断输出可将芯片从低功耗模式下唤醒。当被监测电压与 LVD 阈值的比较结果满足触发条件时,可产生中断或复位信号。产生中断还是复位信号由控制寄存器 LVD_CR0 的 ACTION 位域控制:

 • ACTION 为 1,LVD 触发产生复位 #define LVD_Action_Reset  ((uint32_t)0x00000002)

 • ACTION 为 0,LVD 触发产生中断 #define LVD_Action_Irq   ((uint32_t)0x00000000)

LVD可以通过设置控制寄存器 LVD_CR0 的 IE 位域为 1,使能 LVD 中断,满足触发条件时将产生 LVD 中断,中断标志位 LVD_SR.INTF 会被硬件置 1,用户可以向 INTF 位写 0,清除中断标志。设置控制寄存器 LVD_CR1 的 LEVEL、FALL、RISE 位域,可选择不同的中断或复位触发方式,三者可组合使用:

• LEVEL 为 1,被监测电压低于阈值时触发中断或产生复位 

• FALL 为 1,被监测电压跌落到阈值以下的下降沿触发中断或产生复位 

• RISE 为 1,被监测电压回升到阈值以上的上升沿触发中断或产生复位

LVD使用例程介绍:

根据上述内容,可以配置一个关于CW32L083的电压监测例程,LVD的输入通道设置为PA00,输出端口为PA08,门限电压为2.02V,利用LVD的中断实现当LVD输入通道电压低于或者高于门限电压时刻(利用上升沿和下降沿),PC03输出电平翻转一次。

void LVD_PortInit(void) 
{ 
    GPIO_InitTypeDef GPIO_InitStructure = {0}; 
    
    //打开GPIOA时钟 
    __RCC_GPIOA_CLK_ENABLE(); 
    
    //将PA08设置为LVD比较结果输出 
    GPIO_InitStructure.Pins = GPIO_PIN_8; 
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; 
    GPIO_Init(CW_GPIOA, &GPIO_InitStructure); 
    
    //将PA08复用为LVD比较结果输出     
    PA08_AFx_LVDOUT();
     //将PA00设置为LVD的输入口 
    PA00_ANALOG_ENABLE(); 
} 

int main(void) 
{ 
    LVD_InitTypeDef LVD_InitStruct = {0}; 
    
    //LED初始化 
    LED_Init(); 
    
    //配置测试IO口 
    LVD_PortInit(); 
    
    LVD_InitStruct.LVD_Action = LVD_Action_Irq;  //配置中断功能 
    LVD_InitStruct.LVD_Source = LVD_Source_PA00; //配置LVD输入口为PA00 
    LVD_InitStruct.LVD_Threshold = LVD_Threshold_2p02V; //配置LVD基准电压为2.02v 
    LVD_InitStruct.LVD_FilterEn = LVD_Filter_Enable;//LVD滤波模块开启 
    LVD_InitStruct.LVD_FilterClk = LVD_FilterClk_RC150K;//LVD滤波时钟为150KHz 
    LVD_InitStruct.LVD_FilterTime = LVD_FilterTime_4095Clk; 
    LVD_Init(&LVD_InitStruct);
    
    LVD_TrigConfig(LVD_TRIG_FALL | LVD_TRIG_RISE, ENABLE);//LVD中断为上升沿和下降沿触发 
    LVD_EnableIrq(LVD_INT_PRIORITY); 
    LVD_ClearIrq(); 
    FirmwareDelay(4800); 
    LVD_Enable(); //LVD使能 
    
    while (1) 
    { 
        if (gFlagIrq) 
        { 
            PC03_TOG(); 
            gFlagIrq = FALSE; 
        } 
    } 
} 

/** 
* @brief LED I/O初始化 
* 
*/ 
void LED_Init(void) 
{ 
    GPIO_InitTypeDef GPIO_InitStructure = {0};
    
    //打开GPIOC时钟 
    REGBITS_SET(CW_SYSCTRL->AHBEN, SYSCTRL_AHBEN_GPIOC_Msk); 
    
    /* Configure the GPIO_LED pin */ 
    GPIO_InitStructure.Pins = GPIO_PIN_2 | GPIO_PIN_3; 
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; 
    GPIO_Init(CW_GPIOC, &GPIO_InitStructure); 
    
    //LEDs are off. 
    PC02_SETLOW(); 
    PC03_SETLOW(); 
} 

//LVD中断服务函数 
void LVD_IRQHandler(void) 
{ 
    LVD_ClearIrq();      //清除中断标志 
    gFlagIrq = TRUE;     //将gFlagIrq赋值为TURE 
}

根据上述例程可以得到在PA00的输入电压值低于2.02v或高于2.02v的瞬间时刻,LVD会产生中断,PC03的输出电平会产生翻转,可利用CW32L083的开发板和一根杜邦线,将PA00和DVCC连接,在连接上的时刻以及拔掉杜邦线的时刻,LED1的状态会发生翻转。

来源:武汉芯源半导体

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 190

一、波特率介绍

波特率表示单位时间内传送的码元符号的个数,它是对符号传输速率的一种度量,它用单位时间内载波调制状态改变的次数来表示,即指一个单位时间内传输符号的个数(Baud,单位符号:Bd)。

CW32L083 内部集成 6 个通用异步收发器 (UART),支持异步全双工、同步半双工和单线半双工模式,支持硬件数据流控和多机通信;可编程数据帧结构,可以通过小数波特率发生器提供宽范围的波特率选择。UART 控制器工作在双时钟域下,允许在深度休眠模式下进行数据的接收,接收完成中断可以唤醒 MCU 回到运行模式。

波特率发生器框图如下:

1.png

二、波特率设置

1.同步半双工模式下

波特率计算公式:BaudRate = UCLK / 12

其中,UCLK 是 UART 的传输时钟,其来源可以是 PCLK、LSE 或 LSI,通过控制寄存器 UARTx_CR2 的 SOURCE 位域来选择。

2.异步模式下

UART 的接收和发送波特率是相同的,由同一个波特率发生器产生。波特率发生器支持 16 倍采样、8 倍采样、4 倍采样和专用采样这 4 种采样模式,具体的采样模式通过控制寄存器 UARTx_CR1 的 OVER 位域来选择。UCLK是 UART的传输时钟,其来源可以是 PCLK、LSE或 LSI,具体来源通过 UARTx_CR2.SOURCE来选择。BRRI(UARTx_BRRI[15:0]),是波特率计数器的整数部分,可设置范围为 1 ~ 65535。BRRF(UARTx_BRRF[3:0]),是波特率计数器的小数部分,可设置范围为 0 ~ 15。

OVER = 00,设置 16 倍采样,波特率计算公式:BaudRate = UCLK / ( 16×BRRI + BRRF )

OVER = 01,设置 8 倍采样,波特率计算公式:BaudRate = UCLK / ( 8×BRRI )

OVER = 10,设置 4 倍采样,波特率计算公式:BaudRate = UCLK / ( 4×BRRI )

OVER = 11,设置专用采样,波特率计算公式:BaudRate = ( 256×UCLK ) / BRRI

专用采样仅适合传输时钟源为 LSE 或者 LSI 时,进行 2400bps、4800bps 或 9600bps 波特率下的 UART 通信。

UCLK 为 24MHz 波特率设置示例(OVER = 00)

2.png

UCLK 为 32.768kHz 波特率设置示例(OVER = 11)

3.png

3.波特率自动检测 

CW32L083 使用 UART 作为从机进行通信时,可以通过自动波特率检测的方法,自动适应 UART 主机的波特率。可将通用定时器(GTIM)的输入捕获来源配置为 UART 的 RXD 信号,或者将 GTIM 的门控信号配置为 UART 的 RXD 信号,配合使用相关软件算法测量 UART 的波特率,以实现波特率自适应。

三、波特率计数器寄存器定义

1.UARTx_BRRI 波特率计数器整数部分寄存器

Address offset: 0x0C  Reset value: 0x0000 0000

4.png

2.UARTx_BRRF 波特率计数器小数部分寄存器

Address offset: 0x10  Reset value: 0x0000 0000

5.png

四、波特率设置举例

当传输时钟 UCLK 的频率为 24MHz 时,要求配置 BaudRate = 115200 bps,计算 16×BRRI + BRRF = 24000000 / 115200 = 208.33 则: 

BRRI = 208.33 / 16 = 13.02,最接近的整数是:13(0x0D) 

BRRF = 0.02×16 = 0.32,最接近的整数是:0(0x00) 

即需要设置 UARTx_BRRI 为 0x0D,UARTx_BRRF 为 0x00 此时,实际波特率 BaudRate = 115384.62 bps,误差率为 0.16%。

来源:武汉芯源半导体

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 34

页面

订阅 RSS - CW32