單片機串口發(fā)送接收程序,下面是關(guān)于GPS_CHECKTIAMER,局部應用程序#define UART_R_LEN 60#define UART_T_LEN 34uchar idata trdata[UART_T_LEN]; //定義串口發(fā)送緩沖區uchar idata gpsdata[UART_R_LEN]; //定義GPS數據串口接收緩沖區uchar *inlast_t = trdata; //最后放進(jìn)發(fā)送緩沖區的uchar *outlast_t = trdata; //最后從發(fā)送緩沖區出去的uchar *inlast_r = gpsdata; //最后進(jìn)入接收緩沖區的uchar *outlast_r = gpsdata; //最后從接收緩沖區取走的bit t_empty,t_full,r_empty,r_full; //緩沖區的狀態(tài)標志位bit new_time,t_finish; //接收完標志和發(fā)送完標志void serail(void) interrupt 4{if(TI) //如果發(fā)送中斷置位{TI = 0;if(!t_empty) //如果發(fā)送緩沖區數據沒(méi)有發(fā)完{SBUF = *outlast_t; //最后從發(fā)送緩沖區出去的字符送SBUFoutlast_t++; //最后發(fā)送字符指針地址增1t_full = 0; //發(fā)送區狀態(tài)為未滿(mǎn)if(outlast_t >= (trdata + UART_T_LEN)) //如果最后發(fā)送字符的地址超出outlast_t = trdata; //地址到頂部回到底部if(outlast_t == inlast_t) //如果最后發(fā)送字符的地址為最后進(jìn)入發(fā)送的字符地址t_empty = 1;}else t_finish = 1;} if(RI) //如果接收中斷置位{RI = 0;if(~r_full) //如果接收緩沖區未滿(mǎn){*inlast_r = SBUF; //最后進(jìn)入接收緩沖區的字符送SBUFinlast_r++; //最后進(jìn)入接收緩沖區的字符地址增1r_empty = 0; //接收緩沖區為非空if(inlast_r >= (gpsdata + UART_R_LEN)) //如果最后接收字符的地址超出inlast_r = gpsdata; //地址到頂部回到底部if(inlast_r == outlast_r)
//如果最后接收字符的地址等于最后從接收區取走的字符地址r_full = 1; //則接收區滿(mǎn)}} }void loadmsg(uchar *msg, int num) //把字符串放入發(fā)送緩沖區準備發(fā)送{int i;for(i=0; i num; i++) {*inlast_t = *msg; //字符裝入最后進(jìn)入發(fā)送發(fā)送緩沖區的內容msg++; //字符串和緩沖地址同時(shí)增1inlast_t++;t_empty = 0; //未發(fā)送完if(inlast_t >= (trdata+UART_T_LEN))inlast_t = trdata; //地址到頂部回到底部if(inlast_t == outlast_t)t_full = 1; //發(fā)送緩沖區滿(mǎn)}if(t_finish){TI = 1;t_finish = 0;}}uchar getbyte_r(void) //從接收緩沖區取一個(gè)字節{uchar c;while(r_empty); //當接收緩沖區等待接收ES = 0; //禁止串行中斷c = *outlast_r; //最后從接收緩沖區取走的數據賦值給Cr_full = 0; //接收未滿(mǎn)outlast_r++; //最后由接收緩沖區取走的數據地址增1if(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];
//定義時(shí)標接收區,所存儲的時(shí)標數據為接收緩沖區未作轉換的時(shí)標,用來(lái)作全局時(shí)標的中轉存儲while(!r_empty !new_time) //若接收緩沖區非空,且接收未完成{temp = getbyte_r(); //每次while循環(huán)依次取入一個(gè)字節的接收數據switch(r_state)
//如果依次取入的數據符合表頭“@@Hb”,r_state位置4,進(jìn)入取時(shí)標及GPS狀態(tài)字節{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)
//在完成有用數據采集后,經(jīng)過(guò)數據轉換,將標準字符存入全局時(shí)標緩沖中{ptr = (uint*)(tp+2); //經(jīng)轉換數據送時(shí)標緩沖區 gps_dt[0] = (*ptr)%100; //年gps_dt[1] = tp[0]; //月gps_dt[2] = tp[1]; //日gps_dt[3] = tp[4]; //時(shí)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;}}}
評論