1、定时器中断
定时器的分类:
通用定时器框图:
定时器和总线对应关系:
实验:在LCD屏幕上每秒滚动显示字符。
配置步骤:
(1)、TIM3 时钟使能。
(2)、初始化定时器参数,设置自动重装值,分频系数,计数方式等
(3)、设置 TIM3_DIER 允许更新中断。
(4)、TIM3 中断优先级设置。
(5)、允许 TIM3 工作,也就是使能 TIM3。
(6)、编写中断服务函数。
TIM.c:
#include "Headfile.h"
u8 TimCount = 0;
//Tout = (ARR+1)(PSC+1)/Tclk 时间计算公式
void Timer3InteruptInit(u16 arr, u16 psc){
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//(1)、TIM3 时钟使能。
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能TIM3时钟
//(2)、初始化定时器参数,设置自动重装值,分频系数,计数方式等
TIM_TimeBaseInitStructure.TIM_Period = arr;//自动重装值
TIM_TimeBaseInitStructure.TIM_Prescaler = psc;//分频系数
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//计数方式
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//设置时钟分割
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
//(3)、设置 TIM3_DIER 允许更新中断。
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
//(4)、TIM3 中断优先级设置。
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寄存器
//(5)、允许 TIM3 工作,也就是使能 TIM3。
TIM_Cmd(TIM3,ENABLE);
}
//(6)、编写中断服务函数。
void TIM3_IRQHandler(void){
if(TIM_GetFlagStatus(TIM3,TIM_FLAG_Update) == SET){
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}
TimCount ++;
LCD_DisplayStringLine(Line4 ,&(TimCount));
}
main.c:
#include "Headfile.h"
//Main Body
int main(void)
{
SysTick_Config(SystemCoreClock/1000);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
Timer3InteruptInit(9999,7199);//1s
LEDInit();
Delay_Ms(100);
STM3210B_LCD_Init();
LCD_Clear(Blue);
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
LCD_DisplayStringLine(Line4 ,(unsigned char *)" Hello,world. ");
LCD_Clear(Blue);
while(1);
}
2、定时器输出PWM
TIM3重映射表:
两种PWM_OC_MODE
:
PWM1
模式:向上计数时,一旦TIMx_CNT
<TIMx_CCR3
时通道3为有效电平;在向下计数时,一旦TIMx_CNT
>TIMx_CCR1
时通道3为无效电平。
则为有效电平(OC1REF=1)。
PWM2
模式:在向上计数时,一旦TIMx_CNT
<TIMx_CCR3
时通道3为无效电平;在向下计数时,一旦TIMx_CNT
>TIMx_CCR3
时通道3为有效电平。
(有效电平是高电平还是低电平可以在TIM_OCPolarity
设置。)
下面是PWM2模式(有效电平是高电平)示意图:
实验:LD1、LD2(PC8、PC9)呼吸灯交替闪烁。
配置步骤:
(1)开启 TIM3 时钟以及复用功能时钟,配置 PB8、PB9 为复用输出。
(2)、设置 TIM3_CH3 TIM3_CH4 重映射到 PB8、PB9 上。
(3)、初始化 TIM3,设置 TIM3 的 ARR 和 PSC。
(4)、设置 TIM3_CH3(4) 的 PWM 模式,使能 TIM3 的 CH3 (4)输出。
(5)、修改 TIM3_CCR3、TIM3_CCR4 来控制占空比。
TIM.c:
#include "Headfile.h"
void Timer3PWMInit(u16 arr, u16 psc){
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
//(1)开启 TIM3 时钟以及复用功能时钟,配置 PB8、PB9 为复用输出。
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能TIM3时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOC,ENABLE);
//(2)、设置 TIM3_CH3 TIM3_CH4 重映射到 PB8、PB9 上。
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE);//通过Datasheet可知PC8和PC9对应TIM3PWM输出为完全重映射
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOC,&GPIO_InitStructure);
//(3)、初始化 TIM3,设置 TIM3 的 ARR 和 PSC。
TIM_TimeBaseInitStructure.TIM_Period = arr;
TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
//PC8 PWM输出设置TIM3_CH3
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //PWM输出模式
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性高
TIM_OC3Init(TIM3,&TIM_OCInitStructure);
//(4)、设置 TIM3_CH3 的 PWM 模式,使能 TIM3 的 CH3 输出。
TIM_OC3PreloadConfig(TIM3,TIM_OCPreload_Enable);
//PC9 PWM输出设置TIM3_CH4
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC4Init(TIM3,&TIM_OCInitStructure);
//(4)、设置 TIM3_CH4 的 PWM 模式,使能 TIM3 的 CH4 输出。
TIM_OC4PreloadConfig(TIM3,TIM_OCPreload_Enable);
//
TIM_Cmd(TIM3,ENABLE);
}
main.c:
#include "Headfile.h"
int main(void)
{
u16 led0pwmval = 0;
u8 dir = 1;
SysTick_Config(SystemCoreClock/1000);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
LEDInit();
//闪灯
Delay_Ms(200);
LEDCmd(Bit_SET);
GPIO_Write(GPIOC,GPIO_ReadOutputData(GPIOC) & 0x00FF);
LEDCmd(Bit_RESET);
Delay_Ms(200);
LEDCmd(Bit_SET);
GPIO_Write(GPIOC,GPIO_ReadOutputData(GPIOC) | 0xFF00);
LEDCmd(Bit_RESET);
//
LEDCmd(Bit_SET);
Timer3PWMInit(899,99);//72000000/900/1000=800Hz ω=72MHz/arr/psc
// STM3210B_LCD_Init();
// LCD_Clear(Blue);
// LCD_SetBackColor(Blue);
// LCD_SetTextColor(White);
while(1){
Delay_Ms(10);
if(dir)led0pwmval++;
else led0pwmval--;
if(led0pwmval>300)dir=0;
if(led0pwmval==0)dir=1;
//(5)、修改 TIM3_CCR3、TIM3_CCR4 来控制占空比。
TIM_SetCompare3(TIM3,led0pwmval); //LD1
TIM_SetCompare4(TIM3,301-led0pwmval); //LD2
}
}
3、定时器复用功能重印象表
Tips:蓝桥板子上使用的是64脚。