嵌入式开发–STM32G431RBTx-定时器中断流水灯
定时器工作原理
如图有反映stm32g431的定时器资源。
共10个定时器
定时器 | 定时器类型 | 个数 |
---|---|---|
TIM6,7 | 基本定时器 | 2 |
TIM2,3,4 | 全功能通用定时器 | 3 |
TIM15,16,17 | 通用定时器(只有1或2个通道) | 3 |
TIM1,8 | 高级控制定时器 | 2 |
- 当APB1/2分频系数为1时,给定时器的时钟为X1
- 当APB1/2分频系数不为1时,给定时器时钟需X2
基本定时功能,当累加的时钟脉冲数超过预定值时,能触发中断或者触发DMA请求。
是专门用于驱动数模转换器(DAC)
基本定时器TIM6/7内部结构图
- 核心功能是控制CK_INT时钟是否可以正常传输到PSC预分频器内
- 当更新事件发生的时候,重装载寄存器的数值才传递到影子寄存器里。影子寄存器是真正起作用的寄存器。当使用定时器过程中,如果不修改这个寄存器,就不涉及这个问题。
【寄存器组成】
计数器寄存器(TIMx_CNT)
预分频寄存器(TIMx_PSC)
自动重装载寄存器(TIMx_ARR)
这三个寄存器都是16位有效数字,可设置的值为0~65535。
【预分频器】
CK_CNT=CK_PSC/(PSC[15:0]+1)
【计数过程】
每来一个CK_CNT脉冲,TIMx_CNT值就加1,当TIMx_CNT值与TIMx_ARR的设定值相等时就自动生成更新事件(也可以产生DMA请求、产生中断信号或者触发DAC同步电路),并且TIMx_CNT自动清零,然后重新开始计数,不断重复上述过程。因此我们只要设定TIMx_PSC和TIMx_ARR这两个寄存器的值就可以控制事件生成时间。对应的就是程序中定时器预分频设置(斜率)和定时器周期。
基本定时器TIM6/7时钟和基本信号
配置定时器
设定TIM6定时器
设定系数
第一个是分频系数
(Prescaler)
第二个是周期计数值,按照分频后的时间进行计数(Counter Period)
80M的晶振除以8000,得到的工作频率为80 000 000/8 000=10 000
计算到ARR,如果是1s,就让ARR设置为10 000-1
如此频率乘周期即为时间,即为一次中断触发的时间为1s
使用中断
关于按键中断的实现
struct keys key[4]={0,0,0};
if(htim->Instance==TIM3)
{
key[0].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
key[1].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
key[2].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
key[3].key_sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
}
这段代码是一个中断回调函数,用于处理定时器 TIM3 的中断事件。代码中包含一个名为 key
的结构体数组,用于记录按键的状态。
在函数体中,首先通过读取 GPIO 引脚的状态,将按键的状态存储到 key
数组中的相应位置。其中,key[i].key_sta
表示第 i 个按键的状态。
接下来,使用一个循环遍历 key
数组的每个元素,对每个按键的状态进行判断和处理。
for(int i=0;i<4;i++)
{
switch (key[i].judge_sta)
{
case 0: //
{
if(key[i].key_sta==0) key[i].judge_sta=1;
}
break;
case 1:
{
if(key[i].key_sta==0)
{
key[i].judge_sta=2;
key[i].single_flag=1;
}
else key[i].judge_sta=0;
}
break;
case 2:
{
if(key[i].key_sta==1)
{
key[i].judge_sta=0;
}
}
break;
}
}
在 switch
语句中,根据 key[i].judge_sta
的值来确定需要执行的操作。key[i].judge_sta
表示按键的判断状态。
当key[i].judge_sta
的值为 0 时,表示按键处于初始状态。
- 如果按键的状态为按下(
key[i].key_sta
等于 0),则将key[i].judge_sta
的值设为 1,表示按键已按下。
当 key[i].judge_sta
的值为 1 时,表示按键已按下。
- 如果按键的状态仍然为按下,维持
key[i].judge_sta
的值为 1。 - 如果按键的状态变为松开(
key[i].key_sta
等于 1),则将key[i].judge_sta
的值设为 2,表示按键已松开,并将key[i].single_flag
的值设为 1,表示按键被单击。
当key[i].judge_sta
的值为 2 时,表示按键已松开。
- 如果按键的状态变为按下,将
key[i].judge_sta
的值设为 0,表示按键已按下。
功能实现
在stm32g4xx_it.c
文件中TIM6_DAC_IRQHandler
函数下添加如下内容。
void TIM6_DAC_IRQHandler(void)
{
HAL_TIM_IRQHandler(&htim6);
LED_Disp(ledFlag);
ledFlag = !ledFlag;
}
即可实现LED在一秒钟亮灭交替效果