




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、串口設(shè)備驅(qū)動接口STM32的2.0固件庫的工程文檔ourdev_611401K0IJZU.rar(文件大小:227K) (原文件名:串口發(fā)送模板(第二版).rar)STM32的3.0固件庫的工程文檔ourdev_611402L6BK0Z.rar(文件大小:801K) (原文件名:串口發(fā)送模板(第三版).rar)在設(shè)計串口驅(qū)動的過程中,要遵循的兩條準(zhǔn)則是:1:盡量的減少程序運(yùn)行的時間。2:盡量的減少程序所占用的內(nèi)存。譬如,下面的一段程序:程序段1-1/*指針是指向ptr,需要發(fā)送count個數(shù)據(jù)*/void USART1WriteDataToBuffer(*ptr,u8 count) /*判斷數(shù)
2、據(jù)是否發(fā)送完畢*/ while(count-) /*發(fā)送數(shù)據(jù)*/ USART1SendByte(*ptr+); /*等待這個數(shù)據(jù)發(fā)送完畢,然后進(jìn)入下一個數(shù)據(jù)的發(fā)送過程*/ while(USART_GetFlagStatus(USART1,USART_FLAG_TC); /*數(shù)據(jù)發(fā)送完畢,返回*/很明顯,這段程序在實際應(yīng)用中將會產(chǎn)生災(zāi)難性的后果,首先,當(dāng)發(fā)送數(shù)據(jù)送到發(fā)送寄存器啟動發(fā)送以后,CPU就一直在等待這個數(shù)據(jù)發(fā)送完成,然后進(jìn)入下一個數(shù)據(jù)的發(fā)送,這樣,直到所有要發(fā)送的數(shù)據(jù)完成,CPU才能做其他的事情。相對于CPU內(nèi)核運(yùn)行的速度而言,串口外設(shè)的運(yùn)行速度是非??斓模屢粋€速度非??斓脑O(shè)備去等待相
3、對很慢的設(shè)備,程序的效率是非常低下的。所以必須采用中斷的方式發(fā)送數(shù)據(jù)。程序段1-2/*將數(shù)據(jù)寫入發(fā)送緩沖區(qū)*/void USART1WriteDataToBuffer(*ptr,u8 count) while(count!='0') USART1SendTCBIndex+=*ptr+; Count=count; /.判斷溢出等其他代碼省略./.發(fā)送中斷的ISR./void USART1SendUpdate(void) /.判斷發(fā)送緩沖區(qū)中的數(shù)據(jù)是否發(fā)送完畢./ /將發(fā)送緩沖區(qū)的數(shù)據(jù)發(fā)送出去/ USART1SendByte(*ptr+); /.發(fā)送指針加一,待發(fā)送的字節(jié)數(shù)減一等代
4、碼./ 這樣,當(dāng)調(diào)用USART1WriteDataToBuffer函數(shù)將待發(fā)送的數(shù)據(jù)寫入發(fā)送緩沖區(qū)以后,CPU就可以執(zhí)行其他的任務(wù),待一個數(shù)據(jù)發(fā)送完成以后,中斷ISR就會觸發(fā),在中斷服務(wù)程序里面將下一個數(shù)據(jù)寫入發(fā)送寄存器,啟動下一次發(fā)送,知道完全發(fā)送完畢為止。 很明顯,上述的程序的設(shè)計比較好,不用占用過多的CPU時間。 在實際的工程應(yīng)用中,經(jīng)常會出現(xiàn)類似這種情況:串口顯示屏需要顯示1000個點(diǎn),通過串口發(fā)送這1000個點(diǎn)的顏色的RGB亮度值。將這1000個數(shù)據(jù)寫入發(fā)送緩沖區(qū)以后,啟動發(fā)送。在115200的波特率,一位起始位,一位停止位,無校驗位的情況下,至少需要(10*1000*2)/1152
5、00=0.1736秒,在這期間以內(nèi),時鐘更新了,需要再發(fā)送給串口一串時間更新的數(shù)據(jù),這個數(shù)據(jù)大約有100個,這樣這串?dāng)?shù)據(jù)需要寫入到發(fā)送緩沖區(qū)的發(fā)送字節(jié)的后面。同樣道理,在這個時候如果有顯示任務(wù)更新的話,將會有其他的數(shù)據(jù)寫入到發(fā)送緩沖區(qū)。串口1 (原文件名:串口1.JPG) 從圖上可以看出,程序段1-2雖然滿足了時間上的要求,卻沒有滿足空間上的要求,它的數(shù)據(jù)緩沖區(qū)是單向的,這樣,當(dāng)發(fā)送緩沖區(qū)的所有的數(shù)據(jù)全部發(fā)送完畢后,或者當(dāng)發(fā)送緩沖區(qū)撐滿了以后才能將發(fā)送緩沖區(qū)內(nèi)的數(shù)據(jù)清空,以便裝入下次的緩沖數(shù)據(jù)。這樣內(nèi)存較小的嵌入式系統(tǒng)來說是不能容忍的。因此,可以將發(fā)送緩沖區(qū)建立成一個環(huán)形的緩沖區(qū),在這個環(huán)形緩
6、沖區(qū)內(nèi),通過頭指針(HostIndex)和尾指針(HostIndex)來定位空白區(qū)和數(shù)據(jù)區(qū)。(1):頭指針(HostIndex)指向有數(shù)據(jù)區(qū)的頂部,每次寫入數(shù)據(jù),都更新頭指針,如果到了緩沖區(qū)的末端(EndIndex),就自動返回到緩沖區(qū)的起始處(StartIndex),直到寫入到尾指針處為止,這時緩沖區(qū)已經(jīng)被裝滿,不能再裝入數(shù)據(jù)。(2):尾指(TailIndex)針指向有數(shù)據(jù)區(qū)的尾部,當(dāng)數(shù)據(jù)發(fā)送完畢后,更新尾指針的位置,如果到了緩沖區(qū)的末端(EndIndex),就自動返回到緩沖區(qū)的起始處(StartIndex),直到遇到頭指針為止,這是證明所有的數(shù)據(jù)已經(jīng)發(fā)送完畢。串口2 (原文件名:串口2.J
7、PG) 這樣就實現(xiàn)了發(fā)送緩沖區(qū)的動態(tài)調(diào)整空白區(qū)和數(shù)據(jù)區(qū),剛剛發(fā)送完畢的數(shù)據(jù),馬上就被開辟出來用于存放下個數(shù)據(jù),最大可能的節(jié)省了寶貴的發(fā)送緩沖區(qū)的空間,提高了使用效率。 這個程序比較復(fù)雜,大致的流程如下(省略了狀態(tài)的判定,保護(hù)措施等代碼)程序段1-3/*將數(shù)據(jù)寫入發(fā)送緩沖區(qū)*/void USART1WriteDataToBuffer(*ptr,u8 count) while(count!='0') /*頭指針不等于尾指針,緩沖區(qū)沒有撐滿*/ if(USART1HosIndext!=USART1TailIndex) USART1SendTCBUSART1HosIndex=*ptr+
8、; /*更新頭指針,如果到了緩沖區(qū)的末端,就自動返回到緩沖區(qū)的起始處*/ if(+USART1HosIndext>=USART1_SEND_MAX_BOX)USART1HosIndext=0; /.判斷溢出等其他代碼省略./.發(fā)送中斷的ISR./void USART1SendUpdate(void) /*頭指針不等于尾指針,緩沖區(qū)尚有未發(fā)生完的數(shù)據(jù)*/ if(USART1HosIndext!=USART1TailIndex) /*將發(fā)送緩沖區(qū)的數(shù)據(jù)發(fā)送出去*/ USART1SendByte(*USART1TailIndex); /*更新尾指針的位置,如果到了緩沖區(qū)的末端,就自動返回到緩沖
9、區(qū)的起始處*/ if(+USART1TailIndex>=USART1_SEND_MAX_BOX)USART1TailIndex=0; /.判斷溢出等其他代碼省略./ 值得注意的是,一些微控制器中,例如在Cortex-M3的微控制器架構(gòu)中,有DMA傳送模式,可以配置一個內(nèi)部的通道,將指定的地址處的數(shù)據(jù),在無須CPU的管理下,直接將其發(fā)送到串口發(fā)送寄存器里去。通過這個方法,可以大大的降低了發(fā)送過程中重復(fù)進(jìn)入中斷的次數(shù),從而大大提高了效率。這樣,如果使用了這個芯片,就可以使用DMA模式進(jìn)行發(fā)送。但是DMA發(fā)送模式下,對于頭指針和尾指針就得做出一些修改,因為DMA傳送過程中,是不能讓頭指針到達(dá)
10、緩沖區(qū)終點(diǎn)后,自動將指針調(diào)整到起點(diǎn)位置的。 但是,加入發(fā)送管理結(jié)構(gòu)體以后,上述問題可以得到解決。 利用內(nèi)存塊動態(tài)分配可以大大減少提高內(nèi)存的使用效率,尤其是對于串口通信而言,更是如此。利用內(nèi)存管理模塊可以將微控制器除全局變量和靜態(tài)結(jié)構(gòu)變量以外的剩余的內(nèi)存統(tǒng)一管理,在需要時候申請,在不用的時候釋放,如串口的發(fā)送緩沖區(qū),以太網(wǎng),SD卡,外部數(shù)據(jù)存儲器等等均可以用內(nèi)存來管理,可以重復(fù)使用,大大提高了使用效率。內(nèi)存分配1 (原文件名:內(nèi)存分配1.JPG) </center> 首先定義發(fā)送緩沖區(qū)管理塊的結(jié)構(gòu)體 typedef struct unsigned char Num; /該存儲區(qū)保存的
11、有效字節(jié)數(shù)量 unsigned char *Index; /該存儲區(qū)申請的內(nèi)存塊的指針 unsigned char *MemIndex; /該存儲區(qū)申請的內(nèi)存塊管理區(qū)的指針 USART1SendTcb; 例如需要200字節(jié):串口3 (原文件名:串口3.JPG) 這樣,加入動態(tài)內(nèi)存與發(fā)送緩沖區(qū)管理塊以后,無論是采用DAM模式發(fā)送數(shù)據(jù)還是普通的方式,都可以輕易的配置。將內(nèi)存塊的指針值Index傳給DMA的發(fā)送地址,將待發(fā)送的字節(jié)數(shù)Num傳給DMA的發(fā)送字節(jié)計數(shù)寄存器,就可以完成無須CPU管理的操作,最大的減少了CPU的使用,大大提高了內(nèi)存效率。或者采用普通的中斷模式。 具體的代碼較長,見工程文件,
12、不再詳細(xì)列出。 內(nèi)存管理 在嵌入式設(shè)備中,往往會存在一些任務(wù)需要大量的內(nèi)存,在內(nèi)存相對較少的微控制器中,怎樣有效管理這些寶貴的資源,是必須解決的一個重要問題。 在上位機(jī)的編程中,我們通常使用malloc()函數(shù)以及Free()函數(shù)來完成對內(nèi)存的管理。這是因為相對嵌入式系統(tǒng)而言,上位機(jī)的內(nèi)存非常大,而且Windows提供了很好的內(nèi)存管理接口,所以不存在問題。但是在嵌入式系統(tǒng)中,大量使用上述函數(shù)會出現(xiàn)兩個問題: (1)產(chǎn)生內(nèi)存碎片的問題。 在運(yùn)行的過程中,各個任務(wù)頻繁的調(diào)用內(nèi)存分配和釋放,會導(dǎo)致原本一整塊空間地址連續(xù)的區(qū)域分散成一堆物理地址上相互獨(dú)立的區(qū)域,這樣有可能導(dǎo)致一個程序需要一個較大的內(nèi)存
13、,空余的內(nèi)存塊沒有一個連續(xù)的地址,無法分配給任務(wù)。久而久之,最后系統(tǒng)可能連一個很小的物理地址都分配不到,最后導(dǎo)致系統(tǒng)的崩潰。如下圖所示:內(nèi)存分配2 (原文件名:內(nèi)存分配2.JPG) 在上圖中可以看到,雖然起始地址為20000的內(nèi)存區(qū)有16個空白的字節(jié),但是仍然無法為任務(wù)分配到四個字節(jié)的物理內(nèi)存。 (2)運(yùn)行的時間不確定的問題 在free()函數(shù)中,存在著一些內(nèi)存合并等功能,例如將釋放完成以后,將空間上相近的兩個空白區(qū)域合并為同一個,將存在內(nèi)存碎片的區(qū)域重新整合,甚至可能使用了二叉樹等非線性數(shù)據(jù)結(jié)構(gòu),等等操作。 而這些函數(shù)所耗費(fèi)的時間是無法確定的,在實際的應(yīng)用中,對于內(nèi)存這種全局變量,多個任務(wù)都
14、要用到,為避免會存在可重入性的問題,必須采用信號同步的方法,或者暫時關(guān)閉中斷的方法,來同步對各個任務(wù)對共享資源的使用。這樣,導(dǎo)致了系統(tǒng)死區(qū)時間的增加,響應(yīng)速度的變慢,不確定性增加。 因此,在大多數(shù)嵌入式系統(tǒng)中,通常采用靜態(tài)內(nèi)存塊池的方法。將系統(tǒng)空余的內(nèi)存統(tǒng)一管理,生成一系列的大小固定的內(nèi)存塊池,在實際的操作中,以這一整個內(nèi)存塊進(jìn)行操作。 實現(xiàn)過程 首先定義內(nèi)存管理塊的結(jié)構(gòu)體 typedef struct OSMEMTCB void *OSMemFreeList;/用于指向該管理區(qū)中的空白的內(nèi)存塊 u8 OSMemBlkSize;/用于該管理區(qū)中的每個內(nèi)存塊的字節(jié)數(shù) u8 OSMemNBlks;
15、/用于該管理區(qū)中的分為多少個內(nèi)存塊 u8 OSMemFreeNBlks;/用于該管理區(qū)還剩多少空白內(nèi)存塊 OSMEMTcb; 將一個靜態(tài)的存儲區(qū)分配給內(nèi)存配置函數(shù),內(nèi)存管理塊的各個列表的含義如下圖所示:內(nèi)存分配3 (原文件名:內(nèi)存分配3.JPG) 每個內(nèi)存塊的頭四個字節(jié)用于存儲下一個內(nèi)存塊的指針地址,直到倒數(shù)第一個為止,最后一個指針指向一個空的指針,表明已經(jīng)到達(dá)內(nèi)存區(qū)的的末端。 在實際運(yùn)用過程中,OSMemFreeList是指向空白的內(nèi)存塊的指針,通過它來申請內(nèi)存,當(dāng)申請到內(nèi)存塊以后,OSMemFreeList指向當(dāng)前數(shù)據(jù)塊的下一個內(nèi)存塊節(jié)點(diǎn)地址(內(nèi)存管理函數(shù)已經(jīng)自動將所有內(nèi)存塊通過指針鏈接成
16、一個單向鏈表),當(dāng)釋放內(nèi)存塊的時候,將OSMemFreeList指向當(dāng)前釋放的內(nèi)存塊,將當(dāng)前內(nèi)存塊的下一個內(nèi)存塊指針指向先前的OSMemFreeList。OSMemFreeNBlks保存著該內(nèi)存區(qū)空白塊的數(shù)量,若內(nèi)存塊已滿,返回錯誤代碼,OSMemBlkSize指的是每個內(nèi)存塊內(nèi)字節(jié)數(shù)量,它的大小可以根據(jù)需要指定,理論上是它越小,內(nèi)塊的利用率就越高,例如保存一個101個字節(jié)的數(shù)據(jù),若一個內(nèi)存塊的大小是10個字節(jié),則需要11個內(nèi)存塊,若一個內(nèi)存塊的大小是100個字節(jié),則需要2個內(nèi)存塊,最后一個內(nèi)存塊僅僅使用了一個字節(jié)。但并非內(nèi)存塊的越小越好,因為保存下個內(nèi)存塊節(jié)點(diǎn)的地址需要4個地址位,內(nèi)存塊越小
17、,保存地址的數(shù)據(jù)所占比例越高。在實際操作32字節(jié)過程中,可以定義大小不同的內(nèi)存塊,靈活運(yùn)用。內(nèi)存分配4 (原文件名:內(nèi)存分配4.JPG) 內(nèi)存配置函數(shù)的核心代碼:OSMemCreate(.)內(nèi)存分配5 (原文件名:內(nèi)存分配5.JPG) for(i=0;i<nblks-1;i+) plink=(void *)(link); /將二維指針定位到框的首位 *plink=(void *)(link+blksize); /該內(nèi)存塊的地址存放的 /是第二片內(nèi)存區(qū)的首地址 link+=blksize; /一維指針重新定位 /最后一個二維指針指向一個空指針 獲取內(nèi)存塊的核心代碼:OSMemGet(.)
18、tcb=(*ptr).OSMemFreeList; if(*ptr).OSMemFreeNBlks=0)return (void *)0;/如果空白內(nèi)存塊的數(shù)量為 /返回,若正確返回,收到的數(shù)據(jù)應(yīng)該是0 (*ptr).OSMemFreeNBlks-; /空白內(nèi)存塊塊數(shù)量減一 /空白內(nèi)存塊指針指向下一個內(nèi)存區(qū) /tcb指向的是內(nèi)存塊節(jié)點(diǎn)指針,不能直接使用,加上偏移值4個字節(jié) index=(u8 *)tcb; index+=4; /返回內(nèi)存塊指針 return index; 釋放內(nèi)存塊的核心代碼:OSMemDelete(.) (void *)tcb=(*ptr).OSMemFreeList; /將
19、OSMemFreeList重新指向這個已經(jīng)變成空白了的指針 (*ptr).OSMemFreeList=tcb; /將這個空白的指針的下個指針指向原先的空白區(qū)指針 (*ptr).OSMemFreeNBlks+; /空白內(nèi)存塊數(shù)量加1值得說明的是,工程文件中的OSQMem.h文件中OS_MEM_MAX /最多允許的內(nèi)存塊管理區(qū)OS_MEM_USART1_MAX 1024 /發(fā)送緩沖區(qū)的內(nèi)存大小OS_MEM_USART1_BLK 32 /每一個塊的長度 而 USART.h文件中DMA_MODE /定義是采用DMA模式,還是普通的中斷模式 推薦是用DMA模式再就是很多朋友可能覺得奇怪的是為什么一個是U
20、SART1.cUSART1Cinfig.cUSART1.c是上層文件,與硬件無關(guān),USART1Cinfig.c是底層文件,與硬件相關(guān),為了方便移植,只需改變USART1Cinfig.c的內(nèi)容就可以,我只有STM32的板子,Mega16的板子,和340的板子,都是我自己做的,這個程序經(jīng)過移植到上述三個板子以后已經(jīng)用在項目中了,在下是個菜鳥,希望朋友們多多指教。一直在這里學(xué)習(xí)到了很多東西,本人比較懶,老是索取而沒有回報,希望能對初學(xué)的朋友們有用。我的郵箱是linquan315歡迎朋友們多多交流。2011年1月16日加上:在補(bǔ)上幾句話,告訴兄弟們怎么使用,把工程文檔的驅(qū)動這個文件夾的內(nèi)容加到你們的工程中就可以了,如果要使用
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 16 《大家排好隊》(教學(xué)設(shè)計)2024-2025學(xué)年統(tǒng)編版(2024)小學(xué)道德與法治一年級上冊
- 云南科技信息職業(yè)學(xué)院《文學(xué)作品與影視改編》2023-2024學(xué)年第二學(xué)期期末試卷
- 臨沂職業(yè)學(xué)院《交通大數(shù)據(jù)分析與處理》2023-2024學(xué)年第二學(xué)期期末試卷
- 河南2025年河南省委黨校省直分校招聘博士研究生2人筆試歷年參考題庫附帶答案詳解
- 遼寧裝備制造職業(yè)技術(shù)學(xué)院《水質(zhì)監(jiān)測與實驗》2023-2024學(xué)年第二學(xué)期期末試卷
- 洛陽師范學(xué)院《運(yùn)動技能學(xué)習(xí)與控制》2023-2024學(xué)年第二學(xué)期期末試卷
- 2025年度文化活動場地租賃合同規(guī)范文本
- 監(jiān)理機(jī)構(gòu)職責(zé)
- 小數(shù)的意義二(教學(xué)設(shè)計)-2023-2024學(xué)年四年級下冊數(shù)學(xué)北師大版
- 2025年度文化產(chǎn)業(yè)反擔(dān)保保證合同及文化產(chǎn)業(yè)發(fā)展規(guī)劃
- 《電力建設(shè)工程施工安全管理導(dǎo)則》(NB∕T 10096-2018)
- 2024-2025學(xué)年廣東省部分學(xué)校高一(上)第一次聯(lián)合考試物理試卷(含答案)
- 《黃色新聞的泛濫》課件
- 2024年山東省公務(wù)員考試《行測》真題及答案解析
- 化工原理Ⅱ?qū)W習(xí)通超星期末考試答案章節(jié)答案2024年
- 2024-2025學(xué)年初中體育與健康九年級全一冊人教版(2024)教學(xué)設(shè)計合集
- 環(huán)保產(chǎn)業(yè)政策及市場發(fā)展趨勢分析研究
- 2024年河南省高考對口升學(xué)語文英語試題
- 學(xué)習(xí)白求恩精神,做一個高尚的人一個純潔的人
- 《中醫(yī)藥學(xué)概論》期末考試復(fù)習(xí)題庫(含答案)
- 2024年秋季新外研版三年級上冊英語課件 Unit 1 第1課時(Get ready)
評論
0/150
提交評論