新聞中心
News Center
首頁  >  新聞中心  >  技術文章
STM32單片機寄存器的位置是如何定義的

一直都是用STM32做項目中的主控芯片,在編程的時候,之前一直忽視了一個(ge) 問題,那就是寄存器的位置是如何定義(yi) 的,為(wei) 什麽(me) 用一個(ge) USART1-》CR操作就能夠給這個(ge) CR寄存器賦值?其實這是一個(ge) 比較底層的問題,不懂這方麵的知識也並不影響使用STM32,因為(wei) 底層的定義(yi) 工作,廠家一般都會(hui) 做好,但是多了解一點原理性的東(dong) 西,對自己還是很有幫助的。

這裏我就以STM32F407的USART寄存器為(wei) 例,介紹一下ST廠家是如何做寄存器定義(yi) 的。

 

首先在stm32f4xx.h中

typedefstruct

{

__IOuint16_tSR;/*!

uint16_tRESERVED0;/*!

__IOuint16_tDR;/*!

uint16_tRESERVED1;/*!

__IOuint16_tBRR;/*!

uint16_tRESERVED2;/*!

__IOuint16_tCR1;/*!

uint16_tRESERVED3;/*!

__IOuint16_tCR2;/*!

uint16_tRESERVED4;/*!

__IOuint16_tCR3;/*!

uint16_tRESERVED5;/*!

 

__IOuint16_tGTPR;/*!

uint16_tRESERVED6;/*!

}USART_TypeDef;

這是因為(wei) USART的寄存器組包括SR,DR,BRR,CR1,CR2,CR3,GPTR這幾個(ge) 寄存器,所以用一個(ge) USART_TypeDef結構體(ti) 包含這些寄存器。如果在別的程序中用到這些寄存器,隻需要如下:

USART_TypeDefUSART1//任意取名,盡量與(yu) Datasheet中給出的名字一致便於(yu) 理解

USART1.SR=0x00000001;

或者

USART_TypeDef*USART1

USART1-》SR=0x00000001;

(*USART1).SR=0x00000011;

那麽(me) 具體(ti) 到各個(ge) 寄存器的位置到底是怎樣的呢?從(cong) Datasheet和reference manual中可以看到

USART2屬於(yu) APB1管理的外設,起始地址是0x4000 4400,STM32上所有的外設的基地址都是0x4000 0000(這其實是ARM公司規定的),這也是APB1的起始地址,然後USART2的起始地址在APB1外設基地址的基礎上偏移0x4400,於(yu) 是便可以按照下麵代碼來分配各個(ge) 外設的起始地址了

#definePERIPH_BASE((uint32_t)0x40000000)

/*!

/*!

#defineAPB1PERIPH_BASEPERIPH_BASE

#defineUSART2_BASE(APB1PERIPH_BASE+0x4400)

#defineUSART3_BASE(APB1PERIPH_BASE+0x4800)

#defineUART4_BASE(APB1PERIPH_BASE+0x4C00)

#defineUART5_BASE(APB1PERIPH_BASE+0x5000)

#defineUSART2((USART_TypeDef*)USART2_BASE)

#defineUSART3((USART_TypeDef*)USART3_BASE)

#defineUART4((USART_TypeDef*)UART4_BASE)

#defineUART5((USART_TypeDef*)UART5_BASE)

有了這些外設的基地址,加上上麵提到的寄存器結構體(ti) ,便可以操作各個(ge) 寄存器了,例如,隻需要如下語句,便可以使能USART2

USART_Cmd(USART2,ENABLE);

USART_Cmd這是ST官方給出的庫函數,具體(ti) 定義(yi) 如下

voidUSART_Cmd(USART_TypeDef*USARTx,FunctionalStateNewState)

{

/*Checktheparameters*/

assert_param(IS_USART_ALL_PERIPH(USARTx));

assert_param(IS_FUNCTIONAL_STATE(NewState));

if(NewState!=DISABLE)

{

/*EnabletheselectedUSARTbysetTIngtheUEbiTIntheCR1register*/

USARTx-》CR1|=USART_CR1_UE;

}

else

{

/*DisabletheselectedUSARTbyclearingtheUEbiTIntheCR1register*/

USARTx-》CR1&=(uint16_t)~((uint16_t)USART_CR1_UE);

}

}

如果理解了上述所講的內(nei) 容,你會(hui) 發現,這種通過結構體(ti) 定義(yi) 寄存器的方法非常常見,這是因為(wei) 現在的處理器,各種寄存器相當多(成百上千),如果按照傳(chuan) 統的定義(yi) 方法去操作寄存器,會(hui) 相當的麻煩。不隻是STM32,我知道的有TI的C2000係列DSP,NXP的ARM係列MCU,瑞薩的ARM R4 RZ/T1處理器都是按這樣的方法來定義(yi) 寄存器。(轉自電子產(chan) 品世界)