我在裸机上使用的 Delay 是用 systick timer 实现的
/**
 * @brief  Microsecond delay
 * @param  us specifies the delay time length, in microseconds.
 * @retval None
 */
void Delay_us(uint32_t us)
{
	if (us > 0)
	{
		SysTick->LOAD = SYSTICK_LOAD * us;	  // Set systick reload value
		SysTick->VAL = 0x00;				  // Set SysTick Current Value to 0
		SysTick->CTRL = 0x00000005;			  // Set SysTick clock source to use processor clock and enable timer
		while (!(SysTick->CTRL & 0x00010000)) // Wait for the timer to count to 0
		{
		}
		//		SysTick->CTRL = 0x00000004; // Disable timer
	}
}所以会和 FreeRTOS 产生冲突,所以采用了 TIM2:
void Delay_Init(void)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;
	TIM_TimeBaseInitStructure.TIM_Period = 1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Down;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
}
/**
 * @brief  Microsecond delay
 * @param  us specifies the delay time length, in microseconds.
 * @retval None
 */
void Delay_us(uint32_t us)
{
	if (us > 0)
	{
		TIM2->CNT = us - 1;		  // 向计数器装要递减的数,减到0后会触发定时器的TIM_FLAG_UpDate标志位
		TIM2->CR1 |= TIM_CR1_CEN; // 使能计数器, 计数器开始递减
		while ((TIM2->SR & TIM_FLAG_Update) != SET)
		{
			// 等到计数器减到0
		}
		TIM2->CR1 &= (~TIM_CR1_CEN);	// 关闭计数器
		TIM2->SR &= (~TIM_FLAG_Update); // 清除定时器变为0的标志位
	}
}请问还有其他方法么?比如还是利用 SysTick 来delay,只读不修改。
创建任务时,usStackDepth 最好设置大一点儿,例如 128
如果你使用任何通信,请把通信函数添加到 `portENTER_CRITICAL()` 和 `portEXIT_CRITICAL()` 之间,这是为了确保时间片结束不会被打断通信
void vSHT30Task(void *pvParameters)
{
    SHT30_TypeDef sht30 = {0};
    for (;;)
    {
        portENTER_CRITICAL();
        SHT30_Measure_Periodic_Mode(&sht30);
        OLED_ShowNum(3, 1, sht30.temp, 4);
        OLED_ShowNum(4, 1, sht30.hum, 4);
        printf("sht30_task:%f\n", sht30.hum);
        portEXIT_CRITICAL();
        vTaskDelay(1000);
    }
}p.s. 为什么论坛不支持 markdown 呢,写文章好麻烦。
最近编辑记录 shiinakaze (2024-10-01 10:56:10)
离线
RTOS使用systick溢出中断的分辨率是毫秒,其计数器VAL的分辨率小于微秒。两者结合可以得到微秒分辨率的计时
好的,谢谢大佬指点。
离线