×
嵌入式 > 技术百科 > 详情

于GPS_CHECKTIAMER串口收发程序

发布时间:2020-06-15 发布时间:
|
单片机串口发送接收程序,下面是关于GPS_CHECKTIAMER,局部应用程序

 

#define UART_R_LEN  60
#define UART_T_LEN  34

uchar idata trdata[UART_T_LEN];     //定义串口发送缓冲区
uchar idata gpsdata[UART_R_LEN];          //定义GPS数据串口接收缓冲区

uchar  *inlast_t = trdata;             //最后放进发送缓冲区的
uchar  *outlast_t = trdata;            //最后从发送缓冲区出去的
uchar  *inlast_r = gpsdata;            //最后进入接收缓冲区的
uchar  *outlast_r = gpsdata;           //最后从接收缓冲区取走的
bit  t_empty,t_full,r_empty,r_full;  //缓冲区的状态标志位
bit  new_time,t_finish;              //接收完标志和发送完标志

void serail(void) interrupt 4
{
    if(TI)                           //如果发送中断置位
 {
     TI = 0;
  if(!t_empty)                 //如果发送缓冲区数据没有发完
  {
  
      SBUF = *outlast_t;          //最后从发送缓冲区出去的字符送SBUF
   outlast_t++;           //最后发送字符指针地址增1
   t_full = 0;            //发送区状态为未满
   if(outlast_t >= (trdata + UART_T_LEN)) //如果最后发送字符的地址超出
     outlast_t = trdata;           //地址到顶部回到底部
   if(outlast_t == inlast_t)  //如果最后发送字符的地址为最后进入发送的字符地址
     t_empty = 1;
  }
  else t_finish = 1;
 } 

 if(RI)                      //如果接收中断置位
 {
  RI = 0;
  if(~r_full)             //如果接收缓冲区未满
  {
   *inlast_r = SBUF; //最后进入接收缓冲区的字符送SBUF
   inlast_r++;   //最后进入接收缓冲区的字符地址增1
   r_empty = 0;  //接收缓冲区为非空
   if(inlast_r >= (gpsdata + UART_R_LEN))   //如果最后接收字符的地址超出
     inlast_r = gpsdata;            //地址到顶部回到底部
   if(inlast_r == outlast_r)    
//如果最后接收字符的地址等于最后从接收区取走的字符地址
     r_full = 1;       //则接收区满
  }
 } 
}

void loadmsg(uchar *msg, int num)         //把字符串放入发送缓冲区准备发送
{
 int i;

 for(i=0; i< num; i++) 
 {
  *inlast_t = *msg;       //字符装入最后进入发送发送缓冲区的内容
  msg++;          //字符串和缓冲地址同时增1
  inlast_t++;
  t_empty = 0;        //未发送完
  if(inlast_t >= (trdata+UART_T_LEN))
    inlast_t = trdata;         //地址到顶部回到底部
  if(inlast_t == outlast_t)
    t_full = 1;           //发送缓冲区满
  
 }

 if(t_finish)
 {
  TI = 1;
  t_finish = 0;
 }

}


uchar getbyte_r(void)         //从接收缓冲区取一个字节
{
 uchar c;
 while(r_empty);           //当接收缓冲区等待接收
 ES = 0;       //禁止串行中断
 c = *outlast_r;     //最后从接收缓冲区取走的数据赋值给C
 r_full = 0;      //接收未满
 outlast_r++;     //最后由接收缓冲区取走的数据地址增1
 if(outlast_r >= (gpsdata + UART_R_LEN))   //如果地址超出
   outlast_r = gpsdata;     //地址回原处
 if(outlast_r == inlast_r)    
//如果最后接收字符的地址等于最后从接收区取走的字符地址
   r_empty = 1;      //接收缓冲区为空
 ES = 1;        //恢复串行中断
 return c;
}

uchar r_state = 0;
uchar r_byte = 0;
uchar gps_chksum= 0;

void r_string(void)     // 接收字符串
{
 uint    *ptr;
  
 uchar temp;
 uchar tp[7];   
 //定义时标接收区,所存储的时标数据为接收缓冲区未作转换的时标,用来作全局时标的中转存储

 while(!r_empty && !new_time)   //若接收缓冲区非空,且接收未完成
 {
  temp = getbyte_r();     //每次while循环依次取入一个字节的接收数据
  switch(r_state)      
//如果依次取入的数据符合表头“@@Hb”,r_state位置4,进入取时标及GPS状态字节
  {
   case 0:
    if(temp == 0x40)   //@
      r_state = 1;
    break;
   case 1:
    if(temp == 0x40)        //@  
    {
     r_state = 2;
     gps_chksum = 0;
    }
    else r_state = 0;
       break;
   case 2:
    if(temp == 0x48)  //H
    {
                    r_state = 3;
     gps_chksum = gps_chksum^temp;
    }
    else r_state = 0;
    break;
   case 3:
    if(temp == 0x62)  //b
    {
                    r_state = 4;
     r_byte = 0;
     gps_chksum = gps_chksum^temp;
    }
    else r_state = 0;
    break;
   case 4:
    if(r_byte == 47)
      { if(gps_chksum == temp)   
//在完成有用数据采集后,经过数据转换,将标准字符存入全局时标缓冲中
          {
        ptr = (uint*)(tp+2);    
                    //经转换数据送时标缓冲区 
              gps_dt[0] = (*ptr)%100;             //年
                 gps_dt[1] = tp[0];        //月
                 gps_dt[2] = tp[1];           //日
                 gps_dt[3] = tp[4];           //时
                 gps_dt[4] = tp[5];           //分
                 gps_dt[5] = tp[6];           //秒
  
        new_time = 1;  
        } 
     r_state = 0;          //用于判断的数据归零,以便下一次取数据
      }
    else
      {
     gps_chksum = gps_chksum^temp;

     if(r_byte <7)
          tp[r_byte] = temp;
     else if(r_byte == 38)
      gps_state = temp;

        r_byte++;
      } 
    break;
      default:
       break;
  }

 }
}
 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
ADI 高精度低功耗精密放大器