0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于N32G45的定时器PWM输出

嵌入式技术 来源:嵌入式技术 作者:嵌入式技术 2022-12-05 12:08 次阅读

​ PWM是一种对模拟信号电平进行​​​​数字编码​​​​​的方法。通过高​​​​分辨率​​​​计数器的使用,方波的占空比被调制用来对一个具体​​​​模拟信号​​​​的电平进行编码。PWM信号仍然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有(ON),要么完全无(OFF)。电压或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去的。通的时候即是直流供电被加到负载上的时候,断的时候即是供电被断开的时候。只要带宽足够,任何模拟值都可以使用PWM进行编码。

脉宽调制(PWM,Pulse Width Modulation)是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中 。

​PWM的一个优点是从处理器到​​​被控系统​​​信号都是数字形式的,再进行数模转换。可将噪声影响降到最低(可以跟电脑一样)。噪声只有在强到足以将逻辑1改变为逻辑0或将逻辑0改变为逻辑1时,也才能对数字信号产生影响。

1.PWM模式

用户可以使用 PWM 模式产生一个信号,其占空比由 TIMx_CCDATx 寄存器的值决定,其频率由TIMx_AR 寄存器的值决定。 并且取决于 TIMx_CTRL1.CAMSEL 的值, TIM 可以在边沿对齐模式或中央对齐模式下产生 PWM 信号。

用户可以通过设置 TIMx_CCMODx. OCxMD=110 或设置 TIMx_CCMODx.OCxMD=111 来设置 PWM 模式 1 或 PWM 模式 2。 要使能预加载寄存器,用户必须设置相应的 TIMx_CCMODx.OCxPEN。 然后设置 TIMx_CTRL1.ARPEN 自动重装载预加载寄存器。

用户可以通过设置 TIMx_CCEN.CCxP 来设置 OCx 的极性。当 TIM 处于 PWM 模式时, TIMx_CNT 和 TIMx_CCDATx 的值总是相互比较。

只有当更新事件发生时,预加载寄存器才会转移到影子寄存器。 因此,用户必须在计数器开始计数之前通过设置 TIMx_EVTGEN.UDGN 来复位所有寄存器。

1.1 PWM中央对齐模式

如果用户设置 TIMx_CTRL1.CAMSEL 等于 01、 10 或 11, PWM 中央对齐模式将被激活。 比较标志的设置取决于 TIMx_CTRL1.CAMSEL 的值。 设置比较标志的情况有 3 种,仅当计数器向上计数时,仅当计数器向下计数时,或当计数器向上计数和向下计数时。 用户不应通过软件修改 TIMx_CTRL1.DIR,它是由硬件更新的。

中央对齐 PWM 波形示例如下,波形设置为: TIMx_AR=8, PWM 模式 1 ,当计数器向下计数对应TIMx_CTRL1.CAMSEL=01 时设置比较标志。

pYYBAGONZnuACHpTAAEI05e7VJM794.png

使用中央对齐模式时用户应注意的事项如下:

计数器向上或向下计数取决于 TIMx_CTRL1.DIR 的值。 注意不要同时更改 DIR 和 CAMSEL 位

用户在中央对齐模式下不要写计数器,否则会导致意想不到的结果。 例如:

如果写入计数器的值为 0 或者是 TIMx_AR 的值,则方向会被更新,但不会产生更新事件

如果写入计数器的值大于自动重载的值,则方向不会更新

为了安全起见,建议用户在启动计数器之前设置 TIMx_EVTGEN.UDGN 以通过软件生成更新,并且在计数器运行时不要写入计数器。

1.2 PWM 边沿对齐模式

边沿对齐模式有两种配置,向上计数和向下计数

向上计数

用户可以设置 TIMx_CTRL1.DIR=0 使计数器向上计数。

PWM 模式 1 的示例:

当 TIMx_CNT < TIMx_CCDATx 时, OCxREF 为高电平,否则为低电平。 如果 TIMx_CCDATx 中的比较值大于自动重载值,则 OCxREF 将保持为 1。相反,如果比较值为 0,则 OCxREF 将保持为 0。当 TIMx_AR=8 时, PWM 波形如下:

poYBAGONZ2WAZ0JjAAB7R9Iyi64267.png

向下计数

用户可以设置 TIMx_CTRL1.DIR=1 使计数器向下计数。

PWM 模式 1 的示例:

当 TIMx_CNT > TIMx_CCDATx 时, OCxREF 为低电平,否则为高电平。 如果 TIMx_CCDATx 中的比较值大于自动重载值,则 OCxREF 将保持为 1。

注:若第n 个PWM 周期CCDATx 影子寄存器>=AR 值,第n+1 个PWM 周期CCDATx 的影子寄存器值是0。在第n+1 个PWM周期的计数器为0 的时刻,虽然计数器 = CCDATx 影子寄存器的值 = 0, OCxREF =‘0’,但不会产生比较事件。

2.通过PWM输出呼吸灯示例

1.根据N32G45帖子介绍可知LED硬件接口:https://bbs.elecfans.com/jishu_2320004_1_1.html

poYBAGOLSzGAEIR2AAApZY0b19M245.png#pic_center

2.接下来我我们以D2、D3为例(D2、D3刚才处于TIM3的通道1和通道2上),实现PWM输出控制LED。

根据参考手册第7章可以看到,我们想要实现该功能,就需要开始TIM3的部分重映射功能。

pYYBAGONaPWALuFjAACJ53d22dI465.png

TIM3通道的部分重映射配置如下:

  RCC->APB2PCLKEN|=1<<0;//AFIO
  AFIO->RMP_CFG&=~(0x3<<10);
  AFIO->RMP_CFG|=2<<10;//开启部分重映像
  AFIO->RMP_CFG&=~(0x7<<24);
  AFIO->RMP_CFG|=1<<24;//将PB4设置为普通IO

寄存器相关介绍可查看N32用户手册第7.4章节AFIO寄存器配置。

3.配置定时器基本功能和PWM模式。

在完成PWM模式输出时,我们需要先完成定时器的基本功能配置(开定时器时钟、设置预分频系数,设置周期时间)。

定时器相关寄存器可参考N32用户手册12.4章节。下面列举几个常用寄存器。

控制寄存器1(TIM_CTRL1)

pYYBAGONasOAXDf7AACnE-rkno0333.png

本寄存器主要实现定时器的基本功能配置:设置计数模式、开始定时器等。

预分频器(TIM_PSC)

pYYBAGONayWABR5CAACvUSRIfKQ765.png

本寄存器设置定时器的工作频率,例如要实现计数器+1的时长为1us,则时钟的PSC=72-1;

注意:定时器的时钟线工作频率为72MHZ,即CK_PSC=72MHZ

重装载寄存器(TIM_AR)

poYBAGONa8yAfM3bAAGaxQwgmfk599.png

重装载寄存器为实现定时器计数周期。

捕获比较寄存器(TIM_CCDAT1)

pYYBAGONbG2AAMhYAAI5Zu_qx7Y685.png

当为输出模式时,CCDAT寄存器用于设置占空比;当为输入模式时,CCDAT用于保存捕获到的电平时间;

捕获/比较寄存器(TIM_CCMOD)

pYYBAGONbPWAXvWRAAHWWWbmmrI017.png

捕获比较寄存器用于设置输入捕获模式和输出比较模式的通道参数信息

捕获/比较使能寄存器(TIM_CCEN)

pYYBAGONbWOAMz3ZAACmpeu2tvM984.png

捕获比较使能寄存器用于启动通道、设置有效电平极性。

2.1 定时配置示例

完成定时器基本功能配置,设置周期时间,设置分频系数,配置通道参数,输出PWM。

/***********************************
**
**函数功能:定时器器PWM输出
**TIM3通道引脚: 
**           没有重映射   部分重映射     完全重映射
**  TIM3_CH1    PA6           PB4             PC6
**  TIM3_CH2    PA7           PB5             PC7
**形参:
**    chx --要开启的通道(1 --通道1,2--通道2, 3 --表示开启通道1和通道2)
**    psc --预分频系数
**    ar  --重装载值(即周期时间)
**    ccr --占空比
**  注意:本示例采用部分重映射功能  
**作者:IT_阿水
************************************/
void TIM3_PWM_Out(u8 chx,u16 psc,u16 ar,u16 ccr)
{
  /*1.开时钟*/
  RCC->APB2PCLKEN|=1<<3;//PB
  RCC->APB2PCLKEN|=1<<0;//AFIO
  AFIO->RMP_CFG&=~(0x3<<10);
  AFIO->RMP_CFG|=2<<10;//开启部分重映像
  AFIO->RMP_CFG&=~(0x7<<24);
  AFIO->RMP_CFG|=1<<24;//将PB4设置为普通IO
  /*2.配置GPIO*/
  GPIOB->PL_CFG&=0xFF00FFFF;
  GPIOB->PL_CFG|=0x00BB0000;//通用复用推挽输出模式
  /*3.定时器配置*/
  RCC->APB1PCLKEN|=1<<1;//TIM3
  RCC->APB1PRST|=1<<1;//开启复位时钟
  RCC->APB1PRST&=~(1<<1);//取消复位
  TIM3->CTRL1|=1<<7;
  TIM3->PSC=psc-1;//预分频
  TIM3->AR=ar;//重装载值
  
  /*输出PWM配置*/
  if(chx&0x1)
  {
    TIM3->CCMOD1&=~(0x3<<0);//输出
    TIM3->CCMOD1|=1<<2;//快速使能
    TIM3->CCMOD1|=1<<3;//预加载
    TIM3->CCMOD1|=0x6<<4;//PWM0
    TIM3->CCDAT1=ccr;//占空比,有效电平时间
    TIM3->CCEN|=1<<0;//开启CH1
  }
  if(chx&1<<1)//CH2
  {
    TIM3->CCMOD1&=~(0x3<<8);//输出
    TIM3->CCMOD1|=1<<10;//快速使能
    TIM3->CCMOD1|=1<<11;//预加载
    TIM3->CCMOD1|=0x6<<12;//PWM0  
    TIM3->CCDAT2=ccr;//占空比,有效电平时间
    TIM3->CCEN|=1<<4;//开启CH2
  }
  TIM3->CTRL1|=1<<0;//开启定时器
}

2.2 呼吸灯效果实现

通过调节PWM输出的占空比,实现LED呼吸灯效果。

#include "n32g45x.h"
#include 
#include 
#include "led.h"
#include "key.h"
#include "usart.h"
#include "delay.h"
#include "timer.h"
int main()
{
  u8 key_val;
  int time=0;
  u8 flag=0;
  LED_Init();
  KEY_Init();
  USART_Init(115200);
  TIM3_PWM_Out(3,72,400,0);
  printf("串口初始化完成rn");
  while(1)
  {
    key_val=Key_Scan();  
    if(key_val)
    {
      printf("串口+DMA数据发送测试示例!rn");
    }
    if(usart1_flag)
		{
			usart1_rx_buff[usart1_cnt]='�';
			printf("%s,%drn",usart1_rx_buff,usart1_cnt);
      if(strcmp((char *)usart1_rx_buff,"LED1_ON")==0)LED_D1=1;
      else if(strcmp((char *)usart1_rx_buff,"LED1_OFF")==0)LED_D1=0;
      else if(strcmp((char *)usart1_rx_buff,"LED2_ON")==0)LED_D2=1;
      else if(strcmp((char *)usart1_rx_buff,"LED2_OFF")==0)LED_D2=0;
      else if(strcmp((char *)usart1_rx_buff,"LED3_ON")==0)LED_D3=1;
      else if(strcmp((char *)usart1_rx_buff,"LED3_OFF")==0)LED_D3=0;
			usart1_flag=0;
		}  
    if(time>=400)flag=1;
    else if(time<=0)flag=0;
    if(flag)time--;
    else time++;
    TIM3->CCDAT1=time;
    TIM3->CCDAT2=time;
    Delay_Ms(10);
  }    
}
pYYBAGONbq-AGOePAA0nwUWXJUc426.png

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • PWM
    PWM
    +关注

    关注

    114

    文章

    4905

    浏览量

    210079
  • 定时器
    +关注

    关注

    23

    文章

    3148

    浏览量

    112177
  • n32g455
    +关注

    关注

    0

    文章

    7

    浏览量

    881
收藏 人收藏

    评论

    相关推荐

    利用定时器配置的PWM输出

    实验过程中的笔记 在持续更新中 只是一个简化版本利用定时器1 2 3 4 配置的PWM输出高级定时器PWM
    发表于 08-19 07:17

    定时器应用之PWM输出

    定时器应用之PWM输出1.1 TIM1_CH1N 与 TIM1_CH1 的区别在刚准备使用定时器的时候,我看了下原理图,发现对于
    发表于 08-19 08:40

    定时器输出PWM

    定时器输出PWM波什么是PWM脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处
    发表于 01-05 07:05

    如何使用定时器进行PWM输出

    使用定时器进行PWM输出STM32 的定时器除了 TIM6 和 7。其他的定时器都可以用来产生 PWM
    发表于 03-02 07:30

    国民技术N32G45环境搭建及点灯测试

    1.N32G45简介  N32G45系列集成了最新一代嵌入式ARM Cortex™-M4F处理,在Cortex™-M3内核的基础上强化了运算能力、新增加了浮点运算处理单元(FPU)、DSP
    发表于 12-03 16:34

    【国民技术N32项目移植】基于N32G45贪吃蛇小游戏项目移植

    TIMx_EVTGEN.UDGN 来复位所有寄存。  关于定时器PWM详细介绍请参考文档:基于N32G45定时器
    发表于 12-05 23:53

    N32G45的工程项目如何添加AT组件?

    目前使用的是N32G45的工程项目,需要添加AT组件,然后我根据文档发现没有AT的代码,从rtthread studio新建的项目中把AT文件夹复制过来,在其中使用ENV工具配置,手动将程序全都放进工程中新建的文件夹,编译的时候发现没有,下载了at_device软件版之后不知道怎么配置了。
    发表于 09-07 16:52

    定时器输出PWM实验

    定时器输出PWM 实验 一. 实验目的利用定时器控制产生占空比可变的PWM 波。二. 实验设备及器件IBM PC 机 一台DP-51PRO
    发表于 09-22 10:49 7084次阅读

    AVR单片机定时器输出PWM的设计及注意问题

    本内容提供了AVR单片机定时器输出PWM的设计及注意问题,根据PWM的特点,在使用ATmega128的定时/计数器设计
    发表于 11-09 17:39 1567次阅读

    如何通过STM32的定时器输出PWM

      本文将介绍通过STM32的定时器输出PWM,如果对定时器不太熟悉的同学可以看下之前的文章《STM32基础定时器详解》,关于
    的头像 发表于 02-20 15:08 2.1w次阅读
    如何通过STM32的<b class='flag-5'>定时器</b><b class='flag-5'>输出</b><b class='flag-5'>PWM</b>?

    STM32-通用定时器-PWM输出

    1 通用定时器PWM概述1.1STM32定时器输出通道引脚这里以TIM3为例来讲解。STM32的通用定时器分为TIM2、TIM3、TIM4、
    发表于 11-26 15:36 23次下载
    STM32-通用<b class='flag-5'>定时器</b>-<b class='flag-5'>PWM</b><b class='flag-5'>输出</b>

    STM8学习笔记---定时器输出7路PWM

    波。其中定时器1有4个通道,定时器2有3个通道。现在让定时器1和定时器2所有通道同时输出PWM
    发表于 11-26 16:06 9次下载
    STM8学习笔记---<b class='flag-5'>定时器</b><b class='flag-5'>输出</b>7路<b class='flag-5'>PWM</b>波

    普通定时器输出互补PWM带死区

    普通定时器输出互补PWM带死区一般来说三相半桥电路需要互补PWM驱动,而且互补PWM需要带死区,死区的大小跟管子的性能参数有关。公司为了省成
    发表于 12-16 16:59 24次下载
    普通<b class='flag-5'>定时器</b><b class='flag-5'>输出</b>互补<b class='flag-5'>PWM</b>带死区

    STM32定时器应用——输出PWM给电机调速

    (含源码)运用定时器调整PWM输出值,使直流电机从慢到快,再从快到慢。
    发表于 12-31 19:53 11次下载
    STM32<b class='flag-5'>定时器</b>应用——<b class='flag-5'>输出</b><b class='flag-5'>PWM</b>给电机调速

    详解stm32的定时器8输出PWM

    我在定时器3的例程上面改,改了很久都没改好,百度看别人说定时器1和定时器8需要额外的指令用于PWM输出,今天下午硬件的人来要东西了,来不及研
    的头像 发表于 01-05 11:01 5070次阅读