STM32系列第11篇--定时器
扫描二维码
随时随地手机看文章
STM32共有8个定时器:
通用定时器功能:
位于低速的APB1总线上(APB1)
16 位向上、向下、向上/向下(中心对齐)计数模式,自动装载计数器(TIMx_CNT)。
16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟分频。
4 个独立通道(TIMx_CH1~4),这些通道可以用来作为:输入捕获、输出比较、PWM 生成(边缘或中间对齐模式)、单脉冲模式输出 。
可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外一个定时器)的同步电路。
如下事件发生时产生中断/DMA(6个独立的IRQ/DMA请求生成器): 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发) 、触发事件(计数器启动、停止、初始化或者由内部/外部触发计数) 、输入捕获 、输出比较 等。
通用定时器时钟CK_INT=2*36M=72M
向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。
程序要求:
通过定时器中断配置,每500ms中断一次,然后中断服务函数中控制LED实现LED1状态取反(闪烁)。
Tout(溢出时间)=(ARR+1)(PSC+1)/Tclk
timer.c
#include"timer.h"#include"led.h"//通用定时器3中断初始化//这里时钟选择为APB1的2倍,而APB1为36M//arr:自动重装值。//psc:时钟预分频数//这里使用的是定时器3!voidTIM3_Int_Init(u16arr,u16psc){TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;NVIC_InitTypeDefNVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//时钟使能//定时器TIM3初始化TIM_TimeBaseStructure.TIM_Period=arr;//设置在下一个更新事件装入活动的自动重装载寄存器周期的值TIM_TimeBaseStructure.TIM_Prescaler=psc;//设置用来作为TIMx时钟频率除数的预分频值TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//设置时钟分割:TDTS=Tck_timTIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//TIM向上计数模式TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);//根据指定的参数初始化TIMx的时间基数单位TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//使能指定的TIM3中断,允许更新中断//中断优先级NVIC设置NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;//TIM3中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//先占优先级0级NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;//从优先级3级NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//IRQ通道被使能NVIC_Init(&NVIC_InitStructure);//初始化NVIC寄存器TIM_Cmd(TIM3,ENABLE);//使能TIMx}//定时器3中断服务程序voidTIM3_IRQHandler(void)//TIM3中断{if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)//检查TIM3更新中断发生与否{TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//清除TIMx更新中断标志LED1=!LED1;}}12345678910111213141516171819202122232425262728293031323334353637PWM输出
工作过程:
CCR1:捕获比较(值)寄存器(x=1,2,3,4):设置比较值。
CCMR1: OC1M[2:0]位:
对于PWM方式下,用于设置PWM模式1【110】或者PWM模式2【111】
模式1:计数值小于CCR1值为有效电平
模式2:计数值大于CCR1值为有效电平
CCER:CC1P位:输入/捕获1输出极性。0:高电平有效,1:低电平有效。
CCER:CC1E位:输入/捕获1输出使能。0:关闭,1:打开。
PWM输出配置步骤:
1、使能定时器3和相关IO口时钟。
使能定时器3时钟:RCC_APB1PeriphClockCmd();
使能GPIOB时钟:RCC_APB2PeriphClockCmd();
2、初始化IO口为复用功能输出。函数:GPIO_Init();
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
3、这里我们是要把PB5用作定时器的PWM输出引脚,所以要重映射配置,
所以需要开启AFIO时钟。同时设置重映射。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);
4、初始化定时器:ARR,PSC等:TIM_TimeBaseInit();
5、初始化输出比较参数:TIM_OC2Init();
6、使能预装载寄存器:
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
7、使能定时器。TIM_Cmd();
8、不断改变比较值CCRx,达到不同的占空比效果:TIM_SetCompare2();
程序要求:
使用定时器3的PWM功能,输出占空比可变的PWM波,用来驱动LED灯,从而达到LED【PB5]亮度由暗变亮,又从亮变暗,如此循环。
timer.c
voidTIM3_PWM_Init(u16arr,u16psc){//定义结构体变量GPIO_InitTypeDefGPIO_InitStructure;TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;TIM_OCInitTypeDefTIM_OCInitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能定时器3时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB"RCC_APB2Periph_AFIO,ENABLE);//使能GPIO时钟和AFIO复用功能模块时钟GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);//Timer3部分重映射TIM3_CH2->PB5//GPIO初始化,设置该引脚为复用输出功能,输出TIM3CH2的PWM脉冲波形GPIOB.5GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;//TIM_CH2GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitStructure);//初始化TIM3TIM_TimeBaseStructure.TIM_Period=arr;//设置在下一个更新事件装入活动的自动重装载寄存器周期的值TIM_TimeBaseStructure.TIM_Prescaler=psc;//设置用来作为TIMx时钟频率除数的预分频值TIM_TimeBaseStructure.TIM_ClockDivision=0;//设置时钟分割:TDTS=Tck_timTIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//TIM向上计数模式TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);//根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位//初始化TIM3Channel2PWM模式TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM2;//设置PWM模式2TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//比较输出使能TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//高电平有效TIM_OC2Init(TIM3,&TIM_OCInitStructure);//根据T指定的参数初始化外设TIM3OC2TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);//使能TIM3在CCR2上的预装载寄存器TIM_Cmd(TIM3,ENABLE);//使能TIM3}123456789101112131415161718192021222324252627282930
main.c
intmain(void){u16led0pwmval=0;u8dir=1;delay_init();//延时函数初始化NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置NVIC中断分组2:2位抢占优先级,2位响应优先级uart_init(115200);//串口初始化为115200LED_Init();//LED端口初始化TIM3_PWM_Init(899,0);//不分频。PWM频率=72000000/900=80Khzwhile(1){delay_ms(10);if(dir)led0pwmval++;elseled0pwmval--;if(led0pwmval>300)dir=0;if(led0pwmval==0)dir=1;TIM_SetCompare2(TIM3,led0pwmval);//设置占空比}}12345678910111213141516171819输入捕获:
输入捕获的一般配置步骤:
① 初始化定时器和通道对应IO的时钟。
② 初始化IO口,模式为输入:GPIO_Init();