中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行。
单片机中的中断类型主要分为外部中断和定时器中断。其中定时器中断又可以细分为很多的类型,比如看门狗中断也是某种类型的定时器中断。定时器中断主要是指内部或者外部时钟计时溢出后产生中断的类型。外部中断是指,接受到某个外部IO信号后直接产生中断的类型。
简单说就是暂停手头的事情,去做另外一件事情(中断事件),等事情(中断事件)搞定了再回头去处理一开始停下来的事情。
并且中断是可以嵌套的,就是可以套娃。但是中断调用栈是有限的,同时中断源也是有限的,就是说不能够无限的套娃。
中断具有优先级,高优先级可以打断低优先级,反之则不可以。相当于大领导可以打断小领导,小领导可以打断打工人,反之不行。
中断会影响主程序的运行,所以要尽量少的使用中断,使用中断时也要减少中断内程序的运行时间,过长时间的中断会影响主程序的运行。
在STM32中定时器的主要作用是定时(触发定时中断)、输入捕获、输出比较、生成PWM波(这点和51不同,51要自己去写PWM,STM32可以直接生成)、单脉冲输出等功能。
在STM32F407中定时器的资源十分的多。大体上可以分为以下几类。
16 位自动重载递增计数器(只能递增计数)
16 位可编程预分频器
用于触发 DAC 的同步电路(这两个定时器除了用于生成时基之外,还专门用于驱动数模转换器DAC)
16 位自动重载递增计数器(只能递增计数)
16 位可编程预分频器
都拥有四个通道,可用于输入捕获、输出比较、PWM生成、单脉冲输出
TIM3 和 TIM4拥有16位递增、递减和递增/递减自动重载计数器。
TIM2 和 TIM5拥有32位递增、递减和递增/递减自动重载计数器。
16 位可编程预分频器
都拥有四个通道,可用于输入捕获、输出比较、PWM生成、单脉冲输出
使用外部信号控制定时器且可实现多个定时器互连的同步电路。
支持定位用增量(正交)编码器和霍尔传感器电路
外部时钟触发输入或逐周期电流管理。
高级控制定时器(TIM1 和 TIM8)包含一个 16 位自动重载计数器,该计数器由可编程预分
频器驱动。
此类定时器可用于各种用途,包括测量输入信号的脉冲宽度(输入捕获),或者生成输出波形(输出比较、PWM 和带死区插入的互补 PWM)。
使用定时器预分频器和 RCC 时钟控制器预分频器,可将脉冲宽度和波形周期从几微秒调制
到几毫秒。
高级控制定时器(TIM1 和 TIM8)和通用 (TIMx) 定时器彼此完全独立,不共享任何资源。
TIM1 和 TIM8 主要特性
16 位递增、递减、递增/递减自动重载计数器。
16 位可编程预分频器,用于对计数器时钟频率进行分频(即运行时修改),分频系数
介于 1 到 65536 之间。
4 个独立通道,可用于:输入捕获/输出比较/PWM 生成(边沿和中心对齐模式)/单脉冲模式输出
带可编程死区的互补输出。
使用外部信号控制定时器且可实现多个定时器互连的同步电路。
重复计数器,用于仅在给定数目的计数器周期后更新定时器寄存器。
用于将定时器的输出信号置于复位状态或已知状态的断路输入。
中断请求情况:发生如下事件时生成中断/DMA 请求:1.更新:计数器上溢/下溢、计数器初始化(通过软件或内部/外部触发)2.触发事件(计数器启动、停止、初始化或通过内部/外部触发计数)3.输入捕获4.输出比较5.断路输入
支持定位用增量(正交)编码器和霍尔传感器电路
外部时钟触发输入或逐周期电流管理。
TIM1 和 TIM8 功能
时基单元包括:● 计数器寄存器 (TIMx_CNT)● 预分频器寄存器 (TIMx_PSC)● 自动重载寄存器 (TIMx_ARR)● 重复计数器寄存器 (TIMx_RCR)
预分频器可对计数器时钟频率进行分频,分频系数介于 1 和 65536 之间。该预分频器基于TIMx_PSC 寄存器中的 16 位寄存器所控制的 16 位计数器。由于该控制寄存器具有缓冲功能,因此可对预分频器进行实时更改。而新的预分频比将在下一更新事件发生时被采用。
设置预分频寄存器后,计数器由预分频器输出 CK_CNT 提供时钟。计数器将在 TIMx_CR1 寄存器的 CEN 位置 1 时刻的一个时钟周期后开始计数。
自动重载寄存器是预装载的。对自动重载寄存器执行写入或读取操作时会访问预装载寄存
器。预装载寄存器的内容既可以直接传送到影子寄存器,也可以在每次发生更新事件 (UEV) 时传送到影子寄存器,这取决于 TIMx_CR1 寄存器中的自动重载预装载使能位 (ARPE)。当计数器达到上溢值(或者在递减计数时达到下溢值)并且 TIMx_CR1 寄存器中的 UDIS 位为 0 时,将发送更新事件。该更新事件也可由软件产生。
影子寄存器:影子寄存器是ARM的一个特点。通过引入影子寄存器,指令可以重复使用相同的寄存器编码,但是在不同模式下,这些编码对应不同的物理寄存器。
如果不理解也不影响编程,如果想深入了解可以看看手册和这个帖子:http://www.openedv.com/posts/list/38720.htm 个人觉得解释的不错
1)递增计数
所有定时器都有递增计数模式
在递增计数模式下,计数器从 0 计数到自动重载值(TIMx_ARR 寄存器的内容),然后重新从 0 开始计数并生成计数器上溢事件。
2)递减计数
TIM1~TIM5、TIM8
在递减计数模式下,计数器从自动重载值(TIMx_ARR 寄存器的内容)开始递减计数到 0, 然后重新从自动重载值开始计数并生成计数器下溢事件。
3)中心对齐模式(递增/递减计数)
TIM1~TIM5、TIM8
在中心对齐模式下,计数器从 0 开始计数到自动重载值(TIMx_ARR 寄存器的内容)-1, 生成计数器上溢事件;然后从自动重载值开始向下计数到 1 并生成计数器下溢事件。之后从0 开始重新计数。
此模式下无法写入方向位(TIMx_CR1 寄存器中的 DIR 位)。而是由硬件更新并指示当前计数器方向。
每次发生计数器上溢和下溢时都会生成更新事件,或将 TIMx_EGR 寄存器中的 UG 位置 1(通过软件或使用从模式控制器)也可以生成更新事件。这种情况下,计数器以及预分频器计数器将重新从 0 开始计数。
1)内部时钟 (CK_INT):所有定时器。
2)外部时钟模式 1:外部输入引脚:TIM1、2、3、4、5、8、9、12
3)外部时钟模式 2:外部触发输入 ETR:TIM1、2、3、4、8
4)外部触发输入 (ITRx):使用一个定时器作为另一定时器的预分频器,例如,可将定时器1 配置为定时器 2 的预分频器。:TIM1、2、3、4、5、8、9、12
选择定时器,配置时钟源,设置预分频系数,计数模式,设置自动重装载值
计算公式
不过一般情况下定时时间都是毫秒级别。
时钟频率是84Mhz这里进行84分频,就是1Mhz,也就是每秒10的6次方个脉冲。而重装载值是10000,每秒可以触发100个中断,也就是定时时间是10ms。
然后要设置中断向量表
接着点击GENERATE CODE生成代码。
功能:实现LED0每秒翻转,LED1每10秒翻转
编写中断回调函数
这一点和标准库不同,标准库要我们自己编写中断程序,而HAL库在HAL_XXX_IRQHandler这一类的函数里面帮我们完成了,只需要自己在回调函数中加上应用程序就可以。
//定时器开启的时候记得设置CUBE里面的NVIC
uint16_t t3_count;
uint16_t t3_count2;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *hitm)
{
if(hitm ->Instance ==TIM1)
{
}
if(hitm ->Instance ==TIM3)//定时器3,定时时间10ms
{
t3_count++;
if(t3_count>=100)//1s
{
t3_count=0;
Led0_Toggle;
t3_count2++;
if(t3_count2>=10)//10s
{
Led1_Toggle;
t3_count2=0;
}
}
}
}
在主函数中启动时基
__HAL_TIM_CLEAR_IT(&htim3,TIM_IT_UPDATE ); //清除IT标志位
HAL_TIM_Base_Start_IT(&htim3); //启动时基
《STM32F4xx中文参考手册》
感谢各位的浏览。鄙人水平有限,很多地方写的感觉差强人意,如果有不对的地方欢迎指正。