學習STM32時,首先要熟悉流水燈例程,在這里就來分析流水燈中的GPIO_Init()函數(shù)
例如:流水燈例程中使用的端口是macLED1_GPIO_PORT=GPIOB,
控制的引腳是GPIO_Pin_0,
引腳的模式是GPIO_Mode_Out_PP(通用推挽輸出),
引腳的速率是GPIO_Speed_50MHz,
用到的寄存器是CRL
將上述的引腳、模式、速率換算成32位的16進制,分別是:
1)控制的引腳是GPIO_Pin_0
換算成32位的16進制是:0x0000 0001
2)引腳的模式是GPIO_Mode_Out_PP(通用推挽輸出)
換算成32位的16進制是:0x0000 0010
3)引腳的速率是GPIO_Speed_50MHz
換算成32位的16進制是:0x0000 0003
然后調用庫函數(shù)GPIO_Init(),初始化GPIOB
GPIO_Init(macLED1_GPIO_PORT, &GPIO_InitStructure);
GPIO_Init()函數(shù)的定義如下:
GPIO Mode Configuration
currentmode=((uint32_t)GPIO_InitStruct-》GPIO_Mode)&((uint32_t)0x0F);
可以得出currentmode=0x0000 0010 & 0x0000 000F
=0x0000 0000
if ((((uint32_t)GPIO_InitStruct-》GPIO_Mode) & ((uint32_t)0x10)) != 0x00)
判斷是否是輸出模式,“是”,執(zhí)行下面代碼;“否”,不執(zhí)行
如:0x0000 0010 & 0x0000 00010 !=0x 0000 0000
則執(zhí)行下面語句
{
/* Output mode */
currentmode “= (uint32_t)GPIO_InitStruct-》GPIO_Speed;
可以得出currentmode=currentmode | 0x0000 0003=0x0000 0000
=0x0000 0003
}
GPIO CRL Configuration
if(((uint32_t)GPIO_InitStruct-》GPIO_Pin&((uint32_t)0x00FF)) != 0x00)
判斷是否是Pin0~Pin7引腳,“是”,執(zhí)行下面代碼;“否”,不執(zhí)行
如:0x0000 0001 & 0x 0000 00FF != 0x0000 0000
則執(zhí)行下面語句
{
tmpreg = GPIOx-》CRL;
備份原CRL寄存器的值
則是:tmpreg=0x4444 4444
for (pinpos = 0x00; pinpos 《 0x08; pinpos++)
{
pos = ((uint32_t)0x01) 《《 pinpos;
pos是0x0000 0001左移 pinpos 位得到的
如:pos=0x0000 0001 《《 0x00
= 0x0000 0001
為后面的if (currentpin == pos) 判斷作準備
/* Get the port pins position */
currentpin = (GPIO_InitStruct-》GPIO_Pin) & pos;
可得currentpin= 0x0000 0001 & 0x0000 0001
=0x0000 0001
為后面的if (currentpin == pos) 判斷作準備
if (currentpin == pos)
由上面得出的pos = 0x0000 0001
currentpin = 0x0000 0001
兩者相等,則執(zhí)行下面代碼語句
{
pos = pinpos 《《 2;
可得pos= 0x0000 0000 《《 2
=0x 0000 0000
/* Clear the corresponding low control register bits */
pinmask = ((uint32_t)0x0F) 《《 pos;
可得pinmask=0x0000 000F 《《 0x0000 0000
= 0x0000 000F
tmpreg &= ~pinmask;
可得tmpreg= tmpreg & ~pinmask
= 0x4444 4444 & 0xFFFF FFF0
= 0x4444 4440
/* Write the mode configuration in the corresponding bits */
tmpreg |= (currentmode 《《 pos);
首先,要知道currentmode 《《 pos = 0x0000 0003 《《 0x 0000 0000
= 0x 0000 0003
可得tmpreg= tmpreg | 0x0000 0003
= 0x4444 4440 & 0x0000 0003
= 0x4444 4443
/* Reset the corresponding ODR bit */
if (GPIO_InitStruct-》GPIO_Mode == GPIO_Mode_IPD)
判斷是否為下拉輸入模式
{
GPIOx-》BRR = (((uint32_t)0x01) 《《 pinpos);
}
else
{
/* Set the corresponding ODR bit */
if (GPIO_InitStruct-》GPIO_Mode == GPIO_Mode_IPU)
判斷是否為上拉輸入模式
{
GPIOx-》BSRR = (((uint32_t)0x01) 《《 pinpos);
}
}
結果,兩種輸入模式都不是,而是通用推挽輸出,所以不執(zhí)行
}
}
GPIOx-》CRL = tmpreg;
把前面處理后的暫存值寫入到CRL寄存器之中
也就是GPIOx-》CRL= 0x4444 4443
}
最終,向GPIOB組的CRL寄存器寫入一個值:
GPIOx-》CRL = 0x4444 4443
轉換為二進制是:(0100 0100 0100 0100 0100 0100 0100 0011)B
因此,Pin0的控制值為(0011)B
下面是CRL寄存器的說明
對比一下CRL寄存器的說明,Pin0的控制值正好可以把GPIO設置為符合我們輸入參數(shù)要求的狀態(tài),即最大速率為50MHz的通用推挽輸出模式。
評論
查看更多