主函数尽量避免死等的延时函数

主函数尽量避免死等的延时函数,第1张

文章目录
  • 前言
  • 一、实时性的重要性
  • 二、避免使用延时函数
  • 三、推荐做法
    • 1.main.c
    • 2.中断服务函数文件it.c


前言

我们编写单片机的程序的时候,大家最容易忽略的是它的实时性,所以导致会出现明明程序没有写错,但却出现bug,这是为什么呢? 是因为单片机的程序是裸机,没有带 *** 作系统。很多时候会被刚入门的单片机爱好者忽略掉实时性,导致会丢失事件。


一、实时性的重要性

我们先来谈谈为什么单片机有时候会丢失事件。首先,我们知道单片机程序是轮询模式,是一个语句执行完以后,再执行下一条语句,整个主函数就是一个进程,进程里面就只有一个线程。那么在这种模式下,我们完成一个项目会写很多的任务,这些任务都是有顺序的执行的。那么丢失事件是如何发生的呢?我用 图一 比较简易的代码来解释。
图一

程序分析:从图一的代码来看,一开始,没有检测到开盖事件,然后我的程序就一直往下跑。假如我的程序正在执行任务二,如果这时候,有开盖事件发生,但此时我正在执行任务二,那么我们是无法及时响应开盖事件的相应的动作。这时候,我们就丢失了一次开盖事件。

二、避免使用延时函数

由上面的介绍,我们终于知道了实时性的重要性了,这时候你应该也知道为什么我要说避免使用延时函数了吧?比如说:delay_ms(uint8_t ms)延时函数,我写了一个比较简单的程序 如图二(先不要考虑按键的软件消抖,这里重点是为了讲解为什么不要用延时函数)
图二

程序分析:从图二的代码来看,假如说一开始按键1被按下了,按道理来说,led1灯就会常亮三秒。可是我按完按键1后,很快我又按了按键2。这时候,你说,led2灯是否会亮? 很明显,答案是没有。
因为我按下按键1的时候,程序亮完灯以后,就什么事情都没干,一直死等三秒。这时候,就算我按下按键2,程序还在死等延时,不会做出led2灯亮的动作。

由此可见,我们在写程序的时候,尽量避免使用死等的延时函数。会很浪费CPU的资源和时间,而且实时性会变得很差,容易丢失事件。

三、推荐做法

假如说,你要延时1us,1ms,或者几十ms,用死等的延时函数,我觉得问题不大。毕竟单片机一条指令是us级别。对程序的实时性影响不大。但如果是延时1s,几秒这样,那就只能用其他方法了。
我这里推荐的是用滴答定时器计时方法,方法很多,不仅限于一种。

1.main.c
uint8_t g_led2_on_flag = 0;

void main(void) {
	uint8_t key2_flag = 0;
	while(1) {
		/* 假如有按键2被按下 */
		if(1 == key2_flag) {
			led2_on();		/* LED2灯亮 */
			g_led2_on_flag = 1;
		}

	}
}

2.中断服务函数文件it.c

代码如下(示例):

uint16_t led2_time = 0;
/* 滴答定时器中断服务函数:1ms中断一次 */
void SysTick_Handler() 
{
	if(g_led2_on_flag) {
		led2_time++;
		if(led2_time == 3000) {
			LED2_OFF;
			g_led2_on_flag = 0;
		}
	}
}


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/707154.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-24
下一篇 2022-04-24

发表评论

登录后才能评论

评论列表(0条)

保存