分享

stm32CubeMX HAL库中延时的几种方式解析

 圆锥的布袋 2017-09-21
  1. /* 
  2.  * 本文件包括四种延时方式: 
  3.  * 1. 原来的HAL库函数HAL_Delay()    2. 采用定时器2设置延时函数     3. 采用系统滴答中断方式的ms和us级延时 
  4.  * 4. 采用系统滴答非中断方式的ms和us级延时(在一次计数值范围内的延时) 
  5.  */  
  6.   
  7.   
  8. /* Includes ------------------------------------------------------------------*/  
  9. #include "stm32l1xx_hal.h"  
  10. #include "tim.h"  
  11. #include "usart.h"  
  12. #include "gpio.h"  
  13.   
  14. /* USER CODE BEGIN Includes */  
  15.   
  16. /* USER CODE END Includes */  
  17.   
  18. /* Private variables ---------------------------------------------------------*/  
  19.   
  20. /* USER CODE BEGIN PV */  
  21. /* Private variables ---------------------------------------------------------*/  
  22.   
  23. volatile unsigned int timenum;      //必须要加volatile!!!  
  24. volatile unsigned long time_delay; // 延时时间,注意定义为全局变量  
  25.   
  26. /* USER CODE END PV */  
  27.   
  28. /* Private function prototypes -----------------------------------------------*/  
  29. void SystemClock_Config(void);  
  30. void Error_Handler(void);  
  31.   
  32. /* USER CODE BEGIN PFP */  
  33. /* Private function prototypes -----------------------------------------------*/  
  34. HAL_StatusTypeDef delay_10us(uint32_t num);  
  35. void delay_us(volatile unsigned long nms);  
  36. void delay_ms(volatile unsigned long nms);  
  37. void delay_ms2(int32_t nms);  
  38.   
  39. /* USER CODE END PFP */  
  40.   
  41. /* USER CODE BEGIN 0 */  
  42.   
  43. int fputc(int ch, FILEFILE *f)    
  44. {    
  45.     HAL_UART_Transmit(&huart2 , (uint8_t *)&ch, 1, 0xFFFF);    
  46.     return ch;    
  47. }  
  48.   
  49. /* USER CODE END 0 */  
  50.   
  51. int main(void)  
  52. {  
  53.   
  54.   /* USER CODE BEGIN 1 */  
  55.   
  56.   /* USER CODE END 1 */  
  57.   
  58.   /* MCU Configuration----------------------------------------------------------*/  
  59.   
  60.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */  
  61.   HAL_Init();  
  62.   
  63.   /* Configure the system clock */  
  64.   SystemClock_Config();  
  65.   
  66.   /* Initialize all configured peripherals */  
  67.   MX_GPIO_Init();  
  68.   MX_TIM2_Init();  
  69.   MX_USART2_UART_Init();  
  70.   
  71.   /* USER CODE BEGIN 2 */  
  72.   
  73.        
  74.   /*##-1- Start the TIM Base generation in interrupt mode ####################*/  
  75.   //HAL_TIM_Base_Start_IT(&htim2);  
  76.        
  77.            
  78.     printf("Testing timer2\n");  
  79.     HAL_Delay(1000);  
  80.     printf("Testing timer2\n");  
  81.         HAL_Delay(1000);  
  82.     printf("Testing timer2\n");  
  83.         HAL_Delay(1000);  
  84.     printf("Testing timer2\n");  
  85.         HAL_Delay(1000);  
  86.     printf("Testing timer2\n");  
  87.   
  88.   
  89.   /* USER CODE END 2 */  
  90.   
  91.   /* Infinite loop */  
  92.   /* USER CODE BEGIN WHILE */  
  93.   while (1)  
  94.   {  
  95.   /* USER CODE END WHILE */  
  96.   
  97.   /* USER CODE BEGIN 3 */  
  98.         //HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);  
  99.         delay_ms2(500);  
  100.         printf("12\n");  
  101.         //HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);  
  102.   
  103.         //delay_us(500000);  
  104.   
  105.   }  
  106.   /* USER CODE END 3 */  
  107.   
  108. }  
  109.   
  110. /** System Clock Configuration 
  111. */  
  112. void SystemClock_Config(void)  
  113. {  
  114.   
  115.   RCC_OscInitTypeDef RCC_OscInitStruct;  
  116.   RCC_ClkInitTypeDef RCC_ClkInitStruct;  
  117.   
  118.   __HAL_RCC_PWR_CLK_ENABLE();  
  119.   
  120.   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);  
  121.   
  122.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;  
  123.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;  
  124.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;  
  125.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;  
  126.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12;  
  127.   RCC_OscInitStruct.PLL.PLLDIV = RCC_PLL_DIV3;  
  128.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)  
  129.   {  
  130.     Error_Handler();  
  131.   }  
  132.   
  133.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK  
  134.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;  
  135.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;  
  136.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;  
  137.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;  
  138.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;  
  139.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)  
  140.   {  
  141.     Error_Handler();  
  142.   }  
  143.   
  144.   HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1);  
  145.   
  146.   HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);  //注意这里HAL库重装了系统计数器的值,使美1ms中断一次!!  
  147.   
  148.   HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);  
  149.   
  150.   /* SysTick_IRQn interrupt configuration */  
  151.   HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);  
  152. }  
  153.   
  154. /* USER CODE BEGIN 4 */  
  155.   
  156. /** 
  157.   * @brief  Period elapsed callback in non blocking mode 
  158.   * @param  htim: TIM handle 
  159.   * @retval None 
  160.   */  
  161. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//定时器2中断处理函数  
  162. {  
  163.     if (htim->Instance == htim2.Instance)  
  164.     {  
  165.             HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);  
  166.             if(timenum)  
  167.             {  
  168.                 timenum--;  
  169.                 //printf("%d\n", timenum);  
  170.             }  
  171.     }  
  172. }  
  173.   
  174. HAL_StatusTypeDef delay_10us(uint32_t num)//自定义的定时器2实现延时的函数  
  175. {  
  176.     timenum = num;  
  177.     HAL_TIM_Base_Start_IT(&htim2);  
  178.     while(timenum)                                          //为什么一直停在这个循环中???3-2-1-2-3……怎么会这样!!!--volatile!  
  179.         ;  
  180.     HAL_TIM_Base_Stop_IT(&htim2);  
  181.       
  182.     return HAL_OK;  
  183.       
  184. }  
  185.   
  186.   
  187.   
  188. //SysTick实现延时n_ms,中断方式  
  189. void delay_ms(volatile unsigned long nms)  
  190. {  
  191.     //SYSTICK分频--1ms的系统时钟中断  
  192.     if (SysTick_Config(HAL_RCC_GetHCLKFreq()/1000))  
  193.     {  
  194.      
  195.         while (1);  
  196.     }  
  197.     time_delay=nms;//读取定时时间  
  198.     while(time_delay);  
  199.     SysTick->CTRL=0x00; //关闭计数器  
  200.     SysTick->VAL =0X00; //清空计数器  
  201. }  
  202.   
  203.   
  204. //SysTick实现延时n_us,中断方式  
  205. void delay_us(volatile unsigned long nus)  
  206. {  
  207.  //SYSTICK分频--1us的系统时钟中断  
  208.     if (SysTick_Config(HAL_RCC_GetHCLKFreq()/1000000))  
  209.     {  
  210.      
  211.         while (1);  
  212.     }  
  213.     time_delay=nus;//读取定时时间  
  214.     while(time_delay);  
  215.     SysTick->CTRL=0x00; //关闭计数器  
  216.     SysTick->VAL =0X00; //清空计数器  
  217. }  
  218.   
  219. //SysTick实现延时中断方式的中断处理函数  
  220. //在中断中将time_delay递减。实现延时  
  221. //void SysTick_Handler(void)  
  222. //{  
  223. //    if(time_delay)  
  224. //        time_delay--;  
  225. //}  
  226.   
  227.   
  228. //void HAL_SYSTICK_Callback(void)//原cube HAL库中中断处理回调函数重写  
  229. //{  
  230. //  if(time_delay)  
  231. //      time_delay--;     
  232. //}  
  233.   
  234.   
  235. //void HAL_IncTick(void)//原cube HAL库中,重写  
  236. //{  
  237. //  if(time_delay)  
  238. //      time_delay--;     
  239. //}  
  240.   
  241. /********************************* 优选的方式 ***********************************************************************/  
  242. /*一次填充系统计时器以实现非中断延迟,受限系统计时器stmtick只有24位,所以最长计时有所限制*/  
  243. void delay_ms2(int32_t nms)  
  244. {  
  245.  int32_t temp;  
  246.  SysTick->LOAD = 8000*nms;  
  247.  SysTick->VAL=0X00;//清空计数器  
  248.  SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源  
  249.  do  
  250.  {  
  251.   temp=SysTick->CTRL;//读取当前倒计数值  
  252.  }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达  
  253.     SysTick->CTRL=0x00; //关闭计数器  
  254.     SysTick->VAL =0X00; //清空计数器  
  255. }  
  256.   
  257. /* USER CODE END 4 */  
  258.   
  259. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/  
  260.   
  261.   
  262. /*********************************************************************************************************************/  
  263. /*********************************************************************************************************************/  
  264. /*********************************************************************************************************************/  
  265.   
  266. /*如果自写系统时钟中断处理函数,需要在stml1xx_it.c中注释掉一下函数*/  
  267.   
  268. /** 
  269. * @brief This function handles System tick timer. 
  270. */  
  271. #if 1  
  272. void SysTick_Handler(void)  
  273. {  
  274.   /* USER CODE BEGIN SysTick_IRQn 0 */  
  275.   
  276.   /* USER CODE END SysTick_IRQn 0 */  
  277.   HAL_IncTick();  
  278.   HAL_SYSTICK_IRQHandler();  
  279.   /* USER CODE BEGIN SysTick_IRQn 1 */  
  280.   
  281.   /* USER CODE END SysTick_IRQn 1 */  
  282. }  
  283. #endif  


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多