stm32
定时器(TIM)学习笔记(二)
Part 2.TIM输出比较
输出比较:
通过比较计数器(CNT)与捕获比较寄存器(CCR)之间的大小关系,来选择输出电平是1/0或者翻转的的操作。
可以通过该寄存器来输出PWM波,实现控制电机、舵机等任务。
每个高级定时器与通用定时器都有4个输出比较通道,所以,在制作麦轮小车时,可以只用一个TIM控制四个电机。
更值得一提的是,高级定时器的前3个通道额外用用死区生成和互补输出的功能。
1. 几个寄存器的英文及其缩写
英文全称
中文
缩写
Output Compare
输出比较
OC
InputCapture
输入捕获
IC
Capture/Compare
输入捕获与输出比较单元
CC
2.PWM
2.1 简介
image-20240316182430100
2.2 输出比较模式
image-20240316182829650
有效电平:高电平;无效电平:低电平。
PWM1和PWM2模式相似,仅仅只有电平不同,所以在实际使用的过程中完全可以按照PWM1使用即可
2.3 原理图
image-20240316183552303
这个图中,蓝色线是CNT的值,黄色线是ARR的值,红色线是CCR的值
当CNT自增时,他会先小于CCR,然后大于CCR,最后来到ARR时又会清零,并且不断重复这个过程。
我们可以在小于的部分输出低电平,大于的电平输出高电平,如此方可输出一个PWM波。
2.4 参数计算
image-20240316184227783
2.5 TB6612电机驱动
image-20240316190634893
3 代码实现-PWM驱动LED呼吸灯
3.1 Init
1 TIM_OCxInit(TIMy, &TIM_OCInitStructure)
配置输出比较单元,x可以是1,2,3,4四个数中任一的值,y也是。
这说明共有四个输出比较单元可供配置。
1 TIM_OCStructInit(&TIM_OCInitStructure)
配置结构体
1 TIM_SetComparex(TIMy, Compare)
设置占空比函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0 ; TIM_OC1Init(TIM2, &TIM_OCInitStructure);
注意,定时器使用引脚时需要使用复用推挽输出。
pwm.h
1 2 3 4 5 6 7 8 #ifndef __PWM_H #define __PWM_H void PWM_Init (void ) ;void PWM_SetCompare1 (uint16_t Compare) ;#endif
pwm.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 #include "stm32f10x.h" void PWM_Init (void ) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); TIM_InternalClockConfig(TIM2); TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStructure.TIM_Period = 100 - 1 ; TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1 ; TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0 ; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure); TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0 ; TIM_OC1Init(TIM2, &TIM_OCInitStructure); TIM_Cmd(TIM2, ENABLE); }void PWM_SetCompare1 (uint16_t Compare) { TIM_SetCompare1(TIM2, Compare); }
main.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include "stm32f10x.h" #include "Delay.h" #include "OLED.h" #include "PWM.h" uint8_t i;int main (void ) { OLED_Init(); PWM_Init(); while (1 ) { for (i = 0 ; i <= 100 ; i++) { PWM_SetCompare1(i); Delay_ms(10 ); } for (i = 0 ; i <= 100 ; i++) { PWM_SetCompare1(100 - i); Delay_ms(10 ); } } }
stm32
定时器(TIM)学习笔记(二)
Part 2.TIM输出比较
输出比较:
通过比较计数器(CNT)与捕获比较寄存器(CCR)之间的大小关系,来选择输出电平是1/0或者翻转的的操作。
可以通过该寄存器来输出PWM波,实现控制电机、舵机等任务。
每个高级定时器与通用定时器都有4个输出比较通道,所以,在制作麦轮小车时,可以只用一个TIM控制四个电机。
更值得一提的是,高级定时器的前3个通道额外用用死区生成和互补输出的功能。
1. 几个寄存器的英文及其缩写
英文全称
中文
缩写
Output Compare
输出比较
OC
InputCapture
输入捕获
IC
Capture/Compare
输入捕获与输出比较单元
CC
2.PWM
2.1 简介
image-20240316182430100
2.2 输出比较模式
image-20240316182829650
有效电平:高电平;无效电平:低电平。
PWM1和PWM2模式相似,仅仅只有电平不同,所以在实际使用的过程中完全可以按照PWM1使用即可
2.3 原理图
image-20240316183552303
这个图中,蓝色线是CNT的值,黄色线是ARR的值,红色线是CCR的值
当CNT自增时,他会先小于CCR,然后大于CCR,最后来到ARR时又会清零,并且不断重复这个过程。
我们可以在小于的部分输出低电平,大于的电平输出高电平,如此方可输出一个PWM波。
2.4 参数计算
image-20240316184227783
2.5 TB6612电机驱动
image-20240316190634893
3 代码实现-PWM驱动LED呼吸灯
3.1 Init
1 TIM_OCxInit(TIMy, &TIM_OCInitStructure)
配置输出比较单元,x可以是1,2,3,4四个数中任一的值,y也是。
这说明共有四个输出比较单元可供配置。
1 TIM_OCStructInit(&TIM_OCInitStructure)
配置结构体
1 TIM_SetComparex(TIMy, Compare)
设置占空比函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0 ; TIM_OC1Init(TIM2, &TIM_OCInitStructure);
注意,定时器使用引脚时需要使用复用推挽输出。
pwm.h
1 2 3 4 5 6 7 8 #ifndef __PWM_H #define __PWM_H void PWM_Init (void ) ;void PWM_SetCompare1 (uint16_t Compare) ;#endif
pwm.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 #include "stm32f10x.h" void PWM_Init (void ) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); TIM_InternalClockConfig(TIM2); TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStructure.TIM_Period = 100 - 1 ; TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1 ; TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0 ; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure); TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0 ; TIM_OC1Init(TIM2, &TIM_OCInitStructure); TIM_Cmd(TIM2, ENABLE); }void PWM_SetCompare1 (uint16_t Compare) { TIM_SetCompare1(TIM2, Compare); }
main.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include "stm32f10x.h" #include "Delay.h" #include "OLED.h" #include "PWM.h" uint8_t i;int main (void ) { OLED_Init(); PWM_Init(); while (1 ) { for (i = 0 ; i <= 100 ; i++) { PWM_SetCompare1(i); Delay_ms(10 ); } for (i = 0 ; i <= 100 ; i++) { PWM_SetCompare1(100 - i); Delay_ms(10 ); } } }