STM32单片机裸机程序-高级实现实时性处理方法
概述
? ? ? ? 這篇文章是對剛剛學習單片機的小伙伴們,提的一些處理技巧思維。(我在項目上經常使用這樣的處理思路)
現在舉個栗子,應用場景是這樣的,比如:在while(1)中在處理一些裸機,然后碰巧又在延時時候,當你又有其他事件(這個事件是外部觸發而來的)比較緊急要處理這個事件時,這時候,CUP肯定是處理不來,需要等待while(1)處理完延時之后,才能處理這個比較緊急的事件,這時候,可能有人會說,你干嘛不在外部中斷去處理這個事件呢,但是如果這個事件剛好也要延時呢?怎么辦,一般好的程序不會在中斷函數里面使用過多的延時,還有很多邏輯的事件,這時候就要換一種處理思維了。哈哈,想必大家也會想到它,那就是定時器,如果這時候使用定時器的話,問題肯定能處理的比在while(1)的大循環干等待延時要強的多,完美的組合就是,要中斷與定時器搭配來使用才行,這樣的處理事件就不會因為延時邏輯過長導致其它事件處理不及時的問題。(廢話有點多,請諒解)
1、打個比方:我的項目上有關機功能
2、首先配置一個單獨的定時器(我這里配置的是 基本定時器6,注意:如果Tim不夠用的話,可以使用SysTick_Handler/滴答定時器代替,使用方法同理。)
3、該定時專門處理這個關機邏輯的,這時根據自己的需求修改定時器的頻率
tim.c 文件
/* USER CODE BEGIN 0 */ #include "adc.h"extern void Power_OFF(void); /* USER CODE END 0 */ . . ./* USER CODE BEGIN 1 */void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {if(htim->Instance == TIM2){#ifdef TIMER_SAMPLING_MODEget_ADC_Channel_Val();#endif}else if(htim->Instance == TIM6){//編寫回調邏輯,即定時器6定時1000us后的邏輯 1ms=1次Power_OFF();} }/* USER CODE END 1 */Power_OFF()函數:
void Power_ON(void) {uint32_t tickstart = HAL_GetTick();while(1){//讀Power_on是否是高電平if(HAL_GPIO_ReadPin(POWER_OFF_GPIO_Port,POWER_OFF_Pin)==GPIO_PIN_SET){if((HAL_GetTick() - tickstart) >= 3000) //如果大于3s{g_powerON_flag = 1;HAL_GPIO_WritePin(POWER_ON_GPIO_Port,POWER_ON_Pin,GPIO_PIN_SET); //開機HAL_GPIO_WritePin(MOT_EN_GPIO_Port,MOT_EN_Pin,GPIO_PIN_SET); //MOT_ONHAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_SET); //LED_ONHAL_Delay(500); HAL_GPIO_WritePin(MOT_EN_GPIO_Port,MOT_EN_Pin,GPIO_PIN_RESET); //MOT_OFFHAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_RESET); //LED_OFFHAL_Delay(500); HAL_GPIO_WritePin(MOT_EN_GPIO_Port,MOT_EN_Pin,GPIO_PIN_SET); //MOT_ONHAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_SET); //LED_ONHAL_Delay(500);HAL_GPIO_WritePin(MOT_EN_GPIO_Port,MOT_EN_Pin,GPIO_PIN_RESET); //MOT_OFFHAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_RESET); //LED_OFFbreak;}}else{HAL_GPIO_WritePin(POWER_ON_GPIO_Port,POWER_ON_Pin,GPIO_PIN_RESET); //不開機HAL_GPIO_WritePin(MOT_EN_GPIO_Port,MOT_EN_Pin,GPIO_PIN_RESET); //MOT_OFFHAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_RESET); //LED_OFF}} }外部中斷腳代碼處理邏輯
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {if(GPIO_Pin == POWER_OFF_Pin){/* Clear Wake Up Flag */__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);if(HAL_GPIO_ReadPin(POWER_OFF_GPIO_Port,POWER_OFF_Pin)==SET){//printf("關機喚醒中斷\r\n");g_powerOffWakeUp_flag=1;HAL_TIM_Base_Start_IT(&htim6); //開啟定時器}} }?main.c 文件
int main(void) {/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_LPUART1_UART_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 *//* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){//事件1HAL_Delay(1000);//事件2HAL_Delay(3000);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */ }總結一下:其實這樣處理思想,可以應用在很多地方,可達到實時性。不需要管while(1)中大循環的邏輯。有點像多線程處理一樣。
這里的main.c代碼,在實際開發中也不太允許這樣處理,這樣實時性太差了,也是很多小白剛學單片機犯最多的錯誤。這樣寫一看就知道是菜鳥。當然,我那樣寫不是很高大尚,其實想處理多線程的思路,還是引入RTOS好些。當然也不是說邏輯不好,各有利弊,看使用情況而定。
?
總結
以上是生活随笔為你收集整理的STM32单片机裸机程序-高级实现实时性处理方法的全部內容,希望文章能夠幫你解決所遇到的問題。