STM32F103C8 TIM输出比较与PWM

简介: STM32F103C8 TIM输出比较与PWM

图片及文章内容摘自江科大自化协B站视频

前言

这一部分的学习完全不知道原理是很难写好代码的,这篇博客主要通过代码实现的方式叙述,在不需要理解原理的部分直接套用模板代码,按照模板书写容易出错的地方我会加以说明,目的是能在最少时间理解原理的条件下快速的使用STM32


一、大致步骤

在直接展示代码之前,我先大概梳理一下用使用PWM的步骤,方便理解与总结后续的代码

第一步:开启RCC时钟,这里就是把TIM外设和GPIO外设的时钟打开

第二步:选择时钟源并配置时基单元

第三步:配置输出比较单元,包括CCR,输出比较模式等,套模板即可

第四步:配置GPIO为复用推挽输出模式,具体与PWM对应的引脚参考引脚定义表

第五步:运行控制,启动计数器

二、具体代码

1.呼吸灯

这里要用到的公式如下

其他的部分套用模板即可,具体易错点与不明白的点看代码注释,下面先放初始化函数,即一到四步

1. void PWM_Init(void)
2. {
3.  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
4.  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
5. 
6. // RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
7. // GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);
8. // GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
9. 
10.   GPIO_InitTypeDef GPIO_InitStructure;
11.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//想用定时器控制引脚,就要用复用输出
12.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;   //GPIO_Pin_15;
13.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
14.   GPIO_Init(GPIOA, &GPIO_InitStructure);
15. 
16.   TIM_InternalClockConfig(TIM2);
17. 
18.   TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
19.   TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
20.   TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
21.   TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;   //ARR
22.   TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;    //PSC
23.   TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
24.   TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
25. 
26.   TIM_OCInitTypeDef TIM_OCInitStructure;
27.   TIM_OCStructInit(&TIM_OCInitStructure);//如果对于每个变量不想都赋一遍值,则要用这个先帮你赋一遍默认值
28.   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
29.   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
30.   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
31.   TIM_OCInitStructure.TIM_Pulse = 0;    //CCR
32.   TIM_OC1Init(TIM2, &TIM_OCInitStructure);
33. 
34.   TIM_Cmd(TIM2, ENABLE);
35. }

上述代码我们就已经初始化好了GPIO与时钟,现在我们只需要改变CCR的值去不断改变占空比(高电平占总电平时间)就可以实现呼吸灯,代码如下。

1. void PWM_SetCompare1(uint16_t Compare)
2. {
3.  TIM_SetCompare1(TIM2, Compare);//compare后面的1表示的是通道1,这个函数是用来改变CCR的,这里compare的值就是CCR的值
4. }
5. 
6. uint8_t i;
7. 
8. int main(void)
9. {
10.   OLED_Init();
11.   PWM_Init();
12. 
13.   while (1)
14.   {
15.     for (i = 0; i <= 100; i++)
16.     {
17.       PWM_SetCompare1(i);
18.       Delay_ms(10);
19.     }
20.     for (i = 0; i <= 100; i++)
21.     {
22.       PWM_SetCompare1(100 - i);
23.       Delay_ms(10);
24.     }
25.   }
26. }

2.引脚重映射

通过引脚定义表我们知道某个定时器的某个通道对应的引脚是固定的,但是单片机给了我们一次重定义的机会,这个过程就叫引脚重映射,代码如下。这里代码的二三行就是改变引脚功能的函数,函数的第一个参数填的数据参考手册。这里的第二个函数是修改定时器2的通道1,但是那个引脚本来就有调试功能,所以第三行是关闭他的调试功能(一般需要关这种功能的有PA15 PB3 PB4,具体看引脚定义表中该引脚的主功能)

1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//先打开AFIO的RCC
2. GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);//选择要重映射类型
3. GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//关闭重映射后引脚原来的调试功能

一个定时器是可以同时开多个通道的,但是开出后的频率一定相同,占空比可以各自设定,相位是同步的.


总结

以上的代码都是对于通用定时器的操作,这里补充一下高级定时器的一些不同操作

这个函数仅高级定时器输出PWM时需要调用,需要使能主输出,否则PWM将不能正常输出

相关文章
|
4月前
STM32Cubemx PWM驱动加湿器模拟火山喷发效果
STM32Cubemx PWM驱动加湿器模拟火山喷发效果
64 14
|
4月前
STM32Cubemx PWM驱动SG90舵机
STM32Cubemx PWM驱动SG90舵机
145 13
|
4月前
STM32CubeMX PWM
STM32CubeMX PWM
60 9
|
3月前
|
编解码 算法
掌握PWM:STM32F103实现PWM控制直流电机小风扇
PWM,即脉冲宽度调制(Pulse Width Modulation),是一种广泛应用于电子和电机控制领域的信号编码方法。PWM的核心思想是通过改变数字信号的脉冲宽度来模拟模拟信号的幅度变化,从而达到控制输出功率的目的。
445 0
|
6月前
|
缓存 网络协议 算法
[蓝桥杯嵌入式]hal库 stm32 PWM的使用(随时修改占空比,随时修改频率)
[蓝桥杯嵌入式]hal库 stm32 PWM的使用(随时修改占空比,随时修改频率)
STM32学习笔记(4) 高级定时器-两路互补的PWM输出(带死区和刹车控制)
原理:当捕捉到信号的跳变沿时,将CNT的值所存到捕获寄存器CCR中,然后把两次的值相减,就可以得到脉宽或者频率。
1460 0