請(qǐng)教一下CH573串口接收數(shù)據(jù)包不完整問(wèn)題

使用的CH573串口1接收數(shù)據(jù),每接收一字節(jié)數(shù)據(jù)要調(diào)用void uart_receive_input(unsigned char value)函數(shù)將輸入放入緩存區(qū)處理,字節(jié)數(shù)少的話處理起來(lái)沒(méi)問(wèn)題,但是如果接收的是一個(gè)256字節(jié)的數(shù)據(jù)包,接受的數(shù)據(jù)好像不完整,校驗(yàn)會(huì)不通過(guò),請(qǐng)問(wèn)要接收256字節(jié)的數(shù)據(jù)包,甚至512字節(jié),每個(gè)字節(jié)還要調(diào)用函數(shù)放入緩存區(qū),串口終端應(yīng)該怎樣寫(xiě)才能接收完整。

第一個(gè)函數(shù)是單字節(jié)暫存,第二個(gè)函數(shù)是多字節(jié)暫存,附上我的串口中斷函數(shù),請(qǐng)指出不足,謝謝。

void?uart_receive_input(unsigned?char?value)//單字節(jié)暫存
{
????
????if(1?==?rx_buf_out?-?rx_buf_in)?{
????????//串口接收緩存已滿
????}else?if((rx_buf_in?>?rx_buf_out)?&&?((rx_buf_in?-?rx_buf_out)?>=?sizeof(wifi_uart_rx_buf)))?{
????????//串口接收緩存已滿
????}else?{
????????//串口接收緩存未滿
????????if(rx_buf_in?>=?(unsigned?char?*)(wifi_uart_rx_buf?+?sizeof(wifi_uart_rx_buf)))?{
????????????rx_buf_in?=?(unsigned?char?*)(wifi_uart_rx_buf);
????????}
????????
????????*rx_buf_in?++?=?value;
????}
}
void?uart_receive_buff_input(unsigned?char?value[],?unsigned?short?data_len)//多字節(jié)暫存
{
????
????unsigned?short?i?=?0;
????for(i?=?0;?i?<?data_len;?i++)?{
????????uart_receive_input(value[i]);
????}
}
__attribute__((interrupt("WCH-Interrupt-fast")))
__attribute__((section(".highcode")))
void?UART1_IRQHandler(?void?)????????//?UART1?中斷
{
????UINT8V?i?=?0;

????UINT8V?Recv;

????switch?(?UART1_GetITFlag()?)
????{
????????case?UART_II_LINE_STAT?:????????//?線路狀態(tài)錯(cuò)誤
????????{
????????????UART1_GetLinSTA();
????????????break;
????????}

????????case?UART_II_RECV_RDY?:??????????//?數(shù)據(jù)達(dá)到設(shè)置觸發(fā)點(diǎn)
????????????for?(?i?=?0?;?i?!=?trigB_UART_Wifi;?i++?)
????????????{
????????????????Recv?=?R8_UART1_RBR;
????????????????uart_receive_input(Recv);
????????????}
????????break;

????????case?UART_II_RECV_TOUT?:?????????//?接收超時(shí),暫時(shí)一幀數(shù)據(jù)接收完成
????????????i?=?UART1_RecvString(?Wifi_RxBuff?);
????????????uart_receive_buff_input(Wifi_RxBuff,i);
????????????memset(Wifi_RxBuff,0,i);
????????break;

????????case?UART_II_THR_EMPTY?:?????????//?發(fā)送緩存區(qū)空,可繼續(xù)發(fā)送
????????break;

????????case?UART_II_MODEM_CHG?:?????????//?只支持串口0
????????break;

????????default?:
????????break;
????}
}


先按如下優(yōu)化:

  1. 可以降低波特率試試;

  2. 將uart_receive_input和uart_receive_buff_input函數(shù)上方加上__attribute__((section(".highcode")))

  3. 不要在中斷內(nèi)使用memset,中斷程序是在ram中運(yùn)行的,速度要求快,可以手寫(xiě)for循環(huán)代替。

  4. 外部讀取fifo的時(shí)候最好關(guān)閉中斷

  5. UART1_GetLinSTA要賦值給一個(gè)臨時(shí)變量才算一句代碼。


您好,請(qǐng)問(wèn)外部讀取FIFO時(shí)關(guān)閉中斷是什么意思。


防止fifo的參數(shù)變量在參與程序運(yùn)算時(shí)被中斷打斷,然后中斷中對(duì)fifo變量進(jìn)行操作更改,會(huì)導(dǎo)致丟數(shù)據(jù)等情形。


這個(gè)要怎么操作呢


PFIC_EnableIRQ( UART1_IRQn );????????//打開(kāi)串口1中斷

PFIC_DisableIRQ( UART1_IRQn );???????//關(guān)閉串口1中斷

你需要先一步步試,排除問(wèn)題。


請(qǐng)問(wèn)是要在進(jìn)入串口1中斷時(shí)關(guān)閉中斷,在要退出中斷時(shí)使能中斷嗎


不是在中斷程序中,是在外部主程序中,從buffer里取數(shù)據(jù)時(shí)關(guān)閉中斷,取完數(shù)據(jù)打開(kāi)中斷。


謝謝您的解答,但是我修改了您指出的不足之后,問(wèn)題仍沒(méi)有解決,還有一個(gè)問(wèn)題,就是有時(shí)我在向串口發(fā)送大數(shù)據(jù)包時(shí),系統(tǒng)會(huì)重新啟動(dòng),這又是什么原因造成的呢。


你把工程發(fā)過(guò)來(lái)吧,發(fā)到郵箱:mx@wch.cn。


我這邊給個(gè)建議,確認(rèn)串口有沒(méi)有接收錯(cuò)誤,并且不影響當(dāng)前的代碼的話,,很簡(jiǎn)單:? ?只需要再初始化一路串口,然后讓速率略大于當(dāng)前串口的速率, 然后把當(dāng)前的串口接收的數(shù)據(jù)實(shí)時(shí)發(fā)送出去即可.

另外還有一個(gè)要注意的是: ch57x ch58x 系列的芯片 串口時(shí)鐘來(lái)源于系統(tǒng)時(shí)鐘,在波特率比較高的情況下, 部分波特率可能有一定的誤差.



串口中斷為什么用for循環(huán)呀。


串口中斷接受代碼寫(xiě)的問(wèn)題


只是為了避免中斷程序處理時(shí)間占用過(guò)長(zhǎng),memset是flash中的程序,運(yùn)行沒(méi)有ram中的程序快。而且樓上的問(wèn)題最后并不是串口處理,是其他方面錯(cuò)誤導(dǎo)致的。


解決了嗎,請(qǐng)問(wèn)


請(qǐng)教大神,可以添加我的qq嗎,942344644,謝謝


只有登錄才能回復(fù),可以選擇微信賬號(hào)登錄

国产91精品新入口,国产成人综合网在线播放,九热这里只有精品,本道在线观看,美女视频a美女视频,韩国美女激情视频,日本美女pvp视频