加入收藏 在线留言 联系我们
关注微信
手机扫一扫 立刻联系商家
全国服务热线15915421161

SIEMENS山西省晋城市 西门子代理商——西门子华北一级总代理

更新时间
2024-07-04 07:00:00
价格
请来电询价
西门子总代理
PLC
西门子一级代
驱动
西门子代理商
伺服电机
联系电话
15903418770
联系手机
15915421161
联系人
张经理
立即询价

详细介绍

ter value)

3.4 预分频器PSC

预分频器的功能也很单一,就是分频:


位 15:0 PSC[15:0]:预分频器值 (Prescaler value)

计数器时钟频率 CK_CNT 等于 fCK_PSC / (PSC[15:0] + 1)。

PSC 包含在每次发生更新事件时要装载到实际预分频器寄存器的值。

3.5 自动重装载寄存器ARR

自动重装载寄存器的功能也很单一,就是保存一个数,在计数满的时候,重新开始计数


位 15:0 ARR[15:0]:自动重载值 (Auto-reload value)

ARR 为要装载到实际自动重载寄存器的值。

当自动重载值为空时,计数器不工作。

3.6 捕获/比较寄存器CCR

自动重装载寄存器的功能也很单一,也是保存一个数,用于与当前的CNT进行比较,注意 TIM2 和 TIM5是32位计数。


以CCR1寄存器(一共有CCR1~CCR4这4个通道)为例:

位31:16 CCR1[31:16]:捕获/比较 1 的高 16 位(对于 TIM2 和 TIM5)。

位15:0 CCR1[15:0]:捕获/比较 1 的低 16 位 (Low Capture/Compare 1 value)

如果通道 CC1 配置为输出:CCR1 是捕获/比较寄存器 1 的预装载值。如果没有通过 TIMx_CCMR寄存器中的OC1PE 位来使能预装载功能,写入的数值会被直接传输至当前寄存器中。否则只在发生更新事件时生效(拷贝到实际起作用的捕获/ 比较寄存器1)。实际捕获/比较寄存器中包含要与计数器 TIMx_CNT进行比较并在 OC1 输出上发出信号的值。

如果通道 CC1 配置为输入:CCR1 为上一个输入捕获 1 事件 (IC1) 发生时的计数器值。



44代码实现与分析


上面介绍了定时器的基础知识与PWM的输出原理,下面就来实际看一下,如何编写对应的代码(以STM32F407为例)。

4.1 定时器初始化

定时器的初始化,因为需要用到对应的引脚输出PWM,因此要先初始化GPIO引脚,然后,还要初始化定时器的时基(计数的时钟)以及输出通道(用于配置PWM的输出模式)。

4.1.1 复用引脚初始化

这里用到的是定时器3,根据STM32F407的数据手册“3 Pinouts and pin description”中的“Table 9. Alternate function mapping”复用引脚说明表,可以看到定时器3通道1对应的引脚位A6:


因此程序中对A6引脚可以这样配置,注意一定要配置引脚的复用功能:














GPIO_InitTypeDef GPIO_InitStructure; /*引脚配置 结构体*/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);   //使能PORTA时钟GPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_AF_TIM3);  /*GPIOA6复用为定时器3*/
/*复用引脚配置*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;           //GPIOA6GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        /*复用功能*/GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;  //速度100MHzGPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉GPIO_Init(GPIOA,&GPIO_InitStructure);               //初始化PA6



4.1.2 时基初始化

时基初始化,主要是配置定时器的计数频率(psc)和自动重装置值(每次计数的周期,arr),比如TIM3_PWM_Init(500-1,84-1);

(关于psc与arr的知识点,可以再回顾一下上面1.3节的知识)

这里将arr的值设置为500,即计数器每计够500个数就会重新从0开始计数,这个500再乘以计数器计数的周期,就是PWM真正的周期,那计数器计数的频率是多少呢(频率的倒数为周期)?

这里将psc的值设置为84-1,即TIM3的输入频率为84MHz再将频率降低1/84,即使用1MHz的频率计数(1s能计1,000,000个数,也即1us计1个数),那么PWM的真正周期就是500*1us=500us(0.5ms),通过改变占空比的值(ccr),就可以调节PWM的输出占空比。


时基初始化配置如下:












TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure; /*时基 结构体*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);     //TIM3时钟使能  
/*时基初始化*/TIM_TimeBaseStructure.TIM_Period=arr;                     /*ARR 自动重装载值(周期),例如500*/TIM_TimeBaseStructure.TIM_Prescaler=psc;                  /*PSC 定时器分频,例如84*/TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;     /*时钟分割*/TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; /*向上计数模式*/TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);            /*初始化定时器3*/


Zui后一句的时基初始化,起始就是对定时的寄存器进行配置,该函数的内部实现如下:







































void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct){  uint16_t tmpcr1 = 0;  tmpcr1 = TIMx->CR1;  
 if((TIMx == TIM1) || (TIMx == TIM8)|| /*gaoji定时器TIM和TIM8*/     (TIMx == TIM2) || (TIMx == TIM3)||(TIMx == TIM4) || (TIMx == TIM5)) /*通用定时器中的TIM2~TIM5*/  {    /* 设置为计数器模式 */    tmpcr1 &= (uint16_t)(~(TIM_CR1_DIR | TIM_CR1_CMS));    tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_CounterMode;  }   if((TIMx != TIM6) && (TIMx != TIM7)) /*基本定时器TIM6和TIM7无此功能*/  {    /* 设置时钟分频 */    tmpcr1 &=  (uint16_t)(~TIM_CR1_CKD);    tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision;  }
 /* 配置CR1寄存器 */  TIMx->CR1 = tmpcr1;
 /* 配置ARR寄存器,设置自动重转载值 */  TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period ;   /* 配置PSC寄存器,设置预分频值 */  TIMx->PSC = TIM_TimeBaseInitStruct->TIM_Prescaler;   if ((TIMx == TIM1) || (TIMx == TIM8))  /*gaoji定时器TIM和TIM8*/  {    /*  配置RCR寄存器,设置重复计数值 */      TIMx->RCR = TIM_TimeBaseInitStruct->TIM_RepetitionCounter;  }
 /* 生成一个更新事件来立即重新加载预分频器和重复计数器(仅针对gaoji定时器TIM1和TIM8)值 */  TIMx->EGR = TIM_PSCReloadMode_Immediate;          }



相关产品

联系方式

  • 电  话:15903418770
  • 联系人:张经理
  • 手  机:15915421161
  • 微  信:15915421161