蓝桥杯—SysTick中断精准定时实现闪烁灯

在嵌入式系统中,SysTick_Handler 是一个中断服务例程(Interrupt Service Routine, ISR),用于处理 SysTick 定时器的中断。SysTick 定时器通常用于提供一个周期性的定时中断,可以用来实现延时或者周期性任务。

SysTick_Handler中断的周期不一定是固定的1毫秒,它的周期取决于你对系统定时器配置的时钟源和计数器 reload 值。系统定时器通常使用微控制器的主时钟(Core Clock)作为时钟源,并且可以设置为任意时钟周期的N倍来决定中断频率。

但在蓝桥杯中,通常我们的时钟树配置都是一样的,时钟主频为80MHz,此时的SysTick_Handler 为每1ms触发一次中断。

利用这个特性,我们可以实现精准延时。

我们可以在stm32g4xx_it.c的最后找到SysTick_Handler 这个函数。在其中加入一些标志位可实现不少定时的功能。

注意:在中断中不能执行耗时过长的程序,中断通常用于处理需要立即响应的事件,如外部信号变化、定时器到期等。如果中断处理时间过长,会延迟对后续中断事件的响应,从而影响系统的实时性能。因此,中断处理程序应该设计得尽可能短小精悍,只执行必要的、时间关键的操作,如状态保存、事件标记、简单计算等。如果有需要执行耗时较长的程序,应该在中断处理程序中设置一个标志位,然后放在主函数的while(1)里执行。

SysTick_Handler中的程序

cpp 复制代码
u8 led_cnt =0;
void SysTick_Handler(void)
{
  led_cnt++;
	if(led_cnt>100){//用了简单的逻辑,可以改进
		led_flag=1;
	}
	if(led_cnt>200){
		led_flag=0;
		led_cnt=0;
	}
  HAL_IncTick();
}

使LED1以0.1s闪烁。

LED.c

cpp 复制代码
#include "led.h"

_Bool led_flag=0;
void LED_Control(u8 led_ctrl)
{
	//先熄灭所有LED灯
	HAL_GPIO_WritePin(GPIOC,0xff00,GPIO_PIN_SET);		//让PC8~PC15输出高电平,熄灭LED
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);	//打开锁存器
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);	//关闭锁存器
	
	//根据led_ctrl来点亮对应的LED
	HAL_GPIO_WritePin(GPIOC,led_ctrl<<8,GPIO_PIN_RESET);//根据led_ctrl输出低电平,点亮LED
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);	//打开锁存器
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);	//关闭锁存器
}
u8 led_ctrl=0x00;
void LED_Process(void){
	if(led_flag==1){
		led_ctrl |= 0x01;
		LED_Control(led_ctrl);
	}
	else {
		led_ctrl &= ~0x01;
		LED_Control(0x00);
	}
}

LD1-LD8分别对应0xff中从低到高的每一位,十六进制转换为四位二进制后更加清晰:

0xff ----> 1111 1111 (由高到低依次为 LD8 LD7...LD2 LD1)

想点亮哪个灯只需要将那一位置1,然后换算为16进制即可。

点亮LED1

cpp 复制代码
led_ctrl |= 0x01;

熄灭LED1

cpp 复制代码
led_ctrl &= ~0x01;

使LED1闪烁

cpp 复制代码
led_ctrl ^= 0x01;//^=是按位异或,可以切换LED的状态,如果是亮则熄灭,如果是熄灭则亮

led.h

cpp 复制代码
#ifndef __LED_H
#define __LED_H
#include "main.h"
extern _Bool led_flag;
void LED_Control(u8 led_ctrl);
void LED_Process(void);
extern u8 led_ctrl;
#endif
cpp 复制代码
while (1)
  {
		LED_Process();
  }

将LED_Process()放入while(1)中即可实现led以0.1s闪烁。

QQ视频20240528205900

相关推荐
悠哉悠哉愿意2 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
qq_459234422 天前
【题库】| 商用密码应用安全性评估从业人员考核题库(四十)
职场和发展·密码学·学习方法·考核·商用密码·商用密码应用安全性评估·密评
敲敲了个代码2 天前
[特殊字符] 空数组的迷惑行为:为什么 every 为真,some 为假?
前端·javascript·react.js·面试·职场和发展
Lester_11012 天前
STM32霍尔传感器输入口设置为复用功能输入口时,还能用GPIO函数直接读取IO的状态吗
stm32·单片机·嵌入式硬件·电机控制
三佛科技-187366133972 天前
120W小体积碳化硅电源方案(LP8841SC极简方案12V10A/24V5A输出)
单片机·嵌入式硬件
z20348315202 天前
STM32F103系列单片机定时器介绍(二)
stm32·单片机·嵌入式硬件
Alaso_shuang3 天前
STM32 核心输入、输出模式
stm32·单片机·嵌入式硬件
2501_918126913 天前
stm32死锁是怎么实现的
stm32·单片机·嵌入式硬件·学习·个人开发
诚思报告YH3 天前
视频面试软件市场洞察:2026 - 2032年复合年均增长率(CAGR)为10.3%
面试·职场和发展
重生之后端学习3 天前
74. 搜索二维矩阵
开发语言·数据结构·算法·职场和发展·深度优先