×
单片机 > 单片机程序设计 > 详情

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

发布时间:2020-06-09 发布时间:
|

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 1

void 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

 


关键字:stm32CubeMX  HAL库  延时

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
51单片机CO2检测显示程序解析