前言
上一節我們講解了STM32CubeMX的基本使用和工程的配置,那么這一節我們正式來學習CubeMX配置STM32的各個外設功能了
今天我們會詳細的帶你學習STM32CubeMX配置外部中斷,并且講解HAL庫的GPIO的各種函數,帶你學習不一樣的STM32
那么話不多說,我們開始正式的講解吧!
準備工作:
1、STM32開發板(我的是STM32F407ZE和STM32F103RC)
2、STM32CubeMx軟件、 IDE:?Keil軟件
3、STM32F1xx/STM32F4xxHAL庫
4、按鍵管腳? PA11? PB4
5? ?LED管腳 PC4 PC5 PB0 PB1
1新建工程
1.1New Project
1 搜索芯片型號
2選擇芯片
3創建工程
1.2設置RCC
1 點擊RCC
2高速時鐘(HSE)選擇外部晶振
3 軟件自動配置管腳
1.3GPIO初始化
LED:4個GPIO_OUTPUT (輸出模式)
按鍵:2個GPIO_EXITx(外部中斷模式)
1 點擊對應管腳
2 設置對應模式
GPIO的各種模式設置
GPIO output level? ?引腳電平設置? ?高/低
GPIO mode? ?GPIO模式? ? ?推挽輸出/開漏輸出
GPIO Pull-up/Pull-dowm? ?上拉下拉電阻? ? ??上拉電阻/下拉電阻/無上拉或下拉
Maxinum output speed? ?引腳速度設置? ?低速/中速/高速
User Label? ? 用戶標簽? ?給引腳設置名稱? 如LED0
這里可以看出看和我們使用庫函數的時候配置是一樣的,但我們只需要動幾下鼠標便可以完成操作,這正是STM32CubeMX的強大之處
GPIO_EXIT的6種模式
我們的按鍵選擇下降沿觸發
1.4設置NVIC(嵌套向量中斷控制器)
1點擊NVIC2 勾選EXIT Line
2 interrupt 和 EXIT Line[15:12] interrupt 使能中斷
1.5時鐘源設置
1選擇外部時鐘HSE 8MHz
2PLL鎖相環倍頻9倍
3系統時鐘來源選擇為PLL
4設置APB1分頻器為 /2
1 設置項目名稱
2 設置存儲路徑
3 選擇所用IDE
1.7創建工程文件
然后點擊GENERATE CODE??創建工程
隨后我們可以在stm32f1xx_it.c中看到我們所配置的中斷服務函數? 并且可以看到gpio的初始化分到了gpio.c里面
、
我們看到他有一個HAL_GPIO_EXTI_IRQHandler();函數
Go To Definition 查看一下函數代碼
和我們庫函數配置差不多,就是清除中斷標志位,之后進入中斷回調函數中
在HAL庫中,中斷運行結束后不會立刻退出,而是會先進入相對應的中斷回調函數,處理該函數中的代碼之后,才會退出中斷,所以在HAL庫中我們一般將中斷需要處理代碼放在中斷回調函數中,
配置下載工具
新建的工程所有配置都是默認的? 我們需要自行選擇下載模式,勾選上下載后復位運行
所有自己編寫的代碼請放在/* USER CODE BEGIN XXX */ ? /* USER CODE END XXX */之間
這樣我們修改工程的時候你自己寫的代碼就不會被刪除
HAL庫 GPIO函數庫講解
在正常使用中,除了STM32CubeMX配置之外,我們有時候還需要自己配置一些東西,學習并理解HAL庫,也是我們必須要學習的一個地方
首先打開stm32f4xx_hal_gpio.h? 發現一共定義有8個函數
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);
void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin);
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);
功能: GPIO初始化
實例:HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin);
功能:在函數初始化之后的引腳恢復成默認的狀態,即各個寄存器復位時的值
實例:HAL_GPIO_Init(GPIOC, GPIO_PIN_4);
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
功能:讀取引腳的電平狀態、函數返回值為0或1
實例:HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4);
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
功能:引腳寫0或1
實例:HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4,0);
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
翻轉引腳的電平狀態
實例:HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_4);? ? 常用在LED上
HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
功能:鎖住引腳電平,比如說一個管腳的當前狀態是1,當這個管腳電平變化時保持鎖定時的值。
實例:HAL_GPIO_LockPin(GPIOC, GPIO_PIN_4);
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);
功能:? 外部中斷服務函數,清除中斷標志位
實例:HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
功能:? 中斷回調函數,可以理解為中斷函數具體要響應的動作。
實例:HAL_GPIO_EXTI_Callback(GPIO_PIN_4);
GPIO_InitTypeDef結構體定義
typedef struct
{
uint32_t Pin;? ? ? ?/*!
*/
uint32_t Mode;? ? ? /*!< 設置引腳模式
*/
uint32_t Pull;? ? ? /*!< 引腳是否上拉或下拉
*/
uint32_t Speed;? ? ?/*!< 設置引腳速度
*/
} GPIO_InitTypeDef;
同時,不管是標準庫還是HAL庫,都是基于寄存器開發的,寄存器編程在哪個庫都是適用的
GPIO的相關配置寄存器
STM32的每組GPIO口包括7個寄存器。也就是說,每個寄存器可以控制一組GPIO的16個GPIO口。這7個寄存器分別為:
GPIOx_CRL:端口配置低寄存器(32位)
GPIOx_CRH:端口配置高寄存器(32位)
GPIOx_IDR:端口輸入寄存器(32位)
GPIOx_ODR:端口輸出寄存器(32位)
GPIOx_BSRR:端口位設置/清除寄存器(32位)
GPIOx_BRR:端口位清除寄存器(16位)
GPIOx_LCKR:端口配置鎖存寄存器(32位)
具體我們這里就不講了,篇幅有限,可以到《STM32中文參考手冊》中查看
關于GPIO的八種模式請參看 《STM32 GPIO八種模式及工作原理詳解》
按鍵消抖:
/**
* 函數功能: 按鍵外部中斷回調函數
* 輸入參數: GPIO_Pin:中斷引腳
* 返 回 值: 無
* 說? ? 明: 無
*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin==KEY1_GPIO_PIN)
{
HAL_Delay(20);/* 延時一小段時間,消除抖動 */
if(HAL_GPIO_ReadPin(KEY1_GPIO,KEY1_GPIO_PIN)==KEY1_DOWN_LEVEL)
{
BEEP_TOGGLE;
LED1_ON;
LED2_ON;
LED3_ON;
}
__HAL_GPIO_EXTI_CLEAR_IT(KEY1_GPIO_PIN);
}
else if(GPIO_Pin==KEY2_GPIO_PIN)
{
HAL_Delay(20);/* 延時一小段時間,消除抖動 */
if(HAL_GPIO_ReadPin(KEY2_GPIO,KEY2_GPIO_PIN)==KEY2_DOWN_LEVEL)
{
BEEP_TOGGLE;
LED1_OFF;
LED2_OFF;
LED3_OFF;
}
__HAL_GPIO_EXTI_CLEAR_IT(KEY2_GPIO_PIN);
}
}