MX_GPIO_Init分析源碼如下:
__HAL_RCC_GPIOE_CLK_ENABLE源碼如下:
#define RCC ((RCC_TypeDef *) RCC_BASE)
#define RCC_BASE (AHB1PERIPH_BASE + 0x3800UL)
#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000UL)
#define PERIPH_BASE 0x40000000UL
// 可以看到最后RCC地址為 0x40000000UL + 0x00020000UL + 0x3800UL,即0x40023800
我們從數據手冊的寄存器地址映射也可以看到RCC地址確實是0x40023800
RCC_TypeDef
結構體描述如下:
我們查看參考文檔
可以發現這里的寄存器是跟參考文檔一樣按照順序排列,每個寄存器32位4字節。
其中RCC->AHB1ENR
地址應該為0x40023800+0x30
,而RCC_AHB1ENR_GPIOEEN
為0x1UL<<4U
,即0x1<<4
,在位4,通過查文檔,可以看到GPIOEEN確實在位4。
這里SET_BIT為REG |= BIT,即*(0x40023800+0x30) |= (0x1<<4);
,可以看到通過或運算將RCC->AHB1ENR
寄存器的RCC_AHB1ENR_GPIOEEN
位設置為1,而不影響其他位,即開啟了對應寄存器的時鐘功能;
這里READ_BIT為REG & BIT,即(0x40023800+0x30) & (0x1<<4);
,可以看到通過與運算將RCC->AHB1ENR
寄存器的RCC_AHB1ENR_GPIOEEN
位讀取出來,而不讀取其他位,即讀取對應寄存器的時鐘開啟狀態功能;
UNUSED
這里就做了強轉,避免編譯器提示變量未使用;
至此,MX_GPIO_Init
函數分析完畢,即開啟對應GPIO時鐘,然后對GPIO做些初始化。最重要的在于通過或運算向寄存器指定位寫入值,通過與運算讀取寄存器指定位的值。