循环存储的LOG缓冲数组

在做一个单片机监测项目时,项目要求能够将一些报警以及状态信息作为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 %d\n",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 <time.h> 
#include <windows.h>
#include <conio.h>

这样就可以使用kbhit()与time()函数,kbhit()可以非阻塞地响应键盘输入。
完整程序如下:

#include <stdio.h>
#include <time.h> 
#include <windows.h>
#include <conio.h>

#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 %d\n",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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cedar_king

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值