日韩精品在线免费播放-午夜激情网址-日韩黄色一区-91网站免费在线观看-www黄色com-福利网站在线观看-欧美一区二区三区大片-久久久久久久久久久久久久国产-成人理论片-2020亚洲天堂-黄色成人91-毛片视频免费观看-一区二区黄色片-91亚洲精品在线-国产免费看av-黄色一级淫片-国产一级理论片

購(gòu)物車0種商品
IC郵購(gòu)網(wǎng)-IC電子元件采購(gòu)商城
基于51串口通訊編程軟件架構(gòu)剖析
(2011/10/31 9:57:00)
前言:
串口通訊對(duì)于所有的嵌入式工程師十分常見(jiàn),對(duì)于一個(gè)與外界交互的系統(tǒng)必須依賴一些手段,比如串口、USB、紅外、GPRS之類的數(shù)據(jù)通訊傳輸方式。而串口作為一種廉價(jià)的短距離可靠的通訊方式得到了廣泛應(yīng)用。
廢話少說(shuō)了,就此打住,進(jìn)入正題。
本文主要從軟件結(jié)構(gòu)上講解如何在資源比較缺乏的系統(tǒng)上實(shí)現(xiàn)通訊協(xié)議的串口通訊編程,以及如何優(yōu)化程序效率,從而使系統(tǒng)更快、更穩(wěn)定運(yùn)行。

正文:
我們以51單片機(jī)為例。51中一般針對(duì)串口通訊編程,通常采取中斷接受查詢發(fā)送的方式。中斷函數(shù)在接受數(shù)據(jù)到達(dá)時(shí)被重復(fù)調(diào)用,其實(shí)是個(gè)重復(fù)入棧的過(guò)程,所以不宜將函數(shù)寫的太長(zhǎng),函數(shù)太長(zhǎng)一般會(huì)導(dǎo)致棧太深占用系統(tǒng)資源,二是處理時(shí)間過(guò)長(zhǎng),可能導(dǎo)致通訊出錯(cuò)。為了防止在處理數(shù)據(jù)過(guò)程中不受干擾,通常在處理接受數(shù)據(jù)前關(guān)閉中斷,處理完后再開(kāi)。
通常的的編程方式如下:
staticvoidUartInterruptService(void)interrupt4
{
ES=0;
RI=0;
uart_process(SBUF);
ES=1;
}
下面重點(diǎn)介紹數(shù)據(jù)處理函數(shù)uart_process(SBUF);
其實(shí)很多時(shí)候,對(duì)于通訊傳輸?shù)臄?shù)據(jù)處理才是關(guān)鍵,尤其對(duì)于設(shè)計(jì)通訊協(xié)議而言。筆者在剛剛做的一個(gè)系統(tǒng)上就碰到這樣的問(wèn)題,當(dāng)系統(tǒng)龐大了,資源十分有限的情況下,數(shù)據(jù)處理一旦占用資源太多,效率太低將導(dǎo)致系統(tǒng)崩潰而無(wú)法運(yùn)行。
到了這里,很多工程師可能會(huì)考慮開(kāi)個(gè)大的緩沖區(qū)FIFO將接收到的數(shù)據(jù)保存在緩沖區(qū),然后對(duì)其進(jìn)行解析、判斷進(jìn)行下一步程序編寫,當(dāng)然這在系統(tǒng)資源比較豐富的情況下是沒(méi)有問(wèn)題的,ARM上采取的就是這樣的方式。但如何系統(tǒng)龐大呢,留給的資源缺乏則不行。這樣做的一個(gè)很大缺點(diǎn)必須是將數(shù)據(jù)幀接收完了才能夠判斷,降低了效率和運(yùn)行速度。
其實(shí)還有另外的方式,可以采取在每接收一個(gè)字節(jié)就對(duì)其解析,解析完判斷轉(zhuǎn)到下一個(gè)狀態(tài),并將其中的有用數(shù)據(jù)存儲(chǔ)在相應(yīng)的數(shù)據(jù)結(jié)構(gòu)中去,可以采取狀態(tài)機(jī)實(shí)現(xiàn)。

將狀態(tài)機(jī)設(shè)計(jì)為兩個(gè)控制狀態(tài),一是串口狀態(tài)——uart_state,一是命令類型狀態(tài)——cmd_state.
(1)狀態(tài)機(jī)開(kāi)始狀態(tài):串口狀態(tài)為CMD_NO
(2)接受到STX_CMD,狀態(tài)變?yōu)镃MD_START.
(3)接下來(lái)將自動(dòng)進(jìn)入接受命令幀的狀態(tài),再開(kāi)啟命令狀態(tài)的狀態(tài)機(jī),對(duì)發(fā)送來(lái)的有用數(shù)據(jù)進(jìn)行解析,保存,校驗(yàn)等。處理完畢后將uart_state設(shè)為CMD_END狀態(tài)進(jìn)行下一步的接受完畢判斷,將cmd_state設(shè)置為初始的NO_CMD狀態(tài)。
(4)最后進(jìn)行ETX_CMD判斷,判斷數(shù)據(jù)接收是否完畢。


voiduart_process(U8u8)
{
if(uart_state==CMD_NO)
{
if(u8==STX_CMD)
{
uart_state=CMD_START;
}

}
elseif(uart_state==CMD_START)
{
switch(cmd_state)
{
caseNO_CMD:
cmd_state=u8;
break;

caseCOST_CMD:
//解析存儲(chǔ)有用數(shù)據(jù)到相應(yīng)數(shù)據(jù)結(jié)構(gòu)中
//進(jìn)行CRC校驗(yàn)
……
uart_state=CMD_END;
cmd_state=NO_CMD;
CRC=0;
break;
……
}
……
}
elseif(uart_state==CMD_END)
{
uart_state=CMD_NO;
if(u8==ETX_CMD)
{
//接受完畢
//可以考慮拋出一個(gè)消息main函數(shù)循環(huán)中進(jìn)行響應(yīng)處理。
}

}
}


接下來(lái)我們要討論解析后我們數(shù)據(jù)存儲(chǔ)的問(wèn)題,其實(shí)在資源比較足夠的情況下或者能夠擠出data區(qū)的情況下可以考慮用結(jié)構(gòu)體,我們構(gòu)造好相應(yīng)結(jié)構(gòu)體,將接收到的數(shù)據(jù)存儲(chǔ)進(jìn)去,要應(yīng)用的時(shí)候就十分方便。但這也有個(gè)矛盾,一般c51定義的結(jié)構(gòu)體都被存儲(chǔ)在data區(qū),一般通訊的字節(jié)量大空間必然不夠,存在一個(gè)矛盾,可以采用聯(lián)合體union進(jìn)行存儲(chǔ)效果會(huì)好一點(diǎn)。當(dāng)然也可以在保存數(shù)據(jù)時(shí)采用定義在xdata區(qū)(片外)的buffer來(lái)存儲(chǔ)。這樣在一定程序上優(yōu)化了程序的執(zhí)行效率,在程序處理立即拋出消息處理,提高了通訊數(shù)據(jù)的處理速度。對(duì)于通常資源比較豐富的系統(tǒng),比如ARM上一般采取的做法是這樣的,將數(shù)據(jù)存在緩沖區(qū),接收完一幀數(shù)據(jù)后再轉(zhuǎn)換成相應(yīng)的數(shù)據(jù)結(jié)構(gòu),再進(jìn)行分析、校驗(yàn)。

總體來(lái)說(shuō),這種采取狀態(tài)機(jī)實(shí)時(shí)解析串口通訊數(shù)據(jù)的方式在一定程序提高了程序運(yùn)行效率,使軟件架構(gòu)清晰明了,程序可擴(kuò)展性大,有利于后續(xù)開(kāi)發(fā)。以上是筆者的一點(diǎn)愚見(jiàn),歡迎指教。


網(wǎng)友評(píng)論:學(xué)習(xí)啦.

網(wǎng)友評(píng)論:在我發(fā)出STX_CMD命令時(shí),uart-state狀態(tài)機(jī)將進(jìn)入CMD_START狀態(tài),等待下一個(gè)命令的輸入,而此時(shí)命令狀態(tài)機(jī)cmd_state是NO_CMD狀態(tài),好了,現(xiàn)在外面發(fā)過(guò)來(lái)一個(gè)COST_CMD的命令,由于此時(shí)cmd_state正處在NO_CMD的狀態(tài),將執(zhí)行caseNO_CMD的語(yǔ)句,也就是將cmd_state的狀態(tài)進(jìn)入COST_CMD,然后退出switch語(yǔ)句,這樣就相當(dāng)于沒(méi)有去執(zhí)行caseCOST_CMD狀態(tài)的指令,這個(gè)命令就無(wú)效了,不知道我說(shuō)清楚沒(méi)有

網(wǎng)友評(píng)論:這種只能適合一些情況,不能適合所有~~內(nèi)存小就換個(gè)大點(diǎn)的嘛,現(xiàn)在的單片機(jī)差型號(hào)那么多,肯定能找到合適的.

網(wǎng)友評(píng)論:你沒(méi)有想清楚,我可以將cmd_state默認(rèn)設(shè)置為NO_CMD,來(lái)個(gè)COST_CMD也就是cmd_state=u8,此時(shí)cmd_state=COST_CMD,接下來(lái)對(duì)命令幀有用數(shù)據(jù)進(jìn)行解析.仔細(xì)分析下就很清楚的.

30樓說(shuō)的很對(duì),不是適合所有的情況,但大多數(shù)情況下還是合適的,如果通信協(xié)議加上上層的GUI設(shè)計(jì)的,通訊數(shù)據(jù)傳輸速度將影響整個(gè)設(shè)備的響應(yīng)速度.因?yàn)椴粌H僅要傳輸數(shù)據(jù)還要解析,刷屏幕等,速度稍微快點(diǎn)響應(yīng)上將好多了.



網(wǎng)友評(píng)論:誰(shuí)需要直接可以工作的C51程序,可以來(lái)交流一下,QQ28591262

網(wǎng)友評(píng)論:我在使用modbusRTU模式時(shí)候遇到超時(shí)的問(wèn)題,也用的是狀態(tài)機(jī)站好功能碼啥的都接受好了到了接受數(shù)據(jù)那一步了然后假如突然對(duì)方不發(fā)了怎么辦啊,不就一直停在那個(gè)狀態(tài)了啊,另一個(gè)消息來(lái)了就沒(méi)法收了呵呵,雖然一般不會(huì)出現(xiàn)但是假如出現(xiàn)了喃然后就要用到modbus里面的間隔判斷了然后那個(gè)間隔時(shí)間太短就1.5個(gè)字符,這要怎么搞啊,用定時(shí)器是不是可以?有沒(méi)其他的方法喃!因?yàn)樵O(shè)備內(nèi)部要跟DSP通信,還要跟外部的設(shè)備通信所以就要用到兩個(gè)串口,如果兩個(gè)都用定時(shí)器的話,那怎么搞一會(huì)定時(shí)器還給他們兩用完了.

網(wǎng)友評(píng)論:可以仿下TCP/IP的超時(shí)處理機(jī)制.
協(xié)議每執(zhí)行到一個(gè)狀態(tài),進(jìn)行一次檢查.

網(wǎng)友評(píng)論:開(kāi)8個(gè)BYTE的緩沖足夠了~中斷函數(shù)只負(fù)責(zé)接收,在主程序循環(huán)中處理.

staticvoidUartInterruptService(void)interrupt4
{
ES=0;
RI=0;

cSerialReciveBuffer[cSerialWriteBufferPos]=cData;

if(cSerialWriteBufferPos>=UART0_RX_BUFFER_SIZE)
{
cSerialWriteBufferPos=0;
}
cSerialReciveNum++;

ES=1;
}

//主函數(shù)循環(huán)處理
while(cSerialReciveNum)
{
}


網(wǎng)友評(píng)論:你這種方式極其不好,程序效率低下,不能夠老在while(1)循環(huán)處理一些東西,降低了程序消息,采取消息機(jī)制會(huì)好多了,關(guān)于你所說(shuō)的緩沖處理我不做評(píng)價(jià).

網(wǎng)友評(píng)論:這個(gè)也是收到數(shù)據(jù)馬上處理,如果收到多個(gè)就處理多個(gè),設(shè)置緩沖就是為了提高效率啊~~數(shù)據(jù)不在中斷中處理是好事~

網(wǎng)友評(píng)論:while(1)一直被循環(huán)調(diào)用,一般處理是放在外面再通過(guò)消息機(jī)制發(fā)消息到while(1)里判斷處理,如果連串口數(shù)據(jù)處理也放在while(1)里程序?qū)懙暮荛L(zhǎng),我是比較反對(duì)這種將main弄的很長(zhǎng)的做法:)

網(wǎng)友評(píng)論:可以編寫一個(gè)串口處理的函數(shù),把串口數(shù)據(jù)處理放在一個(gè)函數(shù)里面,這樣你就會(huì)覺(jué)得舒服多了~呵呵~~
我一直認(rèn)為提高效率的方法是中斷函數(shù)盡量精簡(jiǎn)~~

網(wǎng)友評(píng)論:大家寫串口的時(shí)候都是怎么搞的,開(kāi)緩沖的多還是不開(kāi)的多,還是剛開(kāi)始不開(kāi),以后成為高手后就開(kāi)了.

網(wǎng)友評(píng)論:是不開(kāi)緩沖的少,我只是探討下一個(gè)特殊情況下的處理以及如何優(yōu)化程序.我不是什么高手.

網(wǎng)友評(píng)論:因?yàn)槟軌蚨嘧屑?xì)考慮一些東西,在平臺(tái)相互移植時(shí)候就會(huì)避免一些問(wèn)題:)

網(wǎng)友評(píng)論:你的狀態(tài)機(jī)是很高明的

網(wǎng)友評(píng)論:中間數(shù)據(jù)解析的時(shí)候就用了結(jié)構(gòu)體做緩沖存儲(chǔ)數(shù)據(jù).我見(jiàn)到有個(gè)網(wǎng)友在我的基礎(chǔ)上改了下?tīng)顟B(tài)機(jī)用于他的項(xiàng)目的一個(gè)文檔,他針對(duì)他的應(yīng)用自己設(shè)置了下?tīng)顟B(tài)的切換我覺(jué)得挺好的.我這個(gè)只是提供一個(gè)架構(gòu),具體應(yīng)用大家仔細(xì)修改下就可以了.另外我絕對(duì)對(duì)于資源比較缺乏的ARM芯片比如LPC的就可以采用我的方法.



網(wǎng)友評(píng)論:說(shuō)白了就是把數(shù)據(jù)處理放在中斷里運(yùn)行,這樣不利于程序移植和維護(hù),如果不是迫不得已不要這樣干。

網(wǎng)友評(píng)論:受教了

其實(shí)只要我們?cè)谔幚硎掷锏陌缸?多注意下,像樓主說(shuō)說(shuō)的狀態(tài)機(jī)之類的處理手
法已經(jīng)應(yīng)用很普遍了,在臺(tái)灣過(guò)來(lái)的程式中特普遍

關(guān)鍵融會(huì)貫通,自己也能熟練的用這種處理方式,這個(gè)是難點(diǎn)

網(wǎng)友評(píng)論:其實(shí)我對(duì)TCP/IP理解在串口通訊之前,因?yàn)槌霈F(xiàn)了一些問(wèn)題才去思考一些解決的方法。過(guò)陣子貼個(gè)TCP/IP協(xié)議中實(shí)現(xiàn)上層的HTTP協(xié)議中的狀態(tài)機(jī),里面對(duì)于狀態(tài)的校驗(yàn)和重發(fā)就做的很好。還是一句老話:“由儉入奢易,由奢入儉難”,很多一些從ARM上跑的好的程序到其他平臺(tái)出問(wèn)題都可能出這樣那樣的問(wèn)題,這樣一個(gè)好的架構(gòu)是很有必要的。當(dāng)然不是說(shuō)我這個(gè)東西有什么高明的地方,只是平時(shí)寫code的時(shí)候多想想一些問(wèn)題可能會(huì)有意想不到的收獲!

網(wǎng)友評(píng)論:這樣寫的話得保證發(fā)來(lái)的第二、第三、、、、等等數(shù)不別的器件當(dāng)成地址或別的啊

網(wǎng)友評(píng)論:我在這個(gè)壇子另外個(gè)帖子里面提到避免這點(diǎn),比如我將STX和ETX設(shè)為HEX,中間的數(shù)據(jù)幀為ASCII就不避免了……

網(wǎng)友評(píng)論:跟著大家學(xué)習(xí)一下^_^

網(wǎng)友評(píng)論:幫頂

網(wǎng)友評(píng)論:頂...以后有這樣的文章多發(fā)一下..呵呵

網(wǎng)友評(píng)論:狀態(tài)機(jī)的方式我也常用,應(yīng)該是比較好的方法,但是我反對(duì)把解析等操作放在中斷種進(jìn)行。36樓中斷中只接受數(shù)據(jù)放到FIFO中也許是不錯(cuò)的方法,樓下說(shuō)while(1)效率低,可能他沒(méi)有考慮到,確實(shí)不能這樣傻等,效率太低,可以改進(jìn)一下,采用輪詢,每隔1mS或其他時(shí)間查詢一下,同時(shí)可以計(jì)算超時(shí)。不過(guò)我建議將解析幀頭放到接收中斷中,用一個(gè)緩沖區(qū)來(lái)放數(shù)據(jù),中斷中幀頭同步之后設(shè)定標(biāo)志并依次接收存儲(chǔ)每一個(gè)數(shù)據(jù),中途有奇偶校驗(yàn)錯(cuò)誤或者緩沖區(qū)益處則等待超時(shí),主程序輪詢并設(shè)定超時(shí),超時(shí)后關(guān)中斷,開(kāi)始解析數(shù)據(jù)。把命令結(jié)構(gòu)體直接指向緩沖區(qū)即可取得所需的數(shù)據(jù)。
現(xiàn)在的這種常用的通信協(xié)議都是幀頭同步,幀尾超時(shí)來(lái)處理,所以我常用上面的方法。不過(guò)需要注意避免主程序和中斷競(jìng)爭(zhēng)數(shù)據(jù)。

網(wǎng)友評(píng)論:采用多機(jī)器通訊做同步最好了,無(wú)論小系統(tǒng),還是大系統(tǒng)都統(tǒng)統(tǒng)可以~
采用緩沖方式效率高啊,放在主函數(shù)中檢測(cè),經(jīng)過(guò)實(shí)際應(yīng)用,效果非常好,不是傻等啊.

網(wǎng)友評(píng)論:不懂將所有的活都放到串口中斷中去完成,會(huì)不會(huì)影響通訊質(zhì)量和占用系統(tǒng)資源阿請(qǐng)教

網(wǎng)友評(píng)論:
SIGNAL(SIG_USART_RECV)
{
unsignedcharUARTemp;
UARTemp=UDR0;
UARTTimer=0x2;
if(!(UARTStatu&_BV(HeadIn)))
{
if(UARTemp!=HeadChar)
return;
else
{
UARTStatu|=_BV(HeadIn);
return;
}
}
if(!(UARTStatu&_BV(LengtIn)))
{
DataLong=UARTemp;
if(DataLong>MAXLength)
{
UARTStatu=0;
return;
}
UARTbuffer[0]=UARTemp;
ByteOfRead=0;
UARTStatu|=_BV(LengtIn);
return;
}
if(ByteOfRead<DataLong)
{
UARTbuffer[ByteOfRead+1]=UARTemp;
if(ByteOfRead<MAXLength)
ByteOfRead++;
if(ByteOfRead==DataLong)
{
if(UARTemp==Crc8fun(UARTbuffer,DataLong))
UARTStatu|=_BV(PackageOk);
else
UARTStatu=0;
}
}
}


網(wǎng)友評(píng)論:在大量數(shù)據(jù)交換通訊應(yīng)用中,使用狀態(tài)機(jī)確實(shí)會(huì)拉低系統(tǒng)實(shí)時(shí)性,使用超時(shí)解析對(duì)于大量數(shù)據(jù)突發(fā)訪問(wèn)會(huì)帶來(lái)溢出風(fēng)險(xiǎn),視不同應(yīng)用采取不同處理方法,實(shí)時(shí)性要求很強(qiáng)的通訊我一般在協(xié)議上下功夫,定義一個(gè)結(jié)束符,一旦判斷到結(jié)束符在中斷中解析完并發(fā)送消息到隊(duì)列中,保證不丟失消息,但需要評(píng)估解析需要消耗的CPU運(yùn)行時(shí)間必須小于一個(gè)字節(jié)的接收時(shí)間。

網(wǎng)友評(píng)論:不錯(cuò),讀這樣的文章如飲甘露。

網(wǎng)友評(píng)論:“為了防止在處理數(shù)據(jù)過(guò)程中不受干擾,通常在處理接受數(shù)據(jù)前關(guān)閉中斷,處理完后再開(kāi)。
static void UartInterruptService(void) interrupt 4
{
ES = 0;
RI = 0;
uart_process(SBUF);
ES=1;
}”
--------51的串口中斷函數(shù)里就不用再關(guān)閉串口中斷允許了吧,因?yàn)樽约菏遣荒軗屨甲约旱摹?br>
“其實(shí)很多時(shí)候,對(duì)于通訊傳輸?shù)臄?shù)據(jù)處理才是關(guān)鍵,尤其對(duì)于設(shè)計(jì)通訊協(xié)議而言。筆者在剛剛做的一個(gè)系統(tǒng)上就碰到這樣的問(wèn)題,當(dāng)系統(tǒng)龐大了,資源十分有限的情況下,數(shù)據(jù)處理一旦占用資源太多,效率太低將導(dǎo)致系統(tǒng)崩潰而無(wú)法運(yùn)行!

---------這很有可能是沒(méi)有充足的堆?臻g造成的。一般至少得留下十幾個(gè)字節(jié)的RAM做堆棧。

網(wǎng)友評(píng)論:不錯(cuò),值得一看

網(wǎng)友評(píng)論:做個(gè)記號(hào),以后用的時(shí)候方便!

網(wǎng)友評(píng)論:來(lái)一下!

網(wǎng)友評(píng)論:陳明計(jì)和周航慈有詳細(xì)的介紹,陳明計(jì)的在《嵌入式實(shí)時(shí)操作系統(tǒng)SMALL RTOS51原理及應(yīng)用》,周航慈在那本介紹ucos的書(shū)里面

網(wǎng)友評(píng)論:呵呵,我做串口都怎么做的!

網(wǎng)友評(píng)論:if(RI)
{
RI=0;
//P22=0;
Incept_data=SBUF;
if(Incept_Status==0x00) //中斷處于接收起始幀階段
{
if(Incept_data==Frame_Head)
{ Incept_Status=0x01;//更新接收狀態(tài)標(biāo)志為接收命令碼
//P23=0;
}
else
Incept_Status=0x00;
}
if(Incept_Status==0x01)
{
if(Incept_data==Frame_SetSimulate_Orde) //如果是設(shè)置幀命令,則立設(shè)置標(biāo)志
{ //P34=0;
command_marker=Frame_SetSimulate_Orde;
Incept_Status=0x02;//更新接收狀態(tài)標(biāo)志為接收幀長(zhǎng)碼
}
else if(Incept_data==Frame_SetDigital_Orde)
{ command_marker=Frame_SetDigital_Orde;
Incept_Status=0x02; // P11=0;
}
else if(Incept_data==Frame_Gather_Orde) //實(shí)時(shí)數(shù)據(jù)采集幀命令,則立設(shè)置標(biāo)志
{
command_marker=Frame_Gather_Orde;
Incept_Status=0x02;

}

syscheckData=0; //準(zhǔn)備進(jìn)行數(shù)據(jù)和校驗(yàn)
return;
}
if(Incept_Status==0x02) //接收幀長(zhǎng)
{// P35=0;
FrameLen=Incept_data;
syscheckData+=FrameLen; //更新累加和校驗(yàn)信息
Incept_Status=0x03; //更新接收狀態(tài)標(biāo)志為接收數(shù)據(jù)碼
return;
}
if(Incept_Status==0x03)
{
Incept_DataStream[RecCount]=Incept_data;
syscheckData+=Incept_DataStream[RecCount]; //更新累加和校驗(yàn)信息
RecCount++;
if(command_marker==Frame_SetSimulate_Orde)
{
if(RecCount==FrameLen)
{ // P36=0;
RecCount=0;
Incept_Status=0x04; //更新接收狀態(tài)為接收校驗(yàn)碼信息
}

}
if(command_marker==Frame_SetDigital_Orde)
{
if(RecCount==FrameLen)
{
RecCount=0;
Incept_Status=0x04; //更新接收狀態(tài)為接收校驗(yàn)碼信息
}

}
if(command_marker==Frame_Gather_Orde)
{
if(RecCount==FrameLen)
{
RecCount=0;
Incept_Status=0x04 ; ////更新接收狀態(tài)為接收校驗(yàn)碼信息
}

}
return;

}
if(Incept_Status==0x04)
{
checkData=Incept_data;
if(syscheckData!=checkData) //如校驗(yàn)出錯(cuò)
Incept_Status=0x00;
else
{Incept_Status=0x0537=0;} //P15=0;
syscheckData=0;
return;

}
if(Incept_Status==0x05)
{
if(Incept_data!=Frame_End)//錯(cuò)誤幀標(biāo)志
b_valid_Frame=0;
else
{ b_valid_Frame=1;} //P16=0;

Incept_Status=0x00;
}

}
}

網(wǎng)友評(píng)論:編程序每個(gè)人的思路都不同,感覺(jué)收發(fā)都在中斷里做會(huì)更好,這個(gè)程序進(jìn)來(lái)就關(guān)中斷不是太好吧?

網(wǎng)友評(píng)論:挖墳?

網(wǎng)友評(píng)論:正遇到這個(gè)問(wèn)題,不過(guò)我現(xiàn)在也是樓主這么做的,

網(wǎng)友評(píng)論:頂一個(gè),學(xué)習(xí)一下!

網(wǎng)友評(píng)論:

我總感覺(jué)樓主的程序是垃圾程序的典范!
嗨!


看出來(lái)了,俺水平太差,看了半天我也沒(méi)有理解樓主是什么意思!
哪位給我指點(diǎn)指點(diǎn)!
其實(shí)很多時(shí)候,對(duì)于通訊傳輸?shù)臄?shù)據(jù)處理才是關(guān)鍵,尤其對(duì)于設(shè)計(jì)通訊協(xié)議而言。筆者在剛剛做的一個(gè)系統(tǒng)上就碰到這樣的問(wèn)題,當(dāng)系統(tǒng)龐大了,資源十分有限的情況下,數(shù)據(jù)處理一旦占用資源太多,效率太低將導(dǎo)致系統(tǒng)崩潰而無(wú)法運(yùn)行。
到了這里,很多工程師可能會(huì)考慮開(kāi)個(gè)大的緩沖區(qū)FIFO將接收到的數(shù)據(jù)保存在緩沖區(qū),然后對(duì)其進(jìn)行解析、判斷進(jìn)行下一步程序編寫,當(dāng)然這在系統(tǒng)資源比較豐富的情況下是沒(méi)有問(wèn)題的,ARM上采取的就是這樣的方式。但如何系統(tǒng)龐大呢,留給的資源缺乏則不行。這樣做的一個(gè)很大缺點(diǎn)必須是將數(shù)據(jù)幀接收完了才能夠判斷,降低了效率和運(yùn)行速度。
其實(shí)還有另外的方式,可以采取在每接收一個(gè)字節(jié)就對(duì)其解析,解析完判斷轉(zhuǎn)到下一個(gè)狀態(tài),并將其中的有用數(shù)據(jù)存儲(chǔ)在相應(yīng)的數(shù)據(jù)結(jié)構(gòu)中去,可以采取狀態(tài)機(jī)實(shí)現(xiàn)。
這段意思是不是這樣:樓主以為先判斷后接收效率高、省資源。 先接收后判斷就“降低了效率和運(yùn)行速度”。

我就沒(méi)有看出到底哪里省資源了?
效率怎么就高了?

誰(shuí)能指點(diǎn)一下?多謝!

網(wǎng)友評(píng)論:直接把處理函數(shù)寫在中斷處理函數(shù)中不利于代碼移植重用和維護(hù),在大程序中這種架構(gòu)不應(yīng)提倡

網(wǎng)友評(píng)論:NO,NO
要用FIFO
要用CRC

網(wǎng)友評(píng)論:小頂一下

網(wǎng)友評(píng)論:頂頂

網(wǎng)友評(píng)論:不錯(cuò),挺好的

網(wǎng)友評(píng)論:
static void UartInterruptService(void) interrupt 4
{
ES = 0;
RI = 0;
uart_process(SBUF);
ES=1;
}
LZ的開(kāi)篇確實(shí)值得質(zhì)疑,上面66樓網(wǎng)友講的正根:“ES不可能自己搶占自己!贝谥袛硬件內(nèi)部已經(jīng)設(shè)計(jì)好了這種關(guān)系:(Intel硬件設(shè)計(jì)師是干什么的?如果我是硬件設(shè)計(jì)師,我怎么會(huì)把這種關(guān)系留給軟件設(shè)計(jì)員?)——首次ES中斷發(fā)生并進(jìn)入ISR之后,必然阻斷后面的同級(jí)中斷(如若有的話)并使其進(jìn)入中斷隊(duì)列排序等待,只有當(dāng)前ISR完成,RETI 退出串口中斷程序之后,此前紀(jì)錄的、位于隊(duì)列中的ES=1才會(huì)再次觸發(fā)串口中斷。所以,LZ的開(kāi)篇程序是不是一開(kāi)始就沒(méi)寫好?后面.....

static void UartInterruptService(void) interrupt 4
{
//ES = 0;
RI = 0;
uart_process(SBUF);
// ES=1;
}

其實(shí)我最近一直不好處理的問(wèn)題是:你在一幀數(shù)據(jù)接收過(guò)程中,如果半中間突然應(yīng)該來(lái)的數(shù)據(jù)中止不來(lái)了,怎么辦?你的while(RI !=1) ; RI=0;該如何處理才不至于死等?才可能盡快退出當(dāng)前狀態(tài)?——你如何盡快感知到通信失效?我知道是利用T0超時(shí),可是怎么寫才簡(jiǎn)單?接收100字節(jié)一幀,就要設(shè)置100次T0初值?太呆板了吧。(當(dāng)然可以用宏指令)如若每接收到第50字節(jié)時(shí)就發(fā)生中止或錯(cuò)誤接收現(xiàn)象,只好一幀重新來(lái)過(guò),以前的都白干!
如何才能提高通信系統(tǒng)可靠性?

網(wǎng)友評(píng)論:mark下串口通信,最近正在搞這個(gè)。

瀏覽:(1627)| 評(píng)論( 1 )
博文評(píng)論
Umesh:2012/12/3 16:33:00
Your posting ralley straightened me out. Thanks!

  • 昵 稱:
  • 內(nèi) 容:10~250個(gè)字符
  • 驗(yàn)證碼: 驗(yàn)證碼看不清楚?請(qǐng)點(diǎn)擊刷新驗(yàn)證碼
  •                      
  • 博文分類

    熱點(diǎn)博文

    最新博文

    最新評(píng)論

    IC電子元件查詢
    IC郵購(gòu)網(wǎng)電子元件品質(zhì)保障

    阜宁县| 龙海市| 鄄城县| 宁津县| 香港| 陕西省| 镇康县| 通道| 龙山县| 赤水市| 襄樊市| 横峰县| 邵阳县| 合川市| 太仓市| 巴南区| 博客| 阜平县| 巴塘县| 郴州市| 遵义市| 南投县| 江西省| 莱芜市| 华容县| 建湖县| 郓城县| 望城县| 六安市| 常德市| 太仓市| 莫力| 井研县| 维西| 怀远县| 祥云县| 夏邑县| 防城港市| 休宁县| 和林格尔县| 三台县|