环形 缓冲区《转自数码之家》
1.环形缓冲区,命令不容易丢失
2.缓冲区大小可自定义
3.移植改写方便
看代码:
//宏定义
//系统可修改参数宏定义
#define BUFFER_SIEZ 64
//控制命令定义
#define COMMUNCIATE 0
#define SET_SYSTEM_CAL_FULL 1
#define SET_SYSTEM_CAL_MV_V 2
#define SET_SYSTEM_OL 3
#define SET_POWER_OFF_TIME 4 //设定系统关机时间
#define READ_SYSTEM_DATA 5
//变量定义
//串口缓冲区 建立一个环形缓冲区,收发
unsigned char xdata UART_Receive_Size=0;//串口缓冲区接收字节数
unsigned char xdata UART_Receive_First=0;//串口缓冲区接收字节开始位置
unsigned char xdata UART_Read_First=0;
unsigned char xdata UART_Buffer[BUFFER_SIEZ];//串口缓冲区
unsigned char xdata UART_Send_Byte_Ok=0;//发送一字节成功
//中断处理
串口初始化根据自己的单片机写就行
void UART0_Interrupt (void) interrupt 4
{
if(RI0) //如果是发中断,返回
{
RI0=0; //清除中断标志
if(UART_Receive_Size<=BUFFER_SIEZ)//缓冲区未满,装载数据
{
UART_Buffer[UART_Receive_First++]=SBUF0;
UART_Receive_Size++;//串口缓冲区接收字节数
if(UART_Receive_First>=BUFFER_SIEZ)//循环装入缓冲区
UART_Receive_First = 0;
}
}
if(TI0)
{
TI0=0;
UART_Send_Byte_Ok=1;
}
}
//在缓冲区中读取一帧数据
void Do_Commend()
{
unsigned char Buf[8]={0,0,0,0,0,0,0,0};//帧数据缓冲区
unsigned char i=0;
unsigned char data_packge_flag=0;
if(UART_Receive_Size>=8)//缓冲区字节数大于等于一个包字节数
{
while(UART_Receive_Size!=0)//寻找帧数据头
{
if(UART_Buffer[UART_Read_First]==0xaa)
{
if(UART_Read_First+7<BUFFER_SIEZ)
{
if(UART_Buffer[UART_Read_First+7]==0x55)
{
data_packge_flag=1;
break;
}
}
else
{
if(UART_Buffer[7-(BUFFER_SIEZ-UART_Read_First)]==0x55)
data_packge_flag=1;
break;
}
}
UART_Read_First++;
if(UART_Read_First>=BUFFER_SIEZ)//环形 缓冲区折行
UART_Read_First=0;
UART_Receive_Size--;
}
if(data_packge_flag==1)//寻找到枕头
{
for(i=0;i<8;i++)//读取帧数据
{
Buf=UART_Buffer[UART_Read_First];
UART_Receive_Size--;
UART_Read_First++;
if(UART_Read_First>=BUFFER_SIEZ)//环形 缓冲区折行
UART_Read_First=0;
}
data_packge_flag=0;
}
if(Buf[7]==0x55&&Buf[0]==0xaa) //接收到一个正确的数据包
{
switch(Buf[1])
{
case COMMUNCIATE :UART0_Send_String(Buf,8);
break;
case
SET_SYSTEM_CAL_FULL
:System_Senser_Full=(Buf[2]|0x0000)<<8|Buf[3];
System_Zero_Display_Data=(Buf[4]|0x0000)<<8|Buf[5];
UART0_Send_String(Buf,8);save_data=1;System_K_Cal_Full();//在系统标定
break;
case
SET_SYSTEM_OL
:System_UPOL=(Buf[2]|0x0000)<<8|Buf[3];System_DWOL=
(Buf[4]|0x0000)<<8|Buf[5];UART0_Send_String(Buf,8);save_data=1;//设
定系统上限报警值
break;
case SET_SYSTEM_CAL_MV_V
:System_Senser_mv_v=(Buf[2]|0x0000)<<8|Buf[3];
System_Zero_Cal=ADC_Senser_Data_Buf;System_Zero=System_Zero_Cal;
UART0_Send_String(Buf,8);save_data=1;System_K_Cal_mv_v();//电子标定
break;
case
SET_POWER_OFF_TIME :
System_Power_OFF_Time=(Buf[2]|0x0000)<<8|Buf[3];
UART0_Send_String(Buf,8);save_data=1;//设定系统自动关机时间
break;
case
READ_SYSTEM_DATA :
Buf[1]=READ_SYSTEM_DATA;Buf[3]=ADC_Senser_Data_Buf;
Buf[2]=ADC_Senser_Data_Buf>>8;Buf[5]=ADC_Power_Voltage;
Buf[4]=ADC_Power_Voltage>>8;UART0_Send_String(Buf,8);//获取传感器信号ADC值
Buf[1]=SET_SYSTEM_CAL_FULL;
Buf[3]=System_Senser_Full;Buf[2]=System_Senser_Full>>8;
Buf[5]=System_Zero_Display_Data;Buf[4]=System_Zero_Display_Data>>
8;UART0_Send_String(Buf,8);//返回正确的数据包;//获取系统保存参数
Buf[1]=SET_SYSTEM_OL;Buf[3]=System_UPOL;Buf[2]=System_UPOL>>8;Buf[5]=System_DWOL;Buf[4]=System_DWOL>>8;UART0_Send_String(Buf,8);
Buf[1]=SET_SYSTEM_CAL_MV_V
;Buf[3]=System_Senser_mv_v;Buf[2]=System_Senser_mv_v>>8;Buf[5]=System_Zero;Buf[4]=System_Zero>>8;UART0_Send_String(Buf,8);
Buf[1]=SET_POWER_OFF_TIME;Buf[2]=System_Power_OFF_Time;Buf[3]=System_Power_OFF_Time>>8;UART0_Send_String(Buf,8);
break;
default:save_data=0;//不保存数据
break;
}
}
}
}