以STM32F103為例,記錄一下自己對STM32中GPIO初始化的理解:
1 void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
功能描述: 根據GPIO_InitStruct中指定的參數初始化外設GPIOx寄存器
輸入參數1:GPIOx //GPIOx:x 可以是 A,B,C,D 或者 E,來選擇 GPIO 外設
輸入參數2:GPIO_InitStruct //GPIO_InitStruct:指向結構 GPIO_InitTypeDef 的指針,包含了外設 GPIO 的配置信息
如:管腳號,速度,模式等(GPIO_Pin,GPIO_Speed,GPIO_Mode)
參閱 Section:GPIO_InitTypeDef 查閱更多該參數允許取值范圍
GPIO_Init:有二個參數,均為結構體指針,右鍵Go To definition :可以查看函數的定義
/** * @brief General Purpose I/O */ typedef struct { __IO uint32_t CRL; //端口配置低寄存器 __IO uint32_t CRH; //端口配置高寄存器 __IO uint32_t IDR; //端口輸入數據寄存器 __IO uint32_t ODR; //端口輸出數據寄存器 __IO uint32_t BSRR; //端口位設置/復位寄存器 __IO uint32_t BRR; //端口位復位寄存器 __IO uint32_t LCKR; //端口配置鎖定寄存器 } GPIO_TypeDef;
/** * @brief GPIO Init structure definition */ typedef struct { uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured. This parameter can be any value of @ref GPIO_pins_define */ GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins. This parameter can be a value of @ref GPIOSpeed_TypeDef */ GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins. This parameter can be a value of @ref GPIOMode_TypeDef */ }GPIO_InitTypeDef;
函數原型如下:
1 /** 2 * @brief Initializes the GPIOx peripheral according to the specified 3 * parameters in the GPIO_InitStruct. 4 * @param GPIOx: where x can be (A..G) to select the GPIO peripheral. 5 * @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that 6 * contains the configuration information for the specified GPIO peripheral. 7 * @retval None 8 */
9 void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct) 10 { 11 uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00; 12 uint32_t tmpreg = 0x00, pinmask = 0x00; 13 /* Check the parameters */
14 assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); 15 assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode)); 16 assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin)); 17
18 /*---------------------------- GPIO Mode Configuration -----------------------*/
19 currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F); 20 if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00) 21 { 22 /* Check the parameters */
23 assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed)); 24 /* Output mode */
25 currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed; 26 } 27 /*---------------------------- GPIO CRL Configuration ------------------------*/
28 /* Configure the eight low port pins */
29 if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00) 30 { 31 tmpreg = GPIOx->CRL; 32 for (pinpos = 0x00; pinpos < 0x08; pinpos++) 33 { 34 pos = ((uint32_t)0x01) << pinpos; 35 /* Get the port pins position */
36 currentpin = (GPIO_InitStruct->GPIO_Pin) & pos; 37 if (currentpin == pos) 38 { 39 pos = pinpos << 2; 40 /* Clear the corresponding low control register bits */
41 pinmask = ((uint32_t)0x0F) << pos; 42 tmpreg &= ~pinmask; 43 /* Write the mode configuration in the corresponding bits */
44 tmpreg |= (currentmode << pos); 45 /* Reset the corresponding ODR bit */
46 if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD) 47 { 48 GPIOx->BRR = (((uint32_t)0x01) << pinpos); 49 } 50 else
51 { 52 /* Set the corresponding ODR bit */
53 if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU) 54 { 55 GPIOx->BSRR = (((uint32_t)0x01) << pinpos); 56 } 57 } 58 } 59 } 60 GPIOx->CRL = tmpreg; 61 }
下面我門以初始化
#define LED_G_GPIO_PIN GPIO_Pin_0
#define LED_G_GPIO_PORT GPIOB
#define LED_G_GPIO_CLK RCC_APB2Periph_GPIOB
void LED_GPIO_Config(void) {
/*定義一個 GPIO_InitTypeDef 類型的結構體*/ GPIO_InitTypeDef GPIO_InitStruct;
/*開啟 LED 相關的 GPIO 外設時鍾*/ RCC_APB2PeriphClockCmd(LED_G_GPIO_CLK, ENABLE);
/*選擇要控制的 GPIO 引腳*/
GPIO_InitStruct.GPIO_Pin = LED_G_GPIO_PIN;
/*設置引腳模式為通用推挽輸出*/
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
/*設置引腳速率為 50MHz*/ GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; /*調用庫函數,初始化 GPIO*/ GPIO_Init(LED_G_GPIO_PORT, &GPIO_InitStruct);
/*設置初始狀態為 SetBits 關閉LED燈(低電平點亮)*/
GPIO_SetBits(LED1_GPIO_PORT, LED1_GPIO_PIN);
}
難點就是函數種運用了結構體指針:
下面我們來學習一下C語言中的結構體
1. 什么是結構體?
結構體是一種工具,用這個工具可以定義自己的數據類型
2. 結構體與數組的比較
(1) 都由多個元素組成
(2) 各個元素在內存中的存儲空間是連續的
(3) 數組中各個元素的數據類型相同,而結構體中的各個元素的數據類型可以不相同
3. 結構體的定義和使用
1>:一般形式
struct 結構體名 { 類型名1 成員名1; 類型名2 成員名2; 類型名n 成員名n; }; struct student { char name[10]; char sex; int age; float score; };
//student 為結構體類型名
2>:定義結構體類型的變量,指針變量和數組
方法一:定義結構體類型時,同時定義該類型的變量
struct [student] /* [ ]表示結構體名是可選的 */ { char name[10]; char sex; int age; float score; }stu1, *ps, stu[5]; /* 定義結構體類型的普通變量、指針變量和數組 */
方法二:先定義結構體類型,再定義該類型的變量
struct student { char name[10]; char sex; int age; float score; }; struct student stu1, *ps, stu[5]; /* 定義結構體類型的普通變量、指針變量和數組 */
方法三:用類型定義符typedef先給結構體類型命別名,再用別名定義變量
typedef struct [student] { char name[10]; char sex; int age; float score; }STU; STU stu1, *ps, stu[5]; /* 用別名定義結構體類型的普通變量、指針變量和數組 */
//注釋:typedef
3:> 給結構體變量賦初值
struct [student] { char name[10]; char sex; int age; float score; }stu[2]={{"Li", 'F', 22, 90.5}, {"Su", 'M', 20, 88.5}};
4:>引用結構體變量中的成員
1) 結構體變量名. 成員名: stu1.name 2) 結構體指針變量->成員名: ps->name 3) (*結構體指針變量). 成員名: (*ps).name 4) 結構體變量數組名. 成員名: stu[0].name
先寫到這里 下次再補充