利用基本定时器实现LED的定时亮灭

发布时间 2023-11-20 10:46:38作者: 京多安

本次实验基于stm32f407,基本定时器是TIM6和TIM7,这里用TIM6,让灯每秒改变一下状态。

对于基本定时器,时基如下:
image

CK_PSC来源于内部时钟,是内部时钟频率两倍,查阅数据手册
image
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 ,这就是中断服务函数的名称。
image
去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();
}

即可实现灯的定时亮灭。