我正在STM32F407 MCU上使用ST链接调试器。我遇到的问题是,在不同的循环缓冲区(用于从USART提取字节)之间,数据加载方式不正确。我想看看从serial [4000]数组中提取帧的线程如何在增加延迟的情况下运行。
下面的代码可以很好地使用debuger,我可以单步进入每一行,检查变量的值。

//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);
导致程序执行陷入一个倒计时循环,并阻止我到达位于等待语句之后的断点。
在我看来,当使用FreeRTOS时,osDelay更接近。
我能想到的唯一原因是ST-Link缺乏兼容性或驱动程序,或者无法包含来自中断触发回调函数的延迟。
谢谢你的帮助。

最佳答案

它与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循环具有近似延迟,启动单次计时器并等待完成,等等。

关于c - 在STM32中使用调试器时如何使用延迟?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54946157/

10-09 22:13