1.定时器的选择
基本定时器:TIM1、TIM8(总线APB1)
拥有定时中断、主模式触发DAC的功能。
通用定时器:TIM6、TIM7(总线APB1)
拥有基本定时器全部功能,并额外具有内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等功能。
高级定时器:TIM2、TIM3、TIM4、TIM5(总线APB2)拥有通用定时器全部功能,并额外具有重复计数器、死区生成、互补输出、刹车输入等功能。
前面是向上计数,所以我们采用PWM2模式
PWM属于定时器的输出比较的功能,可选通用定时器和高级定时器,而由于我采用的是stm32f103c6芯片,只有PA和PB口,根据查表,我选择PA7对应就是TIM3_CH2
不同的TIM后缀和CH的后缀,你在写代码时,配置的函数或者参数也有出入
TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC2
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器
此处代码中俩个函数名称的TIM_OC2.....,这里的2对应就是前面选择配置的CH2的2,一定不能出错
定时器类型(TIM3),和复用通道(PA7:TIM3_CH2)确定后,着手配置参数。
注:如若你的通道TIM3_CH2与同一表格的ADC12_IN7占用冲突,后续你可以采用重映射,将其中一个,换到别的通道去。
2.代码逻辑流程
2.1时钟使能
时钟使能有俩种RCC_APB1PeriphClockCmd,RCC_APB2PeriphClockCmd,特殊的用APB1函数,普通用APB2函数。
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟
2.2初始化TIM3
定时周期时间=[(重装周期值+1)*(预分频值+1)]/(单片机设定频率)
本例程中:重装周期值为1000-1,预分频值720-1,单片机频率是72MHz。
总定时:10ms
时钟分割作者也不是很懂,一般设为0就行,有兴趣可以查阅相关资料
//初始化TIM3
TIM_TimeBaseStructure.TIM_Period = 1000-1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =720-1; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
2.3初始化TIM3 Channel2 PWM模式
一般默认PWM的选择如下
PWM1:向下计数
PWM2:向上计数
//初始化TIM3 Channel2 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC2
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器
2.4使能TIM3
TIM_Cmd(TIM3, ENABLE); //使能TIM3
3.完整代码与分析
标题2流程代码中,作者没有放入结构体,以下代码,前俩行是初始化的结构体。
作者自定义的函数名称,大家就别纠结了,我是用的上一个工程模板。
延迟头文件这里是用不到的为什么出现呢?参考上一条句子。
#include "stm32f10x.h" // Device header
#include "Delay.h"
void EXTIX_INIT(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外设和AFIO复用功能模块时钟
//初始化TIM3
TIM_TimeBaseStructure.TIM_Period = 1000-1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =720-1; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
//初始化TIM3 Channel2 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC2
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器
TIM_Cmd(TIM3, ENABLE); //使能TIM3
}
EXTIX_INIT();//总的初始化函数
TIM_SetCompare2(TIM3,500);//这个函数的后缀数字2也是与CH2挂勾,一定要注意
此函数的第二个参数占空比,最大值就是你设定的重装周期值为1000-1。
#include "stm32f10x.h"
#include "EXTI.h"
int main(void)
{
{
EXTIX_INIT();
TIM_SetCompare2(TIM3,500);
while(1);
}
}
4.仿真的环境搭建
这一步是最重要的,可以看的出来,stm32f103x,只有这几个系列的,所以你用Keil5软件建工程时要注意,单片机的选择
仿真视频
pwm基础仿真视频
作者的祝语:感谢以下的大大,知识分享,让我少了走很多弯路,但作者还是走了很多弯路,作者走的弯路,特别用红字加粗了,望大家注意!!!
————————————————
代码主体参考摘抄:CSDN博主「KeiSing」
原文链接:https://blog.csdn.net/weixin_44263402/article/details/109801403
————————————————
定时器的介绍参考摘抄:CSDN博主「Coder_貔貅」
原文链接:https://blog.csdn.net/qq_45336153/article/details/124640715
————————————————
PWM1与PWM2的区别参考摘抄:CSDN博主「乐乐小工厂」
原文链接:https://blog.csdn.net/le123didi/article/details/119885006
————————————————
STM32引脚功能图来源:CSDN博主「eewj」
原文链接:https://blog.csdn.net/eewj/article/details/127333625