基本定时器TIM6 TIM7的延时和定时中断
基本定时器和滴答定时器不同,它是在芯片外并不是在内核中
/*TIM6的延时配置*/
初始化配置:
{
时钟源使能
配置影子寄存器
人为UG位置一产生更新事件
清除标志位
配置重载值
配置预分频数
使能计数器
等待计数完成
配置单脉冲时间到停止计数
}
大家对这个影子寄存器可能会比较疑惑:
其实影子寄存器是存在与自动重载寄存器,和预分频寄存器本体里面的可以这样理解,而我们写程序直接操作的是本体寄存器里,由本体寄存器的值加载到影子寄存器,再由影子寄存器将数据传给作用与计数器,真正起作用的是影子寄存器。
为什么要人为置1产生更新事件呢:因为只有当产生更新事件时间到影子寄存器才工作将重载值和预分频置加载到影子寄存器中,所以当程序初始化第一次运行时需要我们人为产生更新事件,然后再清除标志位,再等待计数完成产生更新事件。
影子寄存器还有一个作用:就是可以保持计数周期的完整性。比如说我一次设置重载值为2000,当计数器从0开始计数当计数到1000时,我们又改变重载值改为1500,这个时候1500也不会加载到计数器里,因为只有当2000计数完产生更新事件了影子寄存器才起作用,才能将新的重载值加载到计数器里,所以影子寄存器很好的保护了计数的周期。
/*TIM7延时中断配置*/
初始化配置:
{
//定时器配置
时钟源使能
配置影子寄存器
人为UG位置一产生更新事件
清除标志位
配置重载值
配置预分频数
使能中断
使能计数器
//NVIC控制器配
优先级分组
计算优先级编码分组值
设置中断源
使能中断源通道
}
中断服务函数
{
清除标志位
处理紧急事件
}
设置为1ms进一次中断,处理四个不同时间的事件
void timer7_interrupt_ms(u16 ms)
{
/*定时器控制器配置*/
//定时器时钟使能
RCC->APB1ENR |= (1<<5);
//CR1 (3号位要写0,连续计数; 2号位写0 可以产生中断)
TIM7->CR1 |= (1<<7); //影子寄存器
TIM7->CR1 &= ~(1<<3); //连续计数
TIM7->CR1 &= ~(1<<2);
TIM7->CR1 &= ~(1<<1);
//分频寄存器
TIM7->PSC = 8400-1;
//重载值寄存器
TIM7->ARR = ms * 10 - 1;
//人为产生更新事件
TIM7->EGR |= (1<<0);
//清除中断标志位
TIM7->SR &= ~(1<<0);
/*NVIC控制器配置*/
//优先级分组--------主函数
//计算优先级编码值
u32 pri = NVIC_EncodePriority (5,2,3);
//确定具体中断源
NVIC_SetPriority(TIM7_IRQn,pri);
//使能NVIC响应通道
NVIC_EnableIRQ(TIM7_IRQn);
//更新中断使能
TIM7->DIER |= (1<<0);
//计数器使能
TIM7->CR1 |= (1<<0);
}
/***********************************************
*函数名 :TIM7_IRQHandler
*函数功能 :定时器中断服务函数
*函数参数 :无
*函数返回值:无
*函数描述 :
************************************************/
u32 timer7_cnt[10];
void TIM7_IRQHandler(void)
{
//清除标志位
TIM7->SR &= ~(1<<0);
//紧急事件
//紧急事件
timer7_cnt[1]++;
timer7_cnt[2]++;
timer7_cnt[3]++;
timer7_cnt[4]++;
//第一件事
if(timer7_cnt[1] == 301)
{
timer7_cnt[1] = 0;
LED1_OVERTURN;
}
//第二件事
if(timer7_cnt[2] == 522)
{
timer7_cnt[2] = 0;
LED2_OVERTURN;
}
//第三件事
if(timer7_cnt[3] == 655)
{
timer7_cnt[3] = 0;
LED3_OVERTURN;
}
//第四件事
if(timer7_cnt[4] == 980)
{
timer7_cnt[4] = 0;
LED4_OVERTURN;
}
}