当前位置:首页 > 芯闻号 > 充电吧
[导读]今天同事测试我之前写的一个小程序,发生了奇怪的错误,先是Uart通讯接收操作,出现了接收数据不全的问题:2个字节的应答帧,在实际运行中只能收到1个字节,导致程序死循环。检查后发现,是接收部分代码留的延

今天同事测试我之前写的一个小程序,发生了奇怪的错误,先是Uart通讯接收操作,出现了接收数据不全的问题:2个字节的应答帧,在实际运行中只能收到1个字节,导致程序死循环。检查后发现,是接收部分代码留的延时太短,造成了芯片误以为通讯已结束,但实际应答帧尚未传输完毕。(此处接收代码的工作模式是:当Uart接收到1个字节后,即开始一个定长的延时,该延时长度与通讯波特率相关,当正常通讯还在继续时,则应在延时结束前收到下一个字节数据,如延时结束仍未收到下一个字节数据,说明当前一帧数据已完成,可开始对已接收数据进行处理)

发现了问题后,进行相应的针对性操作,对延时长度进行了增加,即解决了此问题。但仍然觉得疑惑,因此段程序是已经通过测试的,运行正常,不应突然出现这种奇怪的错误,因此怀疑芯片自身的延时程序存在问题。

而后此程序继续出现的错误证实了之前的怀疑:新出现的错误是显示部分程序的延时明显不够,因此可以断定是延时部分出了问题。此程序的延时功能由滴答定时器的1ms延时函数来实现,对该函数进行排查,果然发现了问题根源。

stm32的滴答定时器设置主要有以下寄存器:


其中SysTick->CTRL寄存器包含了对滴答定时器的时钟频率来源设置和分频设置。前述小程序中,采用的是STM32F107芯片,外部时钟,工作频率为72MHz,在此程序中,为了让滴答定时器的工作压力稍减,使用了8分频的时钟设置,计数(72000000/8000)=9000,时长为1ms。代码如下:


void SystemTick_Configuration(void)
{
    RCC_ClocksTypeDef RCC_Clocks;

    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
    RCC_GetClocksFreq(&RCC_Clocks);
    // SystTick configuration: an interrupt every 1 ms
    if(SysTick_Config(RCC_Clocks.SYSCLK_Frequency / 8000))
    {
        while(1) FEED_WWDG;
    }
}

此程序在我的电脑编译下是正常工作的,但在同事电脑编译下出了问题,滴答定时器的延时明显缩短,原因在于core_cm3.h文件。此文件位置在C:KeilARMCMSISInclude文件夹下,此文件中的SysTick_Config函数包含以下操作:



static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */

  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register */
  NVIC_SetPriority (SysTick_IRQn, (1<VAL   = 0;                                          /* Load the SysTick Counter Value */
  SysTick->CTRL  |= SysTick_CTRL_CLKSOURCE_Msk |
                   SysTick_CTRL_TICKINT_Msk   |
                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
  return (0);                                                  /* Function successful */
}


此处对滴答定时器的时钟来源进行了操作,使其恢复了最高频率(72MHz),不分频:

SysTick->CTRL  |= SysTick_CTRL_CLKSOURCE_Msk |



在我的电脑上,因为对core_cm3.h文件做了以下修改,屏蔽了其对滴答定时器时钟的操作,所以可以正常运行:

SysTick->CTRL  |= //SysTick_CTRL_CLKSOURCE_Msk |

但在同事的电脑上没有做此操作,从而导致了1ms延时实际只有0.125ms,于是出现了前述的种种错误。
解决办法: 1、使用滴答定时器时,不再考虑减轻芯片负担,直接采用原始频率,可以保证不会出现此问题。 2、修改文件调用指向,不调用工程外的相关头文件,防止出现移植时,不同电脑间,工程外文件的不同导致的错误。


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
关闭
关闭