使用HAL库编写stm32微秒级延时函数,要求如下:不使用HAL库自带的延时函数,不使用系统滴答定时器,仅使用定时器10,进行定时器10的初始化和gpio口的初始化。除此之外,延时函数要给出两套方案,一个采用中断方式,另一个采用轮询方式
时间: 2023-10-10 08:14:54 浏览: 34
方案一:中断方式
首先进行定时器10和GPIO口的初始化:
```c
void TIM10_Init(void) {
TIM_HandleTypeDef htim10;
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;
// 使能定时器10时钟
__HAL_RCC_TIM10_CLK_ENABLE();
htim10.Instance = TIM10;
htim10.Init.Prescaler = 83; // 分频系数为84,即计数器时钟为1MHz
htim10.Init.CounterMode = TIM_COUNTERMODE_UP;
htim10.Init.Period = 0xFFFF;
htim10.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_Base_Init(&htim10);
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
HAL_TIM_ConfigClockSource(&htim10, &sClockSourceConfig);
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim10, &sMasterConfig);
HAL_TIM_Base_Start_IT(&htim10);
}
void GPIO_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct;
// 使能GPIO口时钟
__HAL_RCC_GPIOA_CLK_ENABLE();
// 配置PA5为输出模式
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
```
接下来编写延时函数:
```c
void delay_us_interrupt(uint32_t us) {
TIM_HandleTypeDef htim10;
uint32_t ticks = us * 100;
// 初始化定时器10
TIM10_Init();
// 设置计数器初值
__HAL_TIM_SET_COUNTER(&htim10, 0);
// 等待计数器超过ticks
while (__HAL_TIM_GET_COUNTER(&htim10) < ticks);
// 停止定时器10
HAL_TIM_Base_Stop_IT(&htim10);
}
```
在这个延时函数中,我们通过定时器10的中断事件进行延时。首先进行定时器10的初始化,然后设置计数器初值为0,接着等待计数器的值达到指定的ticks,即我们想要延时的时间。当计数器超过ticks时,延时函数结束。
方案二:轮询方式
首先进行定时器10和GPIO口的初始化,与中断方式相同。
接下来编写延时函数:
```c
void delay_us_polling(uint32_t us) {
TIM_HandleTypeDef htim10;
uint32_t ticks = us * 100;
// 初始化定时器10
TIM10_Init();
// 设置计数器初值
__HAL_TIM_SET_COUNTER(&htim10, 0);
// 等待计数器超过ticks
while (__HAL_TIM_GET_COUNTER(&htim10) < ticks);
// 停止定时器10
HAL_TIM_Base_Stop(&htim10);
}
```
在这个延时函数中,我们同样使用定时器10进行延时。首先进行定时器10的初始化,然后设置计数器初值为0,接着进行轮询,等待计数器的值达到指定的ticks,即我们想要延时的时间。当计数器超过ticks时,延时函数结束。