在STM32中使用调试器时如何使用延迟?

时间:2019-03-01 13:57:00

标签: c debugging delay stm32 freertos

我在STM32F407 MCU上使用ST Link调试器。我有一些问题,这些数据无法在用于从USART提取字节的不同循环缓冲区之间正确加载数据。我想看看从serial [4000]数组中提取帧的线程的行为如何增加延迟。

下面的代码在调试器中运行正常,我可以进入每一行,并检查变量的值。

//This callback is automatically called by the HAL when the DMA transfer is completed
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {           

    // read 50 bytes of raw data to the raw_serial buffer   
    HAL_UART_Receive_DMA (huart, raw_serial, 50);

    //osDelay(10);
    //HAL_Delay(10);

    // add raw_serial to the serial[4000]
    AppendSerial(raw_serial,size);  
}

使用这些延迟之一:

  • osDelay(10);
  • HAL_Delay(10);

导致程序执行陷入倒计时循环之一,并阻止我到达等待语句后的断点。

在阅读此post 时,在使用FreeRTOS时,osDelay似乎更合适。

我只能想到的原因是ST Link缺乏兼容性或驱动程序,或者无法在中断触发的回调函数中包含延迟。

感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

与ST-Link无关。

默认情况下,延迟功能通过监视在计时器中断中递增的变量来工作。如果该计时器中断被阻止,则该变量不会递增,并且延迟功能将永远无法完成。有几种解决方法。

让计时器中断抢占串行中断处理程序

确保定时器中断的优先级高于串行中断。默认情况下,HAL将计时器中断设置为stm32f4xx_hal_conf.h

中的最低优先级(相当愚蠢的想法IMO)
#define  TICK_INT_PRIORITY            0x0FU /*!< tick interrupt priority */

将其更改为较低的值(较高的优先级),然后将UART中断的优先级设置为较高的值(较低的优先级)。现在,HAL_Delay()甚至可以在UART中断处理程序中工作。

使HAL_Delay()正常工作

HAL_Delay()的工作方式是重复调用HAL_GetTick(),直到延迟时间过去为止。 HAL_GetTick()应该以32位无符号值返回自启动以来经过的时间(以毫秒为单位)。您可以提供自己的HAL_GetTick()实现,该实现使用32位硬件计时器来确定当前时间。

有两个32位计时器TIM2TIM5,请选择其中一个。将重载值设置为APB1时钟频率除以1000减1(默认时钟设置为83999),开始递增计数。现在HAL_GetTick()可以简单地返回计时器计数器寄存器。

uint32_t HAL_GetTick(void) {
    return TIM2->CNT; // or TIM5->CNT
}

编写您自己的延迟功能

例如,您可以使用cycle counter来缩短延迟,或者使用空的for循环来获得近似的延迟,启动单次计时器并等待直到完成,等等。

答案 1 :(得分:0)

您不能从中断处理程序中调用延迟函数。请记住,中断处理程序的目的是尽快执行,以便程序可以恢复正常执行,而延迟与该概念不兼容。