熱門: 51單片機(jī) | 24小時(shí)必答區(qū) | 單片機(jī)教程 | 單片機(jī)DIY制作 | STM32 | Cortex M3 | 模數(shù)電子 | 電子DIY制作 | 音響/功放 | 拆機(jī)樂園 | Arduino | 嵌入式OS | 程序設(shè)計(jì)
![]() |
發(fā)布時(shí)間: 2024-9-14 18:28
正文摘要:PC發(fā)送hex 5A A5 03 01 02 03;解析出03(數(shù)據(jù)包的長(zhǎng)度),第一次解析正常,03改變后解析還是03, 哪位幫忙分析一下代碼出錯(cuò) void main(){ UartInit(); ... |
samxon 發(fā)表于 2024-9-18 17:16 感覺協(xié)議制定得不太合理,putCmd()應(yīng)該能解決你的第3個(gè)難點(diǎn)。
putCmd()使用示范
簡(jiǎn)化你之前的Uart_send_data()
|
samxon 發(fā)表于 2024-9-18 17:16 一個(gè)一個(gè)來(lái)搞,請(qǐng)各位幫忙把關(guān)代碼。如有更好優(yōu)化,請(qǐng)賜教。 添加數(shù)據(jù)包長(zhǎng)度代碼 void Join_Test_Parameter(unsigned char cmd,unsigned short var_add,unsigned short jdata){ unsigned char temp_buf[15],par_buf[16],i,par_buf_size,cnt=0; temp_buf[cnt++]= (Pack_Head&0xFF00)>>8; //0 temp_buf[cnt++]= Pack_Head&0xFF; //1 temp_buf[cnt++]= cmd; //2 temp_buf[cnt++]=(var_add&0xFF00)>>8; //3 temp_buf[cnt++]=var_add&0xFF; //4 temp_buf[cnt++]=(jdata&0xFF00)>>8; //5 temp_buf[cnt++]=jdata&0xFF; //6 for(i=0;i<10;i++){ if(i<2){ par_buf=temp_buf; }else if(i==2){ par_buf=cnt-3; //將長(zhǎng)度直接添加到數(shù)組下標(biāo)2的位置。 }else{ par_buf=temp_buf[i-1]; } } Send_Test_Parameter(par_buf,cnt+1); } |
謝謝你熱情給力的解析,還把代碼增加了注釋。非常感謝。希望占用您寶貴時(shí)間幫我看看下面的代碼。給點(diǎn)思路和辦法我。謝謝。 遇到的難點(diǎn): 1) 如何把len這個(gè)長(zhǎng)度字段插入到數(shù)據(jù)包的第3個(gè)字節(jié)。 2)由于有效數(shù)據(jù)部分是不確定的?赡苡袝r(shí)是3個(gè)字節(jié),也有可能是四個(gè)字節(jié)。如何把這些直接傳遞給Join_Test_Parameter函數(shù)來(lái)正確的產(chǎn)生一個(gè)數(shù)據(jù)包。 3)也許可用一個(gè)數(shù)組把想要的參數(shù)一次全部打包丟給Join_Test_Parameter這個(gè)函數(shù)處理吧?墒俏也恢涝趺磳(shí)現(xiàn)。 謝謝大家,特別是謝謝這個(gè)ydatou友情幫忙 void Join_Test_Parameter(unsigned char len,unsigned char cmd,unsigned short var_add,unsigned short jdata){ unsigned char par_buf[15],cnt=0; par_buf[cnt++]= (Pack_Head&0xFF00)>>8; par_buf[cnt++]= Pack_Head&0xFF; par_buf[cnt++]=len; par_buf[cnt++]= cmd; par_buf[cnt++]=(var_add&0xFF00)>>8; par_buf[cnt++]=var_add&0xFF; par_buf[cnt++]=(jdata&0xFF00)>>8; par_buf[cnt++]=jdata&0xFF; Send_Test_Parameter(par_buf,cnt); } void Get_Test_Gear(){ if(REC_COMPLETED){ REC_COMPLETED=0; if(USART_RX_BUF[1]==0x31){ switch(USART_RX_BUF[2]){ case 0x00: TEST_GEAR=0; Join_Test_Parameter(0x05,WriteCmd,0x1200,0x61B); //寫入電壓 Join_Test_Parameter(0x05,WriteCmd,0x1250,0x145); //寫入電流 Join_Test_Parameter(0x05,WriteCmd,0x1300,0x1fb); //寫入功率 Join_Test_Parameter(0x07,WriteCmd,0x1350,0x34 0x35 0x57 0x00); //寫入測(cè)試標(biāo)識(shí) Join_Test_Parameter(0x08,WriteCmd,0x1400,0x50 0x41 0x53 0x53 0x00); //寫入測(cè)試結(jié)果(pass或fail) Join_Test_Parameter(0x05,WriteCmd,0x1653,0x0400); //改變字體顏色 Join_Test_Parameter(0x05,WriteCmd,0x1500,0x1455); //寫入最大值 Join_Test_Parameter(0x05,WriteCmd,0x1200,0x13F1); //寫入平均值 Join_Test_Parameter(0x05,WriteCmd,0x1200,0x1389); //寫入最小值 break; case 0x10: TEST_GEAR=1; ........ } } } |
|
samxon 發(fā)表于 2024-9-17 08:18 這段代碼不能在51下工作。 51的ram最多只有256字節(jié),單Buf[300]都不夠。 51的臨時(shí)變量不是分配在堆棧上,函數(shù)一般不支持再入。一個(gè)函數(shù)假如在某個(gè)中斷中有調(diào)用,那么它就不適合在其它中斷中和非中斷中調(diào)用。 用指針傳遞更靈活方便,但占用ram資源多些。用全局變量傳遞,占用ram資源少,使用限制多。 |
感謝壇子高工,問題已經(jīng)解決,增加else條件。 void Uart() interrupt 4 { static unsigned char ccnt,bufccnt,recd_temp[5]; if(RI && REC_COMPLETED==0){ RI=0; if(ccnt<3){ recd_temp[ccnt++]=SBUF; }else{ if(recd_temp[0]==0x5A && recd_temp[1]==0xA5){ DATA_LENGTH=recd_temp[2]; USART_RX_BUF[bufccnt++]=SBUF; if(bufccnt==DATA_LENGTH){ //5A A5 02 03 04 0>03,1;1>04,2 REC_COMPLETED=1; bufccnt=0; ccnt=0; ES=0; } }else{ ccnt=0; } } } if(TI){} } void Uart_send_data(){ static unsigned char m; if(REC_COMPLETED){ for(m=0;m<DATA_LENGTH;m++){ SBUF=USART_RX_BUF[m]; while(!TI); TI=0; } DATA_LENGTH=0; REC_COMPLETED=0; m=0; ES=1; } } |
ydatou 發(fā)表于 2024-9-16 15:35 能不等講一下,我看到很多都是用指針傳送接收數(shù)組uartx_Rx_buf的值。直接傳遞和用指針傳區(qū)別在哪里。直接傳程序看起來(lái)不是更好清晰嗎。謝謝解答。 void Encode_Receive(uint8_t bytedata) { static uint8_t step=0;//狀態(tài)變量初始化為0 在函數(shù)中必須為靜態(tài)變量 static uint8_t cnt=0,Buf[300],len,cmd,*data_ptr; static uint16_t crc16; //進(jìn)行數(shù)據(jù)解析 狀態(tài)機(jī) switch(step) { case 0://接收幀頭1狀態(tài) if(bytedata== 0xAF) { step++; cnt = 0; Buf[cnt++] = bytedata; }break; case 1://接收幀頭2狀態(tài) if(bytedata== 0xFA) { step++; Buf[cnt++] = bytedata; } else if(bytedata== 0XAF) { step = 1; } else { step = 0; } break; case 2://接收數(shù)據(jù)長(zhǎng)度字節(jié)狀態(tài) step++; Buf[cnt++] = bytedata; len = bytedata; break; case 3://接收命令字節(jié)狀態(tài) step++; Buf[cnt++] = bytedata; cmd = bytedata; data_ptr = &Buf[cnt];//記錄數(shù)據(jù)指針首地址 if(len == 0)step++;//數(shù)據(jù)字節(jié)長(zhǎng)度為0則跳過(guò)數(shù)據(jù)接收狀態(tài) break; case 4://接收l(shuí)en字節(jié)數(shù)據(jù)狀態(tài) Buf[cnt++] = bytedata; if(data_ptr + len == &Buf[cnt])//利用指針地址偏移判斷是否接收完len位數(shù)據(jù) { step++; } break; case 5://接收crc16校驗(yàn)高8位字節(jié) step++; crc16 = bytedata; break; case 6://接收crc16校驗(yàn)低8位字節(jié) crc16 <<= 8; crc16 += bytedata; if(crc16 == CRC16_Check(Buf,cnt))//校驗(yàn)正確進(jìn)入下一狀態(tài) { step ++; } else if(bytedata == 0xAF) { step = 1; } else { step = 0; } break; case 7://接收幀尾 if(bytedata== 0xFF)//幀尾接收正確 { Encode_Handle(cmd,data_ptr,len);//數(shù)據(jù)解析 step = 0; } else if(bytedata == 0xAF) { step = 1; } else { step = 0; } break; default:step=0;break;//多余狀態(tài),正常情況下不可能出現(xiàn) } } |
ydatou 發(fā)表于 2024-9-16 15:35 非常感謝,這個(gè)是狀態(tài)機(jī)的思想寫的代碼。當(dāng)然最好。值得擁有。 |
samxon 發(fā)表于 2024-9-16 09:31 這段代碼還有問題。 1.串口是可以同時(shí)收發(fā)的。 if(RI && REC_COMPLETED==0)會(huì)使發(fā)送期間數(shù)據(jù)接收出錯(cuò)。 2.錯(cuò)誤檢查有漏洞。數(shù)據(jù)長(zhǎng)度要做范圍檢查。 3.浪費(fèi)了太多全局變量,51的ram資源又比較少。 請(qǐng)參考我的代碼。
|
感謝壇子高工,問題已經(jīng)解決,增加else條件。 void Uart() interrupt 4 { static unsigned char ccnt,bufccnt,recd_temp[5]; if(RI && REC_COMPLETED==0){ RI=0; if(ccnt<3){ recd_temp[ccnt++]=SBUF; }else{ if(recd_temp[0]==0x5A && recd_temp[1]==0xA5){ DATA_LENGTH=recd_temp[2]; USART_RX_BUF[bufccnt++]=SBUF; if(bufccnt==DATA_LENGTH){ //5A A5 02 03 04 0>03,1;1>04,2 REC_COMPLETED=1; bufccnt=0; ccnt=0; ES=0; } }else{ ccnt=0; } } } if(TI){} } void Uart_send_data(){ static unsigned char m; if(REC_COMPLETED){ for(m=0;m<DATA_LENGTH;m++){ SBUF=USART_RX_BUF[m]; while(!TI); TI=0; } DATA_LENGTH=0; REC_COMPLETED=0; m=0; ES=1; } } |
發(fā)表于 2024-9-15 09:51 修正,情況依舊,可能還是數(shù)組上面的問題。但沒有排查的思路 |
if(bufccnt=DATA_LENGTH)這句是不是應(yīng)該用兩個(gè)等于號(hào)== |
Powered by 單片機(jī)教程網(wǎng)