怎麼仿照STM32庫文件來寫STM32驅動文件

1、這天在折騰STM32,看到很多高手寫的一些程序,記錄一下,作爲以後自己編寫高質量軟件代碼的參照,

      (1)    #define   rUTXH0     (*(volatile unsigned char *)0x1d00020)     //代碼

比如這是ARM頭文件中經常看到的宏定義,UTXH0是寄存器, 這個語句具體是什麼意思?以前有過PIC單片機的基礎,在編寫PIC程序的時候 ,比如像讀取給PORTA寄存器賦值,不用任何定義直接 PORTA=XX就可以了,爲什麼在ARM還要這樣定義  而且定義的這麼複雜,爲什麼不能像單片機那樣直接用嗎?

 答案:嵌入式系統編程,要求程序員能夠利用C語言訪問固定的內存地址。不進行宏定義的話就得每次用的時候用地址了,那是麻煩的操作,另外容易把地址搞錯(例如出現的筆誤現象),使用宏定義的話可以直接進行替換,關於這個定義,是個地址,那麼按照C語言的語法規則,這個表示地址的量應該是指針類型,所以,知道要訪問的內存地址後,比如訪問地址爲0x5F,要進行如下的步驟:

第一步:要把它強制轉換爲指針類型----(unsigned char *)0x5F,關於爲什麼是unsigned char類型的,AVRSREG是八位寄存器,所以0x5F強制轉換爲指向unsigned char類型,在STM32中的寄存器是32位的所以要強制轉換爲unsigned long類型的。volatile(可變的)這個關鍵字說明這變量可能會被意想不到地改變,這樣編譯器就不會去假設這個變量的值了(參考STM32 運行機制,是把ROM裏的數據拷貝到RAM中,由於編譯器的優化,有些變量是使用的備份,而不是RAM中的數據,有時候RAM會由於中斷改變數據)。這種意想不到地改變,不是由程序去改變,而是由硬件去改變——意想不到,使用的是ROM中的原始值,

第二步:對指針變量解引用,就能操作指針所指向的地址的內容了,*(volatile unsigned char *)0x5F就是取地址中的內容

第三步:小心地把#define宏中的參數用括號括起來,這是一個很好的習慣,所以#define SREG     (*(volatile unsigned char *)0x5F),類似的,如果使用一個32位處理器,要對一個32位的內存地址進行訪問,可以這樣定義#define RAM_ADDR      (*(volatile unsigned long   *)0x0000555F),然後就可以用C語言對這個內存地址進行讀寫操作了
    
讀:tmp = RAM_ADDR
    
寫:RAM_ADDR = 0x55
#define U0RBR (*((volatile unsigned char *) 0xE000C000))
這個在單片機裏很常見,

((volatile unsigned char *) 0xE000C000) 是將0xE000C000強制轉換爲保存可能隨時更新無符號字符型數據的地址,前面又加了*,是表示指向這個地址裏面的值,這與其他普通定義的指針一樣了,如charx,y,*p;p=&x;*p=y;y=*p就如同一個變量一樣,既可以從這裏讀出值,也可以給被賦值,這裏需要注意的是,這個地址值裏的東西是不是既可以讀又可以寫,這個在datasheet應該有定義,或者看程序中都拿他幹什麼。

#define U0RBR (*((volatile unsigned char *) 0xE000C000)) 這個是宏定義,即UORBR替換(*((volatile unsigned char*) 0xE000C000)),宏定義是爲了程序書寫方便,因爲在程序中可能有好多地方要使用(*((volatile unsigned char*) 0xE000C000)),在用時,總要寫這麼多東西麻煩。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章