本次实验基于stm32f407,基本定时器是TIM6和TIM7,这里用TIM6,让灯每秒改变一下状态。
对于基本定时器,时基如下:
CK_PSC来源于内部时钟,是内部时钟频率两倍,查阅数据手册
TIM6挂载到APB1总线,故CK_PSC=42Mhz2=84Mhz。另外说一下,高级定时器TIM1、TIM8和通用定时器TIM9、TIM10、TIM11挂载到APB2总线上,时钟源时钟为84Mhz2=168Mhz。
先假定自动重装载寄存器ARR为10000次,10^(-4)10000 = 1s,故输入ARR的时钟频率应为104hz,预分频值84106要分成104hz,PSC应该设置为8400分频,由于都是从0开始计数,所以ARR是10000-1,PSC是8400-1。计算完之后会产生中断,在中断服务函数里写代码实现即可。
知晓原理,接下来就是代码实现
首先依旧是配置好中断优先级,相关函数在misc.h。如下
void TIM_NVICConfig(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //中断优先级分组,组1模式,即主优先级1位,子优先级3位
NVIC_InitStructure.NVIC_IRQChannel = TIM6_DAC_IRQn;//中断源是TIM6
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
然后配置TIM6外设,相关函数在stm32f4xx_tim.h中
void TIM_ModeConfig(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);//注意要开时钟
TIM_TimeBaseInitStructure.TIM_Prescaler = 8400-1 ;
TIM_TimeBaseInitStructure.TIM_Period = 10000-1;
TIM_TimeBaseInit(TIM6, &TIM_TimeBaseInitStructure);//初始化后会产生更新中断,提示定时了一个周期
//上面初始化函数每次初始化之后会产生一个更新中断和更新事件
//更新事件用于重新装载CNT和ARR的值,所以为了系统定时再进入中断而不是一初始化就进入中断,这里清除中断标志位
TIM_ClearFlag(TIM6,TIM_FLAG_Update);
TIM_ITConfig(TIM6,TIM_IT_Update, ENABLE);//开启定时器更新中断
TIM_Cmd(TIM6, ENABLE);//使能定时器
}
再去头文件里找中断向量表,找到TIM6_DAC_IRQHandler ,这就是中断服务函数的名称。
去stm32f4xx_it.c写中断服务函数
void TIM6_DAC_IRQHandler(void)
{
if(TIM_GetITStatus(TIM6,TIM_IT_Update) == SET)//判断定时器是否产生中断
{
LED_1_TOGGLE;
TIM_ClearITPendingBit(TIM6,TIM_IT_Update);//清除中断标志位
}
}
最后主程序如下:
int main(void)
{
LED_Config();
TIM_NVICConfig();
TIM_ModeConfig();
}
即可实现灯的定时亮灭。
标签:定时器,TIM6,亮灭,中断,void,NVIC,TIM,LED From: https://www.cnblogs.com/manchestercity/p/17843434.html