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