- 项目简介
- 简单原理介绍
- 简单寄存器简介
- PWM波原理
- CubeMX 配置&相应工程代码
- 效果展示
- 出现的问题
- 补档
本次小实验基于STM32F429IGT6开发板,通过对通用定时器的使用,达到以下实验目标:
输出PWM波,使得LED对应亮度,实现半呼吸灯
本文参考书为王维波老师的《STM32Cube高效开发教程 基础篇》最近高级篇已经出版 感兴趣的小伙伴可以支持一波
本文参考链接:野火-高级定时器
在F4系列中,通用定时器指的是TIM2-5 & TIM9-14,其中TIM2-5有4个捕获/比较通道,可以实现外部时钟信号驱动,而TIM9-14只有1/2个通道,因为只能使用内部时钟信号。
1个通道的还没有内部触发输入,也就不能使用从模式与其他定时器串联。
以2-5框图为例
定时器内部时钟信号CK_INT,其源来自APB1/APB2,如果设置为从模式,还可以使用别的定时器输出信号作为自己的输入信号。
其中TIM9-11挂载在APB2,TIM12-14挂载在APB1
通过多项选择器,触发控制器输出CK_PSC信号,用于控制定时器复位,使能,计数等等
PSC经过PSC预分频处理(1~65536分频),进入CNT计数器(2-5 32位,9-12 16位,2-5还可以设置递增或递减计数,默认为递增计数),定时器运行时修改PSC分频值,需要下一个UEV事件到来之后才能修改
其上有ARR自动重装载寄存器,用来调控计数周期,有影子寄存器,通过ARPE的0/1来确定是否使用影子寄存器,即0时不适用,ARR写入新值立即生效;1时在UEV事件之后才更新影子寄存器中ARR写入的新值,UEV才生效。
CNT,PSC,ARR构成定时器的时基单元,其控制位有:
TIMx_CR1 ->CEN位使能寄存器,1时经过1周期,CK_CNT工作,0时不工作
TIMx_EGR ->UG通过软件模式产生一次更新时间,在经历一个CK_CNT一个脉冲,产生UEV并自动复位UG,计数器值清零重新计数
更多介绍详见参考手册,这里就不多赘述了
PWM:脉冲宽度调制,即具有一定占空比的信号,对模拟电压进行数字编码,根据数电的知识,可以用施密特触发器产生(原理相似而已)
原理图如图所示
通过设置捕获/比较寄存器CCR的值和ARR的值,就可以实现占空比的调节
注:书中给出的是CNT
PWM模式1- 在向上计数时,一旦TIMx_CNT
则为有效电平(OC1REF=1)。
PWM模式2- 在向上计数时,一旦TIMx_CNT
平
新建新工程,配置时钟树,HCLK=168MHz
查原理图可知LED接在PB1引脚,所以需要通过PB1引脚输出PWM配置小灯即可。
cube显示PB1引脚PWM通过PWM3通道4配置,故在timers-tim3选择,时钟源选择内部时钟源(因为挂载在APB1,时钟频率=APB1总线频率/PSC+1)APB1此时为84MHz,所以配置PSC=84-1;ARR配置为1000-1,表示1000*1/1M为一个周期1ms。
如图所示
开启TIM2定时器,与TIM3配置几乎相同,开启中断,并配置NVIC抢占优先级为3,(如果你的cubemx也存在默认滴答定时器优先级为15,需要手动调回0,否则会有很多麻烦)。
生成工程即可,一定要全英文路径。
首先开启TIM2,并打开TIM3的PWM波
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim2);
HAL_TIM_PWM_Start_IT(&htim3,TIM_CHANNEL_4);
/* USER CODE END 2 */
通过配置中断回调函数
HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
具体代码如下:
/* USER CODE BEGIN PFP */
int a=0;
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim==&htim2)
{
__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_4,a);
a++;
if(a>999-1)
a=0;
}
}
注意:a一定要是外部定义的而不是回调函数中定义的,否则会出现没反应的问题 小灯最开始最亮,最后变最暗,然后瞬间变得最亮。 因为小灯低电平有效所以最开始是最亮的 这个实验过于简单,只需要记住几个关键点就可以完成试验。 我会基本每天都有新东西更新,如果觉得有点帮助的话请为我点赞哦~ 2022.4.1 参数都不变 注意的地方是调用和嵌套的先后顺序 以及标志位 欢迎分享,转载请注明来源:内存溢出
以及:a>999可能会导致小小的溢出,所以减了1,防止溢出
这里默认的是PWM1输出,也就是CNT
最近开学了在家隔离没法返校,本人也是刚入门的菜鸟。
呼吸灯会在下个小实验里面更新更完整的 以及一些pwm的别的用法~
完善了完整呼吸灯 代码如下:void PWM_UpAndDowm(void)
{
if(flag == 1)
{
a++;
if(a>999){
a= 999;
flag =0;
}
}
else{
a--;
if(a<=0){
a=0;
flag =1;
}
}
__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_4,a);
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim==&htim2)
{
PWM_UpAndDowm();
}
}
评论列表(0条)