STM32单片机裸机程序-高级实现实时性处理方法
概述
? ? ? ? 這篇文章是對(duì)剛剛學(xué)習(xí)單片機(jī)的小伙伴們,提的一些處理技巧思維。(我在項(xiàng)目上經(jīng)常使用這樣的處理思路)
現(xiàn)在舉個(gè)栗子,應(yīng)用場(chǎng)景是這樣的,比如:在while(1)中在處理一些裸機(jī),然后碰巧又在延時(shí)時(shí)候,當(dāng)你又有其他事件(這個(gè)事件是外部觸發(fā)而來(lái)的)比較緊急要處理這個(gè)事件時(shí),這時(shí)候,CUP肯定是處理不來(lái),需要等待while(1)處理完延時(shí)之后,才能處理這個(gè)比較緊急的事件,這時(shí)候,可能有人會(huì)說(shuō),你干嘛不在外部中斷去處理這個(gè)事件呢,但是如果這個(gè)事件剛好也要延時(shí)呢?怎么辦,一般好的程序不會(huì)在中斷函數(shù)里面使用過(guò)多的延時(shí),還有很多邏輯的事件,這時(shí)候就要換一種處理思維了。哈哈,想必大家也會(huì)想到它,那就是定時(shí)器,如果這時(shí)候使用定時(shí)器的話,問(wèn)題肯定能處理的比在while(1)的大循環(huán)干等待延時(shí)要強(qiáng)的多,完美的組合就是,要中斷與定時(shí)器搭配來(lái)使用才行,這樣的處理事件就不會(huì)因?yàn)檠訒r(shí)邏輯過(guò)長(zhǎng)導(dǎo)致其它事件處理不及時(shí)的問(wèn)題。(廢話有點(diǎn)多,請(qǐng)諒解)
1、打個(gè)比方:我的項(xiàng)目上有關(guān)機(jī)功能
2、首先配置一個(gè)單獨(dú)的定時(shí)器(我這里配置的是 基本定時(shí)器6,注意:如果Tim不夠用的話,可以使用SysTick_Handler/滴答定時(shí)器代替,使用方法同理。)
3、該定時(shí)專門(mén)處理這個(gè)關(guān)機(jī)邏輯的,這時(shí)根據(jù)自己的需求修改定時(shí)器的頻率
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){//編寫(xiě)回調(diào)邏輯,即定時(shí)器6定時(shí)1000us后的邏輯 1ms=1次Power_OFF();} }/* USER CODE END 1 */Power_OFF()函數(shù):
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); //開(kāi)機(jī)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); //不開(kāi)機(jī)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("關(guān)機(jī)喚醒中斷\r\n");g_powerOffWakeUp_flag=1;HAL_TIM_Base_Start_IT(&htim6); //開(kāi)啟定時(shí)器}} }?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 */ }總結(jié)一下:其實(shí)這樣處理思想,可以應(yīng)用在很多地方,可達(dá)到實(shí)時(shí)性。不需要管while(1)中大循環(huán)的邏輯。有點(diǎn)像多線程處理一樣。
這里的main.c代碼,在實(shí)際開(kāi)發(fā)中也不太允許這樣處理,這樣實(shí)時(shí)性太差了,也是很多小白剛學(xué)單片機(jī)犯最多的錯(cuò)誤。這樣寫(xiě)一看就知道是菜鳥(niǎo)。當(dāng)然,我那樣寫(xiě)不是很高大尚,其實(shí)想處理多線程的思路,還是引入RTOS好些。當(dāng)然也不是說(shuō)邏輯不好,各有利弊,看使用情況而定。
?
總結(jié)
以上是生活随笔為你收集整理的STM32单片机裸机程序-高级实现实时性处理方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。