裸机程序设计模式

裸机程序的设计模式可以分为:轮询、前后台、定时器驱动、基于状态机。前面三种方法都无法解决一个问题:假设有A、B两个都很耗时的函数,无法降低他们互相之间的影响。第4中方法可以解决这个问题,但是实践起来有难度。

1、轮询模式

cpp 复制代码
// 经典单片机程序: 轮询
02 void main()
03 {
04 while (1)
05 {
06 喂一口饭();
07 回一个信息();
08 }
09 }

while循环里有两个函数,这两个函数之间有影响,一个函数运行时间较长,另一个函数就迟迟无法运行。

2、前后台

所谓前后台,就是指使用中断程序。

cpp 复制代码
// 前后台程序
02 void main()
03 {
04 while (1)
05 {
06 // 后台程序
07 喂一口饭();
08 }
09 }
10
11 // 前台程序
12 void 滴_中断()
13 {
14 回一个信息();
15 }

while循环里面的是后台程序,中断里是前台程序,中断程序的执行是非常及时的,但是如果中断函数执行很长,就会造成后台程序运行不及时。

cpp 复制代码
// 前后台程序
02 void main()
03 {
04 while (1)
05 {
06 // 后台程序
07 }
08 }
09
10 // 前台程序
11 void 滴_中断()
12 {
13 回一个信息();
14 }
15
16 // 前台程序
17 void 啊_中断()
18 {
19 喂一口饭();
20 }

改进后,将两个程序都写成前台程序(中断程序),但是如果两个程序同时需要执行,那么就会受影响。

3、定时器驱动

定时器驱动模式,是前后台模式的一种,可以按照不用的频率执行各种函数。比如需要

每 2 分钟给小孩喂一口饭,需要每 5 分钟给同事回复信息。那么就可以启动一个定时器,让

它每 1 分钟产生一次中断,让中断函数在合适的时间调用对应函数。示例代码如下:

cpp 复制代码
// 前后台程序: 定时器驱动
02 void main()
03 {
04     while (1)
05     {
06     // 后台程序
07     }
08 }
09
10 // 前台程序: 每 1 分钟触发一次中断
11 void 定时器_中断()
12 {
13     static int cnt = 0;
14     cnt++;
15     if (cnt % 2 == 0)
16     {
17     喂一口饭();
18     }
19     else if (cnt % 5 == 0)
20     {
21     回一个信息();
22     }
23 }

每发生2次中断,就执行一次喂饭程序,每发生5次中断,就执行一次回一个信息。这种模式适合调用周期性的函数,并且每一个函数执行的时间不能超过一个定时器周期。如果函数执行时间超过定时器周期,那么函数之间就会受影响。

4、基于状态机

当"喂一口饭"、"回一个信息"都需要花很长的时间,无论使用前面的哪种设计模式,

都会退化到轮询模式的缺点:函数相互之间有影响。可以使用状态机来解决这个缺点,示例

代码如下:

cpp 复制代码
// 状态机
02 void main()
03 {
04     while (1)
05     {
06     喂一口饭();
07     回一个信息();
08     }
09 }

01 void 喂一口饭(void)
02 {
03     static int state = 0;
04     switch (state)
05     {
06     case 0:
07     {
08     /* 舀饭 */
09     /* 进入下一个状态 */
10     state++;
11     break;
12     }
13     case 1:
14     {
15     /* 喂饭 */
16     /* 进入下一个状态 */
17     state++;
18     break;
19     }
20     case 2:
21     {
22     /* 舀菜 */
23     /* 进入下一个状态 */
24     state++;
25     break;
26     }
27     case 3:
28     {
29     /* 喂菜 */
30     /* 恢复到初始状态 */
31     state = 0;
32     break;
33     }
34     }
35   }
36
37 void 回一个信息(void)
38 {
39     static int state = 0;
40
41     switch (state)
42     {
43         case 0:
44         {
45         /* 查看信息 */
46         /* 进入下一个状态 */
47         state++;
48         break;
49         }
50         case 1:
51         {
52         /* 打字 */
53         /* 进入下一个状态 */
54         state++;
55         break;
56         }
57         case 2:
58         {
59         /* 发送 */
60         /* 恢复到初始状态 */
61         state = 0;
62         break;
63         }
64     }
65 }

使用状态机模式,可以解决裸机程序的难题:假设有 A、 B 两个都很耗时的函数,怎样

降低它们相互之间的影响。但是很多场景里,函数 A、 B 并不容易拆分为多个状态,并且这

些状态执行的时间并不好控制。所以这并不是最优的解决方法,需要使用多任务系统。

相关推荐
Yue丶越4 小时前
【C语言】字符函数和字符串函数
c语言·开发语言·算法
蓝牙先生6 小时前
简易TCP C/S通信
c语言·tcp/ip·算法
Old_Driver_Lee7 小时前
C语言常用语句
c语言·开发语言
松涛和鸣7 小时前
从零开始理解 C 语言函数指针与回调机制
linux·c语言·开发语言·嵌入式硬件·排序算法
无限进步_10 小时前
C语言动态内存的二维抽象:用malloc实现灵活的多维数组
c语言·开发语言·数据结构·git·算法·github·visual studio
星轨初途12 小时前
数据结构排序算法详解(5)——非比较函数:计数排序(鸽巢原理)及排序算法复杂度和稳定性分析
c语言·开发语言·数据结构·经验分享·笔记·算法·排序算法
f***019313 小时前
CC++链接数据库(MySQL)超级详细指南
c语言·数据库·c++
小曹要微笑14 小时前
STM32F7 时钟树简讲(快速入门)
c语言·stm32·单片机·嵌入式硬件·算法
前端世界16 小时前
float 还是 double?用储罐体积计算带你看懂 C 语言浮点数的真实世界坑
java·c语言·开发语言
小青龙emmm17 小时前
2025级C语言第二次周测(国教专用)题解
c语言·开发语言·算法