日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁(yè) > 嵌入式 > 玩轉(zhuǎn)嵌入式
[導(dǎo)讀]本文介紹如何使用帶FIFO的串口來(lái)減少接收中斷次數(shù),通過(guò)一種自定義通訊協(xié)議格式,給出幀打包方法;之后介紹一種特殊的串口數(shù)據(jù)發(fā)送方法,可在避免使用串口發(fā)送中斷的情況下,提高系統(tǒng)的響應(yīng)速度。一種可1.簡(jiǎn)介串口由于使用簡(jiǎn)單,價(jià)格低廉,配合RS485芯片可以實(shí)現(xiàn)長(zhǎng)距離、抗干擾能力強(qiáng)的局域...

單片機(jī)、ARM、嵌入式等硬件、軟件設(shè)計(jì)經(jīng)驗(yàn)的分享,并提供一定的技術(shù)支持。我已加入“維權(quán)騎士”(rightknights.com)的版權(quán)保護(hù)計(jì)劃" data-from="0">本文介紹如何使用帶FIFO的串口來(lái)減少接收中斷次數(shù),通過(guò)一種自定義通訊協(xié)議格式,給出幀打包方法;之后介紹一種特殊的串口數(shù)據(jù)發(fā)送方法,可在避免使用串口發(fā)送中斷的情況下,提高系統(tǒng)的響應(yīng)速度。一種可

1. 簡(jiǎn)介

串口由于使用簡(jiǎn)單,價(jià)格低廉,配合RS485芯片可以實(shí)現(xiàn)長(zhǎng)距離、抗干擾能力強(qiáng)的局域網(wǎng)絡(luò)而被廣泛使用。隨著產(chǎn)品功能的增多,需要處理的任務(wù)也越來(lái)越復(fù)雜,系統(tǒng)任務(wù)也越來(lái)越需要及時(shí)響應(yīng)。絕大多數(shù)的現(xiàn)代單片機(jī)(ARM7、Cortex-M3)串口都帶有一定數(shù)量的硬件FIFO,本文將介紹如何使用硬件FIFO來(lái)減少接收中斷次數(shù),提高發(fā)送效率。在此之前,先來(lái)列舉一下傳統(tǒng)串口數(shù)據(jù)收發(fā)的不足之處:(1)每接收一個(gè)字節(jié)數(shù)據(jù),產(chǎn)生一次接收中斷。不能有效的利用串口硬件FIFO,減少中斷次數(shù)。(2)應(yīng)答數(shù)據(jù)采用等待發(fā)送的方法。由于串行數(shù)據(jù)傳輸?shù)臅r(shí)間遠(yuǎn)遠(yuǎn)跟不上CPU的處理時(shí)間,等待串口發(fā)送完當(dāng)前字節(jié)再發(fā)送下一字節(jié)會(huì)造成CPU資源浪費(fèi),不利于系統(tǒng)整體響應(yīng)(在1200bps下,發(fā)送一字節(jié)大約需要10ms,如果一次發(fā)送幾十個(gè)字節(jié)數(shù)據(jù),CPU會(huì)長(zhǎng)時(shí)間處于等待狀態(tài))。(3)應(yīng)答數(shù)據(jù)采用中斷發(fā)送。增加一個(gè)中斷源,增加系統(tǒng)的中斷次數(shù),這會(huì)影響系統(tǒng)整體穩(wěn)定性(從可靠性角度考慮,中斷事件應(yīng)越少越好)。(4)針對(duì)上述的不足之處,將結(jié)合一個(gè)常用自定義通訊協(xié)議,提供一個(gè)完整的解決方案。

2.串口FIFO

串口FIFO可以理解為串口專用的緩存,該緩存采用先進(jìn)先出方式。數(shù)據(jù)接收FIFO和數(shù)據(jù)發(fā)送FIFO通常是獨(dú)立的兩個(gè)硬件。串口接收的數(shù)據(jù),先放入接收FIFO中,當(dāng)FIFO中的數(shù)據(jù)達(dá)到觸發(fā)值(通常觸發(fā)值為1、2、4、8、14字節(jié))或者FIFO中的數(shù)據(jù)雖然沒(méi)有達(dá)到設(shè)定值但是一段時(shí)間(通常為3.5個(gè)字符傳輸時(shí)間)沒(méi)有再接收到數(shù)據(jù),則通知CPU產(chǎn)生接收中斷;發(fā)送的數(shù)據(jù)要先寫入發(fā)送FIFO,只要發(fā)送FIFO未空,硬件會(huì)自動(dòng)發(fā)送FIFO中的數(shù)據(jù)。寫入發(fā)送FIFO的字節(jié)個(gè)數(shù)受FIFO最大深度影響,通常一次寫入最多允許16字節(jié)。上述列舉的數(shù)據(jù)跟具體的硬件有關(guān),CPU類型不同,特性也不盡相同,使用前應(yīng)參考相應(yīng)的數(shù)據(jù)手冊(cè)。

3.數(shù)據(jù)接收與打包

FIFO可以緩存串口接收到的數(shù)據(jù),因此我們可以利用FIFO來(lái)減少中斷次數(shù)。以NXP的lpc1778芯片為例,接收FIFO的觸發(fā)級(jí)別可以設(shè)置為1、2、4、8、14字節(jié),推薦使用8字節(jié)或者14字節(jié),這也是PC串口接收FIFO的默認(rèn)值。這樣,當(dāng)接收到大量數(shù)據(jù)時(shí),每8個(gè)字節(jié)或者14個(gè)字節(jié)才會(huì)產(chǎn)生一次中斷(最后一次接收除外),相比接收一個(gè)字節(jié)即產(chǎn)生一個(gè)中斷,這種方法串口接收中斷次數(shù)大大減少。將接收FIFO設(shè)置為8或者14字節(jié)也十分簡(jiǎn)單,還是以lpc1778為例,只需要設(shè)置UART FIFO控制寄存器UnFCR即可。接收的數(shù)據(jù)要符合通訊協(xié)議規(guī)定,數(shù)據(jù)與協(xié)議是密不可分的。通常我們需要將接收到的數(shù)據(jù)根據(jù)協(xié)議打包成一幀,然后交由上層處理。下面介紹一個(gè)自定義的協(xié)議幀格式,并給出一個(gè)通用打包成幀的方法。自定義協(xié)議格式如圖3-1所示。
  • 幀首:通常是3~5個(gè)0xFF或者0xEE
  • 地址號(hào):要進(jìn)行通訊的設(shè)備的地址編號(hào),1字節(jié)
  • 命令號(hào):對(duì)應(yīng)不同的功能,1字節(jié)
  • 長(zhǎng)度:數(shù)據(jù)區(qū)域的字節(jié)個(gè)數(shù),1字節(jié)
  • 數(shù)據(jù):與具體的命令號(hào)有關(guān),數(shù)據(jù)區(qū)長(zhǎng)度可以為0,整個(gè)幀的長(zhǎng)度不應(yīng)超過(guò)256字節(jié)
  • 校驗(yàn):異或和校驗(yàn)(1字節(jié))或者CRC16校驗(yàn)(2字節(jié)),本例使用CRC16校驗(yàn)
下面介紹如何將接收到的數(shù)據(jù)按照?qǐng)D3-1所示的格式打包成一幀。

3.1 定義數(shù)據(jù)結(jié)構(gòu)

typedef?struct?
{
??
????uint8_t?*?dst_buf;??????????????????//指向接收緩存??
????uint8_t?sfd;????????????????????????//幀首標(biāo)志,為0xFF或者0xEE??
????uint8_t?sfd_flag;???????????????????//找到幀首,一般是3~5個(gè)FF或EE??
????uint8_t?sfd_count;??????????????????//幀首的個(gè)數(shù),一般3~5個(gè)??
????uint8_t?received_len;???????????????//已經(jīng)接收的字節(jié)數(shù)??
????uint8_t?find_fram_flag;?????????????//找到完整幀后,置1??
????uint8_t?frame_len;??????????????????//本幀數(shù)據(jù)總長(zhǎng)度,這個(gè)區(qū)域是可選的??
}find_frame_struct;

3.2 初始化數(shù)據(jù)結(jié)構(gòu),一般放在串口初始化中

/**?
*?@brief????初始化尋找?guī)臄?shù)據(jù)結(jié)構(gòu)?
*?@param????p_fine_frame:指向打包幀數(shù)據(jù)結(jié)構(gòu)體變量?
*?@param????dst_buf:指向幀緩沖區(qū)?
*?@param????sfd:幀首標(biāo)志,一般為0xFF或者0xEE?
*/
??
void?init_find_frame_struct(find_frame_struct?*?p_find_frame,uint8_t?*dst_buf,uint8_t?sfd)??
{??
????p_find_frame->dst_buf=dst_buf;??
????p_find_frame->sfd=sfd;??
????p_find_frame->find_fram_flag=0;??
????p_find_frame->frame_len=10;???????
????p_find_frame->received_len=0;??
????p_find_frame->sfd_count=0;??
????p_find_frame->sfd_flag=0;??
}?

3.3 數(shù)據(jù)打包程序

/**?
*?@brief????尋找一幀數(shù)據(jù)??返回處理的數(shù)據(jù)個(gè)數(shù)?
*?@param????p_find_frame:指向打包幀數(shù)據(jù)結(jié)構(gòu)體變量?
*?@param????src_buf:指向串口接收的原始數(shù)據(jù)?
*?@param????data_len:src_buf本次串口接收到的原始數(shù)據(jù)個(gè)數(shù)?
*?@param????sum_len:幀緩存的最大長(zhǎng)度?
*?@return???本次處理的數(shù)據(jù)個(gè)數(shù)?
*/
??
uint32_t?find_one_frame(find_frame_struct?*?p_find_frame,const?uint8_t?*?src_buf,uint32_t?data_len,uint32_t?sum_len)??
{??
????uint32_t?src_len=0;??
????while(data_len--)??
????{??
????????if(p_find_frame?->sfd_flag==0)????????????????????????
????????{???//沒(méi)有找到起始幀首??
????????????if(src_buf[src_len ]==p_find_frame?->sfd)??
????????????{??
????????????????p_find_frame?->dst_buf[p_find_frame?->received_len ]=p_find_frame?->sfd;??
????????????????if( p_find_frame?->sfd_count==5)??????????
????????????????{??
????????????????????p_find_frame?->sfd_flag=1;??
????????????????????p_find_frame?->sfd_count=0;??
????????????????????p_find_frame?->frame_len=10;??
????????????????}??
????????????}??
????????????else??
????????????{??
????????????????p_find_frame?->sfd_count=0;???
????????????????p_find_frame?->received_len=0;???
????????????}??
????????}??
????????else???
????????{???//是否是"長(zhǎng)度"字節(jié)??Y->獲取這幀的數(shù)據(jù)長(zhǎng)度??
????????????if(7==p_find_frame?->received_len)????????????????
????????????{??
????????????????p_find_frame->frame_len=src_buf[src_len] 5 1 1 1 2;?//幀首 地址號(hào) 命令號(hào) 數(shù)據(jù)長(zhǎng)度 校驗(yàn)???????
????????????????if(p_find_frame->frame_len>=sum_len)??
????????????????{???//這里處理方法根據(jù)具體應(yīng)用不一定相同??
????????????????????MY_DEBUGF(SLAVE_DEBUG,("數(shù)據(jù)長(zhǎng)度超出緩存!\n"));??
????????????????????p_find_frame->frame_len=?sum_len;???????
????????????????}??
????????????}??
??????????????
????????????p_find_frame?->dst_buf[p_find_frame->received_len ]=src_buf[src_len ];????????????????
????????????if(p_find_frame?->received_len==p_find_frame?->frame_len)??????????????????
????????????{??
????????????????p_find_frame?->received_len=0;??????????????//一幀完成????
????????????????p_find_frame?->sfd_flag=0;??
????????????????p_find_frame?->find_fram_flag=1;???????????????????
????????????????return?src_len;??
????????????}??
????????}??
????}??
????p_find_frame?->find_fram_flag=0;??
????return?src_len;??
}?
使用例子:定義數(shù)據(jù)結(jié)構(gòu)體變量:find_frame_struct?slave_find_frame_srt;定義接收數(shù)據(jù)緩沖區(qū):#define?SLAVE_REC_DATA_LEN??128
uint8_t?slave_rec_buf[SLAVE_REC_DATA_LEN];
在串口初始化中調(diào)用結(jié)構(gòu)體變量初始化函數(shù):init_find_frame_struct(
本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除( 郵箱:macysun@21ic.com )。
換一批
延伸閱讀

在單片機(jī)通信系統(tǒng)中,數(shù)據(jù)幀是實(shí)現(xiàn)設(shè)備間可靠對(duì)話的核心載體。不同于網(wǎng)絡(luò)通信中成熟的TCP/IP協(xié)議,單片機(jī)通信往往需要自定義數(shù)據(jù)幀格式,而幀頭、幀尾與校驗(yàn)機(jī)制則是保障數(shù)據(jù)傳輸準(zhǔn)確性的三大關(guān)鍵。

關(guān)鍵字: 單片機(jī) 數(shù)據(jù)幀

隨著嵌入式技術(shù)的不斷發(fā)展,時(shí)序分析工具和方法也在不斷進(jìn)步,未來(lái)將朝著智能化、自動(dòng)化的方向發(fā)展,為開(kāi)發(fā)者提供更高效的調(diào)試手段。但無(wú)論技術(shù)如何發(fā)展,扎實(shí)的時(shí)序分析基礎(chǔ)都是嵌入式開(kāi)發(fā)者不可或缺的能力,只有深入理解通信時(shí)序的本質(zhì)...

關(guān)鍵字: 時(shí)序 單片機(jī)

在嵌入式系統(tǒng)設(shè)計(jì)中,不同架構(gòu)、不同廠商的單片機(jī)協(xié)同工作早已成為常態(tài)。從8位的51系列到32位的STM32,從精簡(jiǎn)指令集的PIC到復(fù)雜指令集的AVR,這些性能各異的單片機(jī)如何突破硬件差異實(shí)現(xiàn)數(shù)據(jù)交互,是嵌入式開(kāi)發(fā)中的核心課...

關(guān)鍵字: 嵌入式 單片機(jī)

在嵌入式系統(tǒng)開(kāi)發(fā)中,單片機(jī)的時(shí)鐘系統(tǒng)是整個(gè)系統(tǒng)的"心臟",所有的指令執(zhí)行、外設(shè)操作、定時(shí)器中斷都依賴于精準(zhǔn)的時(shí)鐘信號(hào)。但在實(shí)際開(kāi)發(fā)過(guò)程中,很多開(kāi)發(fā)者都會(huì)遇到單片機(jī)時(shí)鐘不準(zhǔn)的問(wèn)題,表現(xiàn)為定時(shí)器計(jì)時(shí)偏差、UART通信波特率錯(cuò)...

關(guān)鍵字: 控制系統(tǒng) 單片機(jī)

在單片機(jī)開(kāi)發(fā)與調(diào)試過(guò)程中,復(fù)位電路作為保障芯片正常啟動(dòng)的核心模塊,其穩(wěn)定性直接影響程序燒錄與系統(tǒng)運(yùn)行。實(shí)際應(yīng)用中,不少開(kāi)發(fā)者會(huì)遇到“接穩(wěn)壓電源可正常燒錄,接入電池后卻無(wú)法燒錄程序”的故障,此類問(wèn)題多與復(fù)位電路設(shè)計(jì)、電池供...

關(guān)鍵字: 單片機(jī) 復(fù)位電路 時(shí)序匹配

在單片機(jī)的世界里,“字節(jié)”(Byte)是一個(gè)貫穿始終的核心概念。從存儲(chǔ)數(shù)據(jù)到執(zhí)行指令,從變量定義到外設(shè)通信,字節(jié)無(wú)處不在。很多初學(xué)者在學(xué)習(xí)單片機(jī)時(shí),往往更關(guān)注復(fù)雜的程序邏輯和外設(shè)驅(qū)動(dòng),卻忽略了字節(jié)這個(gè)基礎(chǔ)知識(shí)點(diǎn),導(dǎo)致在后...

關(guān)鍵字: 單片機(jī) 字節(jié)

在單片機(jī)的數(shù)字邏輯中,我們通常最關(guān)注的是高電平和低電平兩種狀態(tài),它們構(gòu)成了二進(jìn)制數(shù)字世界的基礎(chǔ)。然而,除了這兩種狀態(tài)之外,還有一種至關(guān)重要但常常被忽視的狀態(tài)——高阻態(tài)(High Impedance State)。高阻態(tài)就...

關(guān)鍵字: 單片機(jī) 高阻態(tài)

對(duì)于PIC入門者來(lái)說(shuō),不需要盲目追求高端開(kāi)發(fā)板,一塊功能均衡、資料豐富的入門款就能滿足需求。比如Microchip官方推出的PIC16F84A開(kāi)發(fā)板,它搭載經(jīng)典的8位PIC內(nèi)核,引腳布局清晰,自帶LED、按鍵等基礎(chǔ)外設(shè),...

關(guān)鍵字: PIC 單片機(jī)

該低功耗器件支持5V運(yùn)行,在實(shí)現(xiàn)高性能的同時(shí),能有效保障系統(tǒng)簡(jiǎn)潔性與成本效益

關(guān)鍵字: MCU 單片機(jī) 工業(yè)自動(dòng)化
關(guān)閉