PN学堂GD32教程第4篇——Systick
本文介绍了基于SysTick中断和状态机实现按键扫描的方法。首先通过SysTick定时器获取系统运行时间,重点讲解了24位递减计数器和重装载寄存器的工作原理。然后详细阐述了基于状态机和定时器的按键扫描实现方案,包括API接口定义和状态机设计。特别强调了中断向量表中句柄名称必须完全一致的重要性。最后通过实例分析了volatile关键字的作用,说明在中断服务函数中修改全局变量时必须使用volatile
·
本篇的主要目的是基于systick中断和状态机实现案件扫描的功能。
代码仓库:
git clone https://gitee.com/jumayusi/unit4-gd32-systick.git
4.1 基于systick实现获取系统运行时间
通过按键消抖这个实际应用场景引入systick。

systick硬件框图

控制寄存器介绍:

计数寄存器介绍:

它是一个24位的计数器,并且进行递减计数。
重装载寄存器介绍:

4.2 基于状态机和定时器实现按键扫描-1
API接口定义与数据类型

按键状态机

4.3 基于状态机和定时器实现按键扫描-2
中断向量表里面重载的句柄一定要一字不差!

昨天这个Tick的T写成了t排查了好久。。。
4.4 volatile关键字有什么作用?
在中断服务函数里面修改全局变量为1:
uint8_t g_pressFlag=0;
/**
***********************************************************
* @brief EXTI0中断服务函数,对应KEY1按键
* @param
* @return
***********************************************************
*/
void EXTI0_IRQHandler(void)
{
if(exti_interrupt_flag_get(EXTI_0)==SET){
//ToggleLed(LED1);
exti_interrupt_flag_clear(EXTI_0);
//while(1);
g_pressFlag=1;
}
}
然后在main方法中验证标记位的作用:
#include <stdint.h>
#include "delay.h"
#include "led_drv.h"
#include "key_drv.h"
extern uint8_t g_pressFlag;
int main(void)
{
DelayInit();
LedDrvInit();
keyDrvInit();
while(!g_pressFlag);
TurnOnLed(LED1);
while (1)
{
}
}
并没有出现我们期待的实验现象。
volatile关键字表示修饰的变量是“易变”的,这个变量的值随时都有可能发生变化,因此编译器在编
译时就不会对这个变量进行优化,每次读写变量时都会在内存中进行实时读写操作。

更多推荐



所有评论(0)