- 前言
- 一、实时性的重要性
- 二、避免使用延时函数
- 三、推荐做法
- 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,几秒这样,那就只能用其他方法了。
我这里推荐的是用滴答定时器计时方法,方法很多,不仅限于一种。
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;
}
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)