新闻中心

EEPW首页>嵌入式系统>设计应用> 关于STM32 Systick 延时函数 变量全局引用的问题

关于STM32 Systick 延时函数 变量全局引用的问题

作者: 时间:2016-12-03 来源:网络 收藏
有这样一段代关于systick.c,如下:

#include "SysTick.h"

volatile unsigned int TimingDelay ; // 精确延时在SysTick中断里用的计数变量
// 在全局变量里面一定要加上volatile关键字(易变的),否则在全局引用中容易造成编译器的传递错误

void SysTick_1ms_Configuration(void)
{
/* Setup SysTick Timer for 1 msecinterrupts */
if (SysTick_Config(SystemFrequency / 1000))
{
/* Capture error */
while (1);
}
}

void Delay_Ms(unsigned int nTime)
{
TimingDelay = nTime;

while(TimingDelay);
}

本文引用地址://m.amcfsurvey.com/article/201612/325152.htm
systick.c的头文件如下:

#ifndef __SYSTICK_H
#define __SYSTICK_H

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"

/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported Global variables -------------------------------------------------*/
extern volatile unsigned int TimingDelay; // 精确延时在SysTick中断里用的计数变量

/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void SysTick_1ms_Configuration(void); // 配置 1ms 时钟心跳
void Delay_Ms(unsigned int nTime); // 1ms 延时

#endif /* __SYSTICK_H */

在中断向量里的函数如下:

/**
* @brief This function handles SysTick Handler.
* @param None
* @retval : None
*/
void SysTick_Handler(void)
{
if (TimingDelay != 0x00)
{
TimingDelay--;
}
}

就是这样一段代码,在stm32里是最常用的精确延时函数,在编译器编译等级为0的时候一切OK,但是一旦上调编译等级到2或者3的时候程序就会死在代码中绿色的位置。最后经尝试知道了是需要在全局变量里使用volatile关键字,否则在编译器进行优化的时候容易产生错误。
仔细分析下类似与变量竞争,一个是中断不断在引用,另外一个是while的循环。如果使用volatile关键字,编译器就会对每次的变量操作进行实际赋值,从而保证了变量数据的真实性。


评论


技术专区

关闭