stm32CubeMX HAL库中延时的几种方式解析
来源:互联网 发布:苏联解体经济数据 编辑:程序博客网 时间:2024/05/17 09:34
stm32CubeMX HAL库中延时的几种方式解析
HAL_Dalay()是毫秒级延时,为了使用微秒级延时最近学习了一下,总结如下,推荐使用最后一种方式。
/* * 本文件包括四种延时方式: * 1. 原来的HAL库函数HAL_Delay() 2. 采用定时器2设置延时函数 3. 采用系统滴答中断方式的ms和us级延时 * 4. 采用系统滴答非中断方式的ms和us级延时(在一次计数值范围内的延时) *//* Includes ------------------------------------------------------------------*/#include "stm32l1xx_hal.h"#include "tim.h"#include "usart.h"#include "gpio.h"/* USER CODE BEGIN Includes *//* USER CODE END Includes *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* Private variables ---------------------------------------------------------*/volatile unsigned int timenum; //必须要加volatile!!!volatile unsigned long time_delay; // 延时时间,注意定义为全局变量/* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/void SystemClock_Config(void);void Error_Handler(void);/* USER CODE BEGIN PFP *//* Private function prototypes -----------------------------------------------*/HAL_StatusTypeDef delay_10us(uint32_t num);void delay_us(volatile unsigned long nms);void delay_ms(volatile unsigned long nms);void delay_ms2(int32_t nms);/* USER CODE END PFP *//* USER CODE BEGIN 0 */int fputc(int ch, FILE *f) { HAL_UART_Transmit(&huart2 , (uint8_t *)&ch, 1, 0xFFFF); return ch; }/* USER CODE END 0 */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(); /* Configure the system clock */ SystemClock_Config(); /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_TIM2_Init(); MX_USART2_UART_Init(); /* USER CODE BEGIN 2 */ /*##-1- Start the TIM Base generation in interrupt mode ####################*/ //HAL_TIM_Base_Start_IT(&htim2); printf("Testing timer2\n");HAL_Delay(1000);printf("Testing timer2\n");HAL_Delay(1000);printf("Testing timer2\n");HAL_Delay(1000);printf("Testing timer2\n");HAL_Delay(1000);printf("Testing timer2\n"); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 *///HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);delay_ms2(500);printf("12\n");//HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);//delay_us(500000); } /* USER CODE END 3 */}/** System Clock Configuration*/void SystemClock_Config(void){ RCC_OscInitTypeDef RCC_OscInitStruct; RCC_ClkInitTypeDef RCC_ClkInitStruct; __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12; RCC_OscInitStruct.PLL.PLLDIV = RCC_PLL_DIV3; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; 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_1) != HAL_OK) { Error_Handler(); } HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1); HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); //注意这里HAL库重装了系统计数器的值,使美1ms中断一次!! HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); /* SysTick_IRQn interrupt configuration */ HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);}/* USER CODE BEGIN 4 *//** * @brief Period elapsed callback in non blocking mode * @param htim: TIM handle * @retval None */void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//定时器2中断处理函数{ if (htim->Instance == htim2.Instance) {HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);if(timenum){timenum--;//printf("%d\n", timenum);} }}HAL_StatusTypeDef delay_10us(uint32_t num)//自定义的定时器2实现延时的函数{timenum = num;HAL_TIM_Base_Start_IT(&htim2);while(timenum)//为什么一直停在这个循环中???3-2-1-2-3……怎么会这样!!!--volatile!;HAL_TIM_Base_Stop_IT(&htim2);return HAL_OK;}//SysTick实现延时n_ms,中断方式void delay_ms(volatile unsigned long nms){ //SYSTICK分频--1ms的系统时钟中断 if (SysTick_Config(HAL_RCC_GetHCLKFreq()/1000)) { while (1); } time_delay=nms;//读取定时时间 while(time_delay); SysTick->CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器}//SysTick实现延时n_us,中断方式void delay_us(volatile unsigned long nus){ //SYSTICK分频--1us的系统时钟中断 if (SysTick_Config(HAL_RCC_GetHCLKFreq()/1000000)) { while (1); } time_delay=nus;//读取定时时间 while(time_delay); SysTick->CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器}//SysTick实现延时中断方式的中断处理函数//在中断中将time_delay递减。实现延时//void SysTick_Handler(void)//{// if(time_delay)// time_delay--;//}//void HAL_SYSTICK_Callback(void)//原cube HAL库中中断处理回调函数重写//{//if(time_delay)//time_delay--;//}//void HAL_IncTick(void)//原cube HAL库中,重写//{//if(time_delay)//time_delay--;//}/********************************* 优选的方式 ***********************************************************************//*一次填充系统计时器以实现非中断延迟,受限系统计时器stmtick只有24位,所以最长计时有所限制*/void delay_ms2(int32_t nms){ int32_t temp; SysTick->LOAD = 8000*nms; SysTick->VAL=0X00;//清空计数器 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源 do { temp=SysTick->CTRL;//读取当前倒计数值 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达 SysTick->CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器}/* USER CODE END 4 *//************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****//*********************************************************************************************************************//*********************************************************************************************************************//*********************************************************************************************************************//*如果自写系统时钟中断处理函数,需要在stml1xx_it.c中注释掉一下函数*//*** @brief This function handles System tick timer.*/#if 1void SysTick_Handler(void){ /* USER CODE BEGIN SysTick_IRQn 0 */ /* USER CODE END SysTick_IRQn 0 */ HAL_IncTick(); HAL_SYSTICK_IRQHandler(); /* USER CODE BEGIN SysTick_IRQn 1 */ /* USER CODE END SysTick_IRQn 1 */}#endif
0 0
- stm32CubeMX HAL库中延时的几种方式解析
- STM32CubeMX Hal库的一些坑
- IOS中延时执行的几种方式的比较
- iOS中延时执行的几种方式
- Android 笔记:Android中延时的几种操作方式
- Android中延时的几种实现方式
- android 延时执行的几种方式
- android 延时执行的几种方式
- android 延时执行的几种方式
- 延时跳转的几种方式
- 延时执行的几种方式
- Android延时的几种常用方式
- STM32CubeMX生成基于HAL库的Can收发配置
- IOS中延时执行的几种方式的比较和汇总
- IOS中延时执行的几种方式的比较和汇总
- IOS中延时执行的几种方式的比较和汇总
- IOS中延时执行的几种方式的比较和汇总
- IOS中延时执行的几种方式的比较和汇总
- Python列出文件夹下所有文件的四种方式
- 如何去写 Android init.rc (Android init language)
- maven几个plugins
- SQLite
- 将maven依赖一并打入jar包
- stm32CubeMX HAL库中延时的几种方式解析
- Spring 学习之 DI 依赖注入
- python 深复制浅复制小结
- 10个鲜为人知但非常有用的PHP函数
- 【文智背后的奥秘】系列篇——海量数据抓取
- nodejs的defer库Q(q)
- SQLiteOpenHelper
- android app换肤(更换主题)
- 常用算法和数据结构的复杂度速查表