由於stm32有很多外設,為降低功耗,每個外設都對應着一個時鍾。在芯片剛剛上電時,這些時鍾都是被關閉的。如果想要外設工作,必須把相應的時鍾打開。
即當GPIO口復用USART進行通訊時,必須要先使能GPIO的時鍾,然后再使能具體外設的時鍾(USART的時鍾)!!!
1. stm32單片機的I/O端口配置步驟:
(1)GPIOx端口定義
(2)GPIO_Pin_x管腳定義
(3)GPIO_InitTypeDef初始化端口參數定義
(4)GPIO_Init初始化端口定義
每個GPIOx端口:共有7個設置寄存器
(1)兩個32位的配置寄存器(GPIOx_CRL, GPIOx_CRH)
(GPIOx_CRL)(x=A....G): GPIOx configuration register low, GPIOx端口低配置寄存器,用於配置GPIOx端口的第0位~第7位。
(GPIOx_CRH)(x=A....G): GPIOx configuration register high, GPIOx端口高配置寄存器,用於配置 GPIOx端口的第8位~第16位。
(2)兩個32位的數據寄存器(GPIOx_IDR, GPIOx_ODR)
(GPIOx_IDR)(x=A....G): GPIOx input data register, GPIOx輸入數據寄存器,讀出對應I/O口輸入的狀態值。
(GPIOx_ODR)(x=A....G): GPIOx output data register, GPIOx輸出數據寄存器,讀出對應I/O口輸出的狀態值。
(3)一個32位的置位/復位寄存器(GPIOx_BSRR)
(GPIOx_BSRR)(x=A...G): GPIOx bit set/reset register 用於設置端口的電平
(4)一個16位的復位寄存器(GPIOx_BRR):清除端口x的某位值
(5)一個32位的鎖定寄存器(GPIOx_LCKR): (GPIOx_LCKR)(x=A...G): GPIOx configuration lock register, 用於寄存器鎖定端口位的配置。
3. 在固件庫函數文件中,用結構體GPIO_TypeDef定義GPIOx端口:
typedef struct { uint32_t CRL; uint32_t CRH; uint32_t IDR; uint32_t ODR; uint32_t BSRR; uint32_t BRR; uint32_t LCKR; }GPIO_TypeDef; //用結構體GPIO_TypeDef定義GPIOx端口,(即定義GPIOx端口的7個設置寄存器)
4. 編程時,GPIOx端口的具體配置是從GPIOA/GPIOB/GPIOC/GPIOD/GPIOE寄存器開始。
首先,在固件庫中用結構體GPIO_TypeDef定義GPIOx端口,(即定義GPIOx端口的7個設置寄存器):
5. GPIO_Init初始化端口定義
功能:根據GPIO_InitTypeDef中指定的參數,初始化外設GPIOx端口
函數名 | GPIO_Init |
函數原型 | void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct) |
功能 | 根據GPIO_InitStruct中指定的參數初始化外設GPIOx寄存器 |
輸入參數1 | GPIOx: x可以是A,B,C,D,E,來選擇GPIO外設 |
輸入參數2 | GPIO_InitStruct: 指向結構體GPIO_InitTypeDef的指針,包含外設GPIO的配置信息 |
輸出參數 | 無 |
返回值 | 無 |
先決條件 | 無 |
被調用函數 | 無 |
例如,GPIO_InitTypeDef GPIO_InitStructure; //定義結構體變量GPIO_InitStructure用於初始化GPIOx端口參數;GPIO_Init(GPIOx, &GPIO_InitStructure); //初始化GPIOx端口。
6. NRZ碼
NRZ碼是單極性不歸零碼,是最基本的數字基帶編碼。
編碼規則:用高電平表示基帶中的“1”, 低電平表示基帶中的“0”;
7. stm32串口復用功能使用
(1)配置時鍾,由於使用串口是在復用IO口,需要打開串口時鍾和相應的IO口時鍾。
(2)配置IO口,串口相應的IO口需要配置,輸出口配置成復用推挽輸出,輸出口速度根據需要配置,輸入口配 置為浮空輸入。
(3)配置串口,主要是包括波特率、數據長度、停止位、奇偶校驗、硬件流控制、接收發送模式。
(4)打開串口
串口配置程序 配置PA9, PA10為USART1的發送和接收口 void Config_Usart1(void) { GPIO_InitTypeDef GPIO_InitStructure; /*定義GPIO初始化結構體變量*/ USART_InitTypeDef USART_InitStructure; /*定義USART初始化結構體變量*/ /*配置USART1時鍾,同時打開引腳時鍾和USART1時鍾*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); /*配置USART1的TX(PA9)端口為推挽輸出*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); /*配置USART1的RX(PA10)端口為浮空輸入*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); /*USART1模式配置發送和接收, 波特率115200bps, 無校驗位,不適用硬件流控制*/ USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_9b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_Even; USART_InitStructure.USART_HardwareFlowControl = USART_Mode_Rx|USART_Mode_Tx; /*初始化USART1,打開USART1*/ USART1_Init(USART1, &USART_InitStructure); USART_Cmd(USART1,ENABLE); }
8. GPIO口作為一般輸入輸出口使用時
使用固件庫點亮LED燈
int main(void) { GPIO_InitTypeDef GPIO_InitStructure; /*定義GPIO_InitTypeDef結構體*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); /*開啟GPIO端口時鍾*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; /*選擇要控制的GPIO引腳*/ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /*選擇引腳模式為通用推挽輸出*/ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /*設置引腳速率為50MHz*/ GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_ResetBits(GPIOA,GPIO_Pin_0); while(1) { GPIO_ResetBits(GPIOA,GPIO_Pin_0); /*使引腳輸出低電平,點亮LED燈*/ Delay(0xffff); GPIO_SetBits(GPIOA,GPIO_Pin_0); /*使引腳輸出高電平,熄滅LED燈*/ Delay(0xffff); } }