目錄
- stm32中斷原理
- 標準庫
- 高低電平使LED亮滅燈
- 采用串口中斷方式做串口通信
stm32中斷原理
在STM32微控制器中,中斷是一種重要的事件驅動機制,用于處理實時事件而無需持續輪詢。中斷在處理外部事件(如按鍵輸入、定時器溢出等)時非常有用。以下是關于STM32中斷的基本原理:
中斷控制器:STM32微控制器內部有一個中斷控制器,負責管理和分配中斷請求。中斷控制器會根據中斷優先級來確定哪個中斷應該被處理。
中斷優先級:每個中斷源都有一個優先級,優先級較高的中斷會在優先級較低的中斷之前得到處理。在STM32中,中斷優先級通常通過NVIC(Nested Vectored Interrupt Controller)進行配置。
中斷向量表:中斷向量表是一個存儲中斷處理函數地址的表格。當發生中斷時,處理器會根據中斷號在中斷向量表中查找對應的中斷處理函數的地址并跳轉執行。
中斷處理流程:當發生中斷時,處理器會立即暫停當前任務,保存當前上下文(如寄存器狀態)并跳轉到中斷處理函數。中斷處理函數執行完畢后,會恢復之前保存的上下文并返回到中斷發生的地方繼續執行。
配置中斷:要在STM32中啟用中斷,通常需要配置相應的中斷優先級、中斷觸發條件以及中斷處理函數。這通常涉及設置相關的寄存器和中斷控制器。
標準庫
在STM32微控制器開發中,標準庫通常指的是STMicroelectronics提供的STM32標準外設庫(Standard Peripheral Library)或者Cube庫(Cube庫是HAL庫的前身,提供了更高級的抽象層)。這些庫提供了一系列函數和驅動程序,用于簡化對STM32外設(如GPIO、UART、SPI等)的控制和配置。
以下是關于STM32標準庫的一些重要信息:
功能:STM32標準庫提供了一組函數,用于配置和控制微控制器的外設。這些函數可以幫助開發者快速編寫代碼,而無需深入了解底層寄存器的操作。
使用:開發者可以通過包含相應的頭文件并調用庫中的函數來使用STM32標準庫。例如,要配置一個GPIO引腳,可以調用庫中提供的函數來設置引腳的模式、速度、上拉/下拉等屬性。
優點:使用STM32標準庫可以簡化開發流程,減少對寄存器級編程的需求,提高代碼的可移植性和可維護性。
替代品:隨著時間的推移,STMicroelectronics逐漸推出了Cube庫(Cube庫包含了HAL庫和LL庫),提供了更高級的抽象層和更豐富的功能。Cube庫通常被認為是標準庫的更先進版本。
高低電平使LED亮滅燈
連接硬件:
將一個LED連接到STM32F103核心板的GPIOA端口的一個引腳(比如PA5)。
將一個開關(用杜邦線模擬)連接到GPIOB端口的一個引腳(比如PB0)。
編寫中斷處理程序:
首先,需要初始化GPIOA和GPIOB端口為輸入和輸出模式,并啟用相應的中斷功能。
然后,編寫中斷處理程序,當檢測到GPIOB端口引腳的狀態改變時,執行相應的操作來控制GPIOA端口引腳的狀態。
編程實現:
在你的STM32F103項目中,你需要設置GPIOA引腳為輸出模式,用于控制LED。設置GPIOB引腳為輸入模式,用于讀取開關狀態。
配置GPIOB引腳的中斷觸發條件,例如上升沿或下降沿觸發中斷。
在中斷服務程序中,讀取GPIOB引腳的狀態,如果檢測到狀態變化,根據開關狀態控制GPIOA引腳來點亮或熄滅LED。
調試和測試:
燒錄程序到STM32F103核心板上,確保硬件連接正確。
測試開關的功能,檢查LED是否根據開關狀態正確亮滅。
采用串口中斷方式做串口通信
分別實現:
(1)當stm32接收到1個字符“s”時,停止持續發送“hello windows!”; 當接收到1個字符“t”時,持續發送“hello windows!”
(2)當stm32接收到字符“stop stm32!”時,停止持續發送“hello windows!”; 當接收到字符“go stm32!”時,持續發送“hello windows!”
代碼:
#include "main.h"
#include "usart.h"
#include "gpio.h"
#include <string.h>void SystemClock_Config(void);char c;//指令 0:停止 1:開始
char message[]="hello Windows\n";//輸出信息
char tips[]="CommandError\n";//提示1
char tips1[]="Start.....\n";//提示2
char tips2[]="Stop......\n";//提示3
int flag=0;//標志 0:停止發送 1.開始發送int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_USART1_UART_Init();//設置接受中斷HAL_UART_Receive_IT(&huart1, (uint8_t *)&c, 1);//當flag為1時,每秒發送一次信息//當flag為0時,停止while (1){if(flag==1){//發送信息HAL_UART_Transmit(&huart1, (uint8_t *)&message, strlen(message),0xFFFF); //延時HAL_Delay(1000);}}
}void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{//當輸入的指令為0時,發送提示并改變flagif(c=='s'){flag=0; }//當輸入的指令為1時,發送提示并改變flagelse if(c=='t'){flag=1; }//當輸入不存在指令時,發送提示并改變flagelse {flag=0;HAL_UART_Transmit(&huart1, (uint8_t *)&tips, strlen(tips),0xFFFF); }//重新設置中斷HAL_UART_Receive_IT(&huart1, (uint8_t *)&c, 1);
}
/* USER CODE END 4 */
/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}
編譯沒有錯誤后,進行燒錄就完了。