• 环形 缓冲区《转自数码之家》


    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;
              }      
         }    
      }
    }

  • 相关阅读:
    一条命令深度清理你的mac
    将以太坊封装为 ERC20
    golang subprocess tests
    go 笔记
    readme
    如何使用 channel
    修改vscode caipeiyu.writeCnblog ,简化博客发布
    thedao
    firefox 59 无法使用 pac 代理上网
    scrapy简单使用
  • 原文地址:https://www.cnblogs.com/locean/p/6101437.html
Copyright © 2020-2023  润新知