在做一个单片机监测项目时,项目要求能够将一些报警以及状态信息作为2或者4字节的LOG存到EE2PROM中,供客户随时导出查看。
要求和实现过程都比较简单,但是在测试过程中发现有一个小问题:由于EE2PROM的存储过程相较于单片机运行速度来说还是比较慢的,存储数据时会有5ms左右的不响应,所以在同时有多个LOG出现时,会有漏存的情况发生,虽然存储指针正常增加,但实际未存储,EE2PROM内容仍为FF。
所以考虑开辟一个100或200字节左右的缓冲数组,LOG先存在这个数组中,待系统有空闲再依次写入。这就要求该数组能够循环存取。
在付诸行动之前,先写一个小程序测试可行性:
预期实现的功能是每隔1s将输入的数字或字母按照输入顺序输出,即使不再按键,也会将数组中保存的输出。暂定义缓冲的数组大小为10,所以如果按的太快,超出的部分丢弃。
首先编写存储和取出的子程序:
定义需要使用的变量:
static unsigned short logdata_storage[N] = {0}; //定义存储数组
static unsigned short logdata_Put_in= 0; //存储地址
static unsigned short logdata_Take_out= 0; //取出地址
当空闲时,如果存储和取出地址不同,则表示仍有数据待输出,需要注意到达数组边界时要转到头部:
if(logdata_Take_out != logdata_Put_in)
{
printf("%c %d %dn",logdata_storage[logdata_Take_out],logdata_Put_in,logdata_Take_out);
logdata_Take_out++;
if(logdata_Take_out >= N) logdata_Take_out = 0;
}
else
{
ret = 1;
return ret;
}
存入数据时,只要保证存入地址最多到达取出地址减一的位置即可,因为如果相等了,即适用上面数据输出完毕的情况,这显然是不合适的。
logdata_storage[logdata_Put_in] = logdata;
if (logdata_Put_in != logdata_Take_out - 1)
{
logdata_Put_in++;
if(logdata_Put_in >= logdata_Take_out)
if(logdata_Put_in >= N) logdata_Put_in = 0;
}
主程序方面,由于是在windows环境下,所以还需要包含如下头文件:
#include#include #include
这样就可以使用kbhit()与time()函数,kbhit()可以非阻塞地响应键盘输入。
完整程序如下:
#include#include #include #include #define N 10 unsigned char save_log(unsigned short logdata); int main(){ unsigned char i,j = 0; time_t start, current = 0; //在windows下获取时间,以用来实现1S间隔 while(j != 27) //判断是否按下ESC键 { if(kbhit()) //判断是否有按键内容 { j = getch(); save_log(j); //有则存储 } time(&start); //获取当前时间 if((current - start) != 0) //1S间隔 { current = start; save_log(0); //0为显示参数 } } return 0; } unsigned char save_log(unsigned short logdata) { unsigned char i = 0; unsigned char ret = 0; static unsigned short logdata_storage[N] = {0}; //定义存储数组 static unsigned short logdata_Put_in= 0; //存储地址 static unsigned short logdata_Take_out= 0; //取出地址 if(logdata == 0) { if(logdata_Take_out != logdata_Put_in) { printf("%c %d %dn",logdata_storage[logdata_Take_out],logdata_Put_in,logdata_Take_out); logdata_Take_out++; if(logdata_Take_out >= N) logdata_Take_out = 0; } else { ret = 1; return ret; } } else { logdata_storage[logdata_Put_in] = logdata; if (logdata_Put_in != logdata_Take_out - 1) { logdata_Put_in++; if(logdata_Put_in >= logdata_Take_out) if(logdata_Put_in >= N) logdata_Put_in = 0; } } return ret; }



