国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

物聯網工程中GPIO模擬串口通用構件研究

2020-02-22 01:35
昆明學院學報 2020年6期
關鍵詞:波特率內核串口

石 棟

(昆明學院 信息工程學院,云南 昆明 650214)

串口是嵌入式系統(tǒng)開發(fā)中微控制器(MCU)間或微控制器與上位機之間最基本的通信手段.隨著物聯網技術的不斷發(fā)展,MCU的功能越來越強大.但考慮到成本問題,MCU生產商在MCU上僅會配置1~3個UART,以至于在嵌入式系統(tǒng)的開發(fā)過程中如果需要較多的串口通信時,就必須采用擴展串口的方式來實現.

目前,相關文獻報道的擴展串口方法主要有3種基本方案:1)利用硬件擴展多串口通信[1].該方式是利用數字控制的模擬數據選擇/分配器,或利用串口的擴展芯片來擴展串口.2)利用MCU定時器的定時功能實現軟件模擬串口.該類型的設計又分為兩種,一種是利用MCU上的定時器進行延時,從而用模擬的方法實現串口功能[2-5],另一種是使用定時器的輸出比較、輸入捕獲的功能實現UART功能[6].3)利用軟件空循環(huán)的方式實現模擬串口[7].這種方法使用for空循環(huán)語句進行延時,以實現控制串口通信每一位的持續(xù)時間.

在現有方案中,方案1的擴展方法需增加硬件成本;方案2需占用MCU定時器資源;方案3無法實現多時鐘頻率、多波特率下正常工作,可移植性差.因此,本文通過分析串口波特率、MCU內核時鐘頻率和延時函數之間的數學關系,借此給出準確延時的計算方案,從而在不增加硬件資源、不占用MCU定時器資源的情況下,利用純軟件方法實現可以在多內核時鐘頻率、多波特率下正常工作,且具備可移植、可復用的GPIO模擬串口構件設計.同時鑒于目前文獻中尚未解決用軟件方法實現串口功能時代碼時間開銷的測算問題,或只能粗略估算代碼時間開銷、僅能實現少量個字符接收的問題[7],提出一種較為準確的調試方法,從而較好地解決模擬串口的測試問題.

1 通用異步串口的技術要點分析

1.1 異步串口通信的技術要點

常見串口的基本要素包含串行通信數據格式、波特率和奇偶校驗.圖1[8]給出了8位數據、無奇偶校驗情況的傳送格式.

波特率是串口每秒內傳送的位數,其倒數就是發(fā)送一位的位長,也稱為位的持續(xù)時間.而奇偶校驗分為奇校驗和偶校驗,在使用時其僅能驗證字符中含“1”的位數是奇數個還是偶數個,校驗功能有限,實際應用中多不使用.因此本設計不考慮該設計方法.

1.2 GPIO模擬串口的技術要點

要實現通過GPIO模擬串口與上位機等其他設備的通信,模擬串口要具備與普通串口相同的異步串口通信格式、波特率等.從圖1可以看出,每發(fā)送(接收)一位都要持續(xù)一定的時間長度,即位長.一方面位長是波特率fbaud的倒數,另一方面位長還等于位長的時鐘周期數與MCU內核時鐘周期(內核時鐘頻率fCPU的倒數)的乘積.如果使用軟件延時的方法實現位長,則軟件延時所需時鐘周期數就應該等于位長的時鐘周期數.那么軟件延時數N就應該與波特率fbaud和MCU內核時鐘頻率fCPU間存在數學關系N=f(fbaud,fCPU),找到這一關系后,就可以用軟件的方式實現串口位長的精確延時,同時利用該數學關系還可實現GPIO模擬串口的可復用與可移植.

2 delay()函數延時公式推導

本文采用delay()函數來實現位延時:

void delay(uint_32 N)

{

uint_32 i;

for(i= 0;i

_asm(“NOP”);

}

其中,“NOP”是匯編指令,稱為空指令.該指令的功能是無操作,通常用作指令對齊或延時[9].如果能測算出當N=1,2,3,…時,delay函數執(zhí)行所需要的時鐘周期數,并找到其入口參數N與時鐘周期數的關系,就可以利用delay函數實現模擬串口的位延時.

2.1 delay()執(zhí)行周期數的測量

delay()函數執(zhí)行的時鐘周期數可借助定時器測量:將定時器的工作時鐘頻率設定為MCU的內核時鐘頻率,記錄下delay()函數開始執(zhí)行時和執(zhí)行結束時定時器的計數值,就可以計算出delay()函數執(zhí)行的時鐘周期數.由于Cortex-M系列處理器包含一個簡單時鐘定時器SysTick[10].因此,本文利用ARM公司的Cortex-M0+系列MCU中的SysTick定時器進行說明,測試方法如下:

……//初始化并使能SysTick定時器.

start_ticks=SysTick->VAL;//保存delay()函數開始時定時器計數值.

delay(N);//delay()函數執(zhí)行.

end_ticks=SysTick->VAL;//保存delay()函數結束時定時器計數值.

……//計算輸出語句或函數執(zhí)行的時鐘周期數.

在NXP公司基于ARM Cortex-M0+內核的KL25上,測量出delay()函數入口參數N與函數執(zhí)行所需時鐘周期數(Ntick)的關系,如表1所示.

表1 delay()函數入口參數與時鐘周期數的關系

從表1可以看出,當delay()函數入口參數為1時,執(zhí)行delay()函數需要的時鐘周期數是55次,隨后delay()函數的入口參數每增加1,delay()函數執(zhí)行需要的時鐘周期數就增加13次.由此不難得出,delay()函數的入口參數(N)與執(zhí)行時鐘周期數(Ntick)的關系為:

Ntick=13(N-1)+55,(N>0),

(1)

(1)式中的常數13和55除決定于MCU的CPU系列外,還與使用的編譯器環(huán)境有關.本文是在NXP的KDS環(huán)境下使用GNU編譯器實現的.在不同系列的MCU和不同的編譯環(huán)境下可將公式抽象為:

Ntick=A(N-1)+B,(N>0),

(2)

其中A和B為兩個待定常數,可在具體的MCU和編譯環(huán)境中測量確定.本文以KL25在GNU編譯環(huán)境下進行,則A=13,B=55.

2.2 串口波特率與MCU內核時鐘頻率的關系

串口的波特率fbaud代表了串口 1 s 能夠傳輸的位(Bit)數,其倒數就是串口傳輸一個二進制位(1 Bit)的位長.那么,串口傳輸一個二進制位(1 Bit)所需的時鐘周期數就應該等于串口傳輸一個二進制位(1 Bit)所持續(xù)的時間與內核時鐘周期的比值,也就是內核時鐘頻率fCPU與波特率fbaud的比值,即:

(3)

2.3 delay()函數延時次數的公式推導

用delay()函數來實現模擬串口的位延時,則delay()函數執(zhí)行延時所需的時鐘周期數應等于串口傳輸1 Bit的時鐘周期數.即:

Nticks=Nbit.

(4)

將公式(1)和公式(3)帶入公式(4),可得:

(5)

從公式(5)可以得出,只要確定MCU的內核時鐘頻率以及串口的波特率,就可以確定delay()函數的入口參數,因此就可用delay()函數在GPIO模擬串口實現位延時.即使內核時鐘頻率改變或波特率改變,也可用公式(5)計算出新入口參數N.

3 可移植與可復用GPIO模擬串口構件設計

為delay()函數找到準確的入口參數后,就可以編程實現模擬串口的功能.本文采用蘇州大學嵌入式實驗中心為KL25開發(fā)的底層驅動,并選用KL25開發(fā)板,在NXP公司提供的KDS軟件環(huán)境中實現模擬串口功能.為實現可移植與可復用的目的,工程采用構件化的思想將模擬串口的功能進行封裝,包含iouart.h和iouart.c文件.iouart.h是模擬串口構件的頭文件,其內容包含聲明保存延時函數入口參數的數組變量,以及模擬串口號的宏定義和函數聲明.iouart.c提供模擬串口的具體實現.這里僅就模擬串口的初始化、發(fā)送和接收功能進行描述,將這3個功能封裝成3個構件:初始化函數iouart_init();發(fā)送一字節(jié)函數iouart_send1();接收一字節(jié)函數iouart_re1().

3.1 GPIO模擬串口構件初始化設計

將GPIO模擬串口的初始化功能封裝成構件:iouart_init(uint_8 uartNo,uint_32 baud),參數uartNo和baud分別代表模擬串口編號和待用的波特率.該構件需完成3個任務:1)在MCU上選擇的2個空閑I/O引腳,將其復用為GPIO功能.2)將發(fā)送功能引腳的GPIO功能定義為輸出,并令其輸出“1”,即輸出空閑電平;將用作接收功能引腳的GPIO功能定義為輸入.3)將MCU的內核時鐘頻率(已知值)和選定的波特率代入公式(5)中計算delay()函數的入口參數,并將計算出來的入口參數結果放入到一個全局變量中供delay()函數使用.基本程序如下:

void iouart_init(uint_8 uartNo,uint_32 baud)

{

……//串口號解析及局部變量的聲明.

gpio_init(Uport[ioN],1,1);//初始化TX引腳:GPIO功能、輸出、高電平.

gpio_init(Uport[ioN+1],0,1);//初始化RX引腳:GPIO功能、輸入.

//計算特定波特率下“NOP”指令執(zhí)行的延時次數,保存到全局變量nop_ticks[]中供延時函數使用.

nop_ticks[nopN]= ((SystemCoreClock*1.0/baud)-55.0)/13.0+1;

}

代碼中,nop_ticks[]是保存delay()函數入口參數的數組,SystemCoreClock用于保存系統(tǒng)時鐘頻率,由MCU在啟動時配置好時鐘頻率后賦值.模擬串口引腳號放置于Uport[]數組中,在“iouart.c”文件中編寫.

3.2 GPIO模擬串口構件發(fā)送功能設計

GPIO模擬串口構件發(fā)送功能封裝為構件:iouart_send1(uint_8uartNo, uint_32 ch).設計只需嚴格按照圖1所示的串行通信數據格式設計即可.構件函數基本程序如下:

void iouart_send1(uint_8 uartNo, uint_8 ch)

{

……//函數初始化.

gpio_set(Uport[ioN],0);//發(fā)送起始位.

delay(nop_ticks[nopN]);//延時一位位長.

//發(fā)送8位數據.

for(i=0;i<8;i++)

{

j= ((ch>>i)&0x01);//獲取第i位狀態(tài).

gpio_set(Uport[ioN],j);//發(fā)送1位.

delay(nop_ticks[nopN]);//數據位延時.

}

gpio_set(Uport[ioN],1);//發(fā)送停止位.

delay(nop_ticks[nopN]);//停止位延時.

}

3.3 GPIO模擬串口構件接收功能設計

GPIO模擬串口構件接收功能封裝成構件:iouart_re1(uint_8uartNo).設計按照圖1所示的串行通信數據格式.但與發(fā)送功能比較,有3點不同:1)將開始位持續(xù)時間延長為原來的1.5倍,保證可以在每一個數據位的中間位置讀取接收數據,避免在電平變換時刻錯誤讀取接收引腳的數值.2)在接收數據位的每一位時采用連續(xù)接收3次的策略,實現濾波功能,避免因信號波動導致讀數錯誤.3)接收到停止位后不做位延時而直接返回數據,保證模擬串口接收連續(xù)字符時有充裕的處理時間.uint_8 iouart_re1(uint_8 uartNo)函數的核心代碼為:

uint_8 iouart_re1(uint_8 uartNo)

{

……//利用模擬串口號解析出RX引腳號及delay入口參數.

k=gpio_get(Uport[ioN]);//獲取起始位.

delay(nop_ticks[nopN]);

for(i=0;i<8;i++)//讀8位數據.

{

//連讀3次濾波,同時可減少由于延時不準確的影響.

k1=gpio_get(Uport[ioN]);

_asm(“NOP”);

k2=gpio_get(Uport[ioN]);

_asm(“NOP”);

k3=gpio_get(Uport[ioN]);

delay(nop_ticks[nopN]);

j=0;

//挑選3次讀中2次相同的值為最終值.

k1+=(k2+k3);

if(k1>=2) j=1;

dat|=((j)<

}

k=gpio_get(Uport[ioN]);//讀停止位.

gpio_clear_int(Uport[ioN]);//清除ISF中斷標志.

return dat

}

3.4 GPIO模擬串口構件的調試方法

實現了發(fā)送、接收功能的基本編程后,由于程序語句執(zhí)行、子函數調用都需要時間,就會導致模擬串口在發(fā)送接收數據時的時序出現問題.因此還需要對構件進行調試方能正常使用.為使GPIO模擬串口能夠正常工作在多種內核時鐘頻率下,且能夠使用多種波特率,調試最好選在低內核時鐘頻率、高波特率下進行.

3.4.1 發(fā)送構件的調試

由于本構件的位延時可以做到非常準確,因此發(fā)送時序的開始位、停止位可以少調試甚至不調試,僅需調試數據位的發(fā)送時序.下面以數據位的調試簡要說明其調試方法:1)根據使用的內核時鐘頻率和波特率,計算出位長的理論時鐘周期數Ntick(公式(3)).2)利用SysTick定時器測量發(fā)送構件iouart_send1()發(fā)送1個字節(jié)所用的時鐘周期數10Nreal(Nreal是發(fā)送1位所需的周期數,發(fā)送1個字節(jié)包含1個開始位、1個結束位、8個數據位),這樣可以得到實際位長的時鐘周期數Nreal.然后比較Ndata與Ntick,其差值ΔN=Nreal-Ntick就是由于數據位語句執(zhí)行消耗的時鐘周期數,這樣數據位的位延時就應該減少△N/13次,則數據位delay()函數的入口參數為N-△N/13,至此完成數據位的調試.

3.4.2 接收構件的調試

本文模擬串口采用GPIO中斷實現接收功能,則接收功能的調試有兩個位置:開始位和數據位.調試開始位時,定時器SysTick應從進入GPIO中斷服務例程時開始計時,到iouart_re1()函數開始位延時后計時結束,此時定時器測得的計數值就是開始位的實際位長Nreal,之后處理方法與發(fā)送功能的數據位調試方法基本一致.而數據位的調試與發(fā)送功能的數據位調試基本一致,此處不再詳述.

4 測試與分析

為實現GPIO模擬串口的通信功能,本文使用蘇州大學NXP嵌入式實驗中心的KL25開發(fā)板,在KDS3.0環(huán)境下利用KL25工程框架進行測試.測試中本文設計的場景是,從上位機發(fā)送“0x01~0xFF”共255個字符,GPIO模擬串口接收到字符后再回發(fā)到上位機.接收回發(fā)功能在中斷中實現.

測試結果如圖2所示.該圖是在KL25內核時鐘頻率為48 MHz、波特率為9 600 bps情況下的測試結果.經過改變系統(tǒng)內核時鐘頻率和波特率進行反復測試的結果表明,本構件在內核時鐘頻率分別為24,48 MHz,波特率可以在300,600,1 200,2 400,4 800,9 600,1 440,19 200,38 400 bps下正常工作.若將其移植到NXP基于Cortex-M4F的K64MCU上,只需重新確定公式(2)的待定參數A和B,模擬串口構件就可在K64上正常工作,從而實現了基于GPIO模擬串口的通用性和可復用性.

5 結語

本文從計算位長的時鐘周期數出發(fā),測算了delay函數的入口參數N及MCU內核時鐘頻率、串口波特率三者間的關系,提出位延時的數學模型N=f(fbaud,fCPU), 并根據該模型設計并實現了GPIO模擬串口構件.利用此方法設計的GPIO模擬串口構件可在不同的內核時鐘頻率、不同的波特率下,實現GPIO模擬串口的可移植和可復用.同時針對目前文獻尚未報道如何很好地解決模擬串口調試方法的問題,提出利用定時器實現GPIO模擬串口發(fā)送、接收功能的調試.此外,本設計方法可以使GPIO模擬串口具備較好的工作性能.

猜你喜歡
波特率內核串口
UART 波特率檢測電路的FPGA 設計算法與實現
多內核操作系統(tǒng)綜述①
基于NPORT的地面綜合氣象觀測系統(tǒng)通信測試方法及故障處理
強化『高新』內核 打造農業(yè)『硅谷』
活化非遺文化 承啟設計內核
CAN 總線波特率自適應程序設計
基于API函數庫實現串口數據通信的分析與設計
基于EM9000工控板高性能雙串口通信模型設計與實現
微軟發(fā)布新Edge瀏覽器預覽版下載換裝Chrome內核
淺談西門子S7—400與S7—200的通訊實現方法