暫存器顧名思義就是可以存放資料的地方,那也就是記憶體的一種囉? 記憶體Block2這塊區域用來設計單晶片上的外設,他們以4個word為一個單元,共32位(STM32的資料匯流排寬度為32位,因此理當以32位做為一個暫存器),每一個單元對應到不同的功能,只要我們控制這些單元就可以改變外設的行為。
這時就顯現C語言的好處了,我們可以直接利用指標的方式操作這些單元,但如果每次都是用指標的方式,不僅程式碼難以閱讀,每次寫程式的時候還要去翻閱資料,看某一個單元的地址為何。因此我們會以功能來命名這些記憶體,這個別名就是我們常說的暫存器,而將已配好地址、有特定功能的記憶體取別名的過程就叫做暫存器映射
https://github.com/Meta-Team/Datasheets/blob/master/STM32F4/STM32F4xx%E4%B8%AD%E6%96%87%E5%8F%82%E8%80%83%E6%89%8B%E5%86%8C.pdf
這裡可以下載《STM32F4xx中文參考手冊》,裡面詳細介紹了STM32F4的暫存器每個bit代表什麼以及使用方式。
單晶片上外設分為4條總線,根據外設速度不同,不同匯流排掛載著不同的外設,APB掛載低速設備,AHB掛載高速設備,每一個匯流排的最低地址被稱為該匯流排的基地址。
匯流排上掛載著各種外設,這些外設也有自己的地址範圍,特定外設的首個地址稱為XX外設機地址,這些在《STM32F4xx中文參考手冊》都有詳細的介紹,這裡我們以GPIO來講解。
外設名稱 | 外設基地址 | 相對AHB1匯流排的地址偏移 |
---|---|---|
GPIOA | 0x4002 0000 | 0x0 |
GPIOB | 0x4002 0400 | 0x0000 0400 |
GPIOC | 0x4002 0800 | 0x0000 0800 |
GPIOD | 0x4002 0C00 | 0x0000 0C00 |
GPIOE | 0x4002 1000 | 0x0000 1000 |
GPIOF | 0x4002 1400 | 0x0000 1400 |
GPIOG | 0x4002 1800 | 0x0000 1800 |
GPIOH | 0x4002 1C00 | 0x0000 1C00 |
從上表我們可以看到GPIOA的基地址相對於AHB1匯流排的地址偏移為0,也就是AHB1的第一個外設就是GPIOA |
處於XX外設的地址範圍內的就是該外設的暫存器。以GPIO外設為例,GPIO有很多暫存器,每一個都有特定的功能。每個暫存器為32位,在該外設的基地址上按照順序排列,暫存器的位置都以相對於外設基地址的偏移來描述。這裡以GPIOH端口為例,來了解GPIO實際上到底有那些暫存器。
暫存器名稱 | 暫存器地址 | 相對GPIOH基地址的偏移 |
---|---|---|
GPIOH_MODER | 0x4002 1C00 | 0x00 |
GPIOH_OTYPER | 0x4002 1C04 | 0x04 |
GPIOH_OSPEEDR | 0x4002 1C08 | 0x08 |
GPIOH_PUPDR | 0x4002 1C0C | 0x0C |
GPIOH_IDR | 0x4002 1C10 | 0x10 |
GPIOH_ODR | 0x4002 1C14 | 0x14 |
GPIOH_BSRR | 0x4002 1C18 | 0x18 |
GPIOH_LCKR | 0x4002 1C1C | 0x1C |
GPIOH_AFRL | 0x4002 1C20 | 0x20 |
GPIOH_AFRH | 0x4002 1C24 | 0x24 |
有關各個暫存器的說明都可以在《STM32F4xx中文參考手冊》中暫存的部分找到,這裡我們以GPIO端口置位/復位暫存器為例(GPIOx_BSRR),介紹如何理解暫存器的說明。
上面有關暫存器的內容,只是要幫助大家更好的理解C語言如何控制讀寫暫存器,我們實際上在使用單晶片的時候當然不會直接去操縱那些暫存器,那樣太沒有效率了,明天我們會介紹STM32是如何使用C語言來對暫存器做封裝。