真正能用于产品的代码为非阻塞代码,需要做分层和隔离,为此使用了队列结构,另外为了标志各个状态,使用大量的变量,这些都增加了RAM存储器的消耗,由于51的资源很有限,如何才能最大化的发挥RAM空间呢?本文来探讨这个问题。
初衷
笔者最近设计了一款键盘矩阵的模块,使用51单片机作为编码器,检测哪一个按键被按下,是长按,还是短按,并通过串口输出其键值,这样在其他的复杂的工程中,只需要直接用主处理器的串口读取键值并做相应的操作即可。这样就避免每次都根据不同的项目在主处理器上做大量的程序改动了,更换键盘也不会引起很大的改动。
而主处理器只需要预留一个串口即可,硬件平台变化后,不会影响IO口的规划,而如果直接使用主处理器,比如STM32,来控制键盘需要占用9个IO引脚,在不同的项目中切换时都需要重新规划IO口。
图1:键盘矩阵实物图 [1]
代码采用了非阻塞代码,并做了分层和隔离,为此使用了队列结构,另外为了标志各个状态,使用了大量的变量,这些都增加了RAM存储器的消耗,由于51的资源很有限,如果不做调整就会报错:
那么如何最大化发挥51单片机RAM的空间呢?
使用bit定义变量,或“降级”变量的类型
51提供bit定义,对于原来使用char、int的变量,如果其值只是0或者1,那么将其改为bit类型。
//满洲里国峰电子科技 guofengdianzi.com
//微信:GuoFengDianZi
//已下代码基于STC89C52
#define KEY_NOT_PRESSED 0
//之前做好的库函数中的变量定义
char Key11_Value=KEY_NOT_PRESSED;
//修改为bit类型
bit Key11_Value=KEY_NOT_PRESSED;
同样的如果变量的范围不需要那么大,将其降级,比如从int型修改为char型。
//满洲里国峰电子科技 guofengdianzi.com
//微信:GuoFengDianZi
//已下代码基于STC89C52
//之前做好的库函数中的变量定义
static unsigned int Key11TimerS,Key11TimerL;
//"降级“变量的类型
static unsigned char Key11TimerS,Key11TimerL;
减小缓存的大小
在非阻塞代码的结构中经常会用到队列、堆栈这样的结构,用作缓存,具体表现为一个数组,在RAM大小有限的情况下,应根据实际需要适当剪裁缓存区的大小,例如本案例中,键盘为慢速输入设备,而设备功能单一只是对按键键值传输,因此,可以将按键缓存区和串口缓存区的大小减小。
//满洲里国峰电子科技 guofengdianzi.com
//微信:GuoFengDianZi
//已下代码基于STC89C52
#define TXBUF_SIZE 64
//例如串口发送缓存
unsigned char TX_BUFF[TXBUF_SIZE];
//可考虑将TXBUF_SIZE的大小改小
//#define TXBUF_SIZE 8
然而修改了发送缓存的大小后,使用printf需要注意,例如:
//满洲里国峰电子科技 guofengdianzi.com
//微信:GuoFengDianZi
//已下代码基于STC89C52
#define TXBUF_SIZE 4
//例如串口发送缓存
unsigned char TX_BUFF[TXBUF_SIZE];
printf("------"):
使用串口助手打印:
图2:缓存不够,打印不完整
从图2中可以看出值只打印出了5个横线,说明缓存太小,后面几个横线打印不出来,这种情况在打印汉字的时候会出现乱码,需要注意。
将大型的数组放在外部RAM
STC89C52提供256字节的外部RAM,可以将大型的数组,缓存区放入其中,使用xdata关键字,例如上面的串口缓存区:
//满洲里国峰电子科技 guofengdianzi.com
//微信:GuoFengDianZi
//已下代码基于STC89C52
#define TXBUF_SIZE 64
//例如串口发送缓存
unsigned char xdata TX_BUFF[TXBUF_SIZE];
//可考虑将TXBUF_SIZE的大小改小
//#define TXBUF_SIZE 8
作者:潇洒的电磁波(专业:射频芯片设计、雷达系统、嵌入式。欢迎大家项目合作交流。)
微信:GuoFengDianZi
引用:
[1]:https://item.taobao.com/item.htm?spm=a2oq0.12575281.0.0.25911debCla5U3&ft=t&id=613868992343