有这样一段代关于systick.c,如下:
#include "SysTick.h"
volatile unsigned int TimingDelay ; // 精确延时在SysTick中断里用的计数变量
// 在全局变量里面一定要加上volatile关键字(易变的),否则在全局引用中容易造成编译器的传递错误
void SysTick_1ms_Configuration(void)
{
/* Setup SysTick Timer for 1 msec interrupts */
if (SysTick_Config(SystemFrequency / 1000))
{
/* Capture error */
while (1);
}
}
void Delay_Ms(unsigned int nTime)
{
TimingDelay = nTime;
while(TimingDelay);
}
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关键字,编译器就会对每次的变量操作进行实际赋值,从而保证了变量数据的真实性。
关键字:STM32 Systick 延时函数 变量全局
引用地址:
关于STM32 Systick 延时函数 变量全局引用的问题
推荐阅读最新更新时间:2024-03-16 15:13
基于STM32的心电采集仪方案设计分析
如今,心血管类疾病已经成为威胁人类身体健康的重要疾病之一,而清晰有效的心电图为诊断这类疾病提供了依据,心电采集电路是心电采集仪的关键部分,心电信号属于微弱信号,其频率范围在0.03~100 Hz之间,幅度在0~5 mV之间,同时心电信号还掺杂有大量的干扰信号,因此,设计良好的滤波电路和选择合适的控制器是得到有效心电信号的关键。基于此,本文设计了以STM32为控制核心,AD620和OP07为模拟前端的心电采集仪,本设计简单实用,噪声干扰得到了有效抑制。 1、总体设计方案 心电采集包括模拟采集和数字处理两部分,本设计通过AgCl电极和三导联线心电采集线采集人体心电信号,通过前置放大电路,带通滤波电路,50 Hz双T陷波后再经主放大
[单片机]
STM32的SPI的原理与使用(W25Q128附代码)
一、SPI介绍 SPI 是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口。是Motorola首先在其MC68HCXX系列处理器上定义的。SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。 正是简单易用的特性,如NRF24L01、VS1053、SD卡等皆集成了这种通信协议 二、SPI接口框图 三、SPI优缺点 SPI接口是在CPU和外围低速器件之间进行同步串行数据传输,在主器件的移位脉冲下,
[单片机]
STM32串口中断、DMA接收的几点注意地方
1UART串口中断接收 使能UART串口中断之后,有接收到UART数据,进入中断,此时要清除RXNE接收标志位: 1.通过软件向该RXNE标志位写入零来清零; 2.通过对 USART_DR 寄存器执行读入操作将该位清零。 这里可以查看对应《参考手册》,一般我们选择第2种,通过读取UART串口数据来清零。 1.中断接收数据丢失 在UART串口中断函数中,或者更高优先级中断函数中长时间执行,导致接收丢失,所以,请勿在中断函数中长时间执行。 特别有些人,还在中断函数添加延时函数。实际应用中,只要不是特殊情况,比如测试某个功能可以添加延时函数,都不建议在中断函数添加延时函数。 2.ORE上溢错误 ORE上溢错误是什么意思呢? 可能很
[单片机]
stm32专题五:时钟树(一)寄存器
详细介绍stm32系统时钟配置: 1 时钟来源:外部高速晶振HSE和内部RC振荡器HSI。通过RCC_CR(时钟控制寄存器来配置)。 HSEON为1时,打开外部时钟;当位HSERDY为1时,表示HSE已经准备就绪。同理,HSION和HSIRDY配置内部时钟。当HSE故障时,系统时钟自动切到HSI,直到HSE启动成功。注意:由于HSI不太精确,系统启动时会自动校准,HSICAL 这些位被自动初始化,HSITRIM 用于内部时钟HSI的调整,由软件写入,这些位会叠加到HSICAL 的数值上。 问题:具体怎么调整?HSITRIM 的默认初始值为16,即10000。中文参考手册中说到,可以把HSI调整到8MHz±1
[单片机]
stm32 adc dma多通道采样 数据错位 的解决方法
解决方法:不要采用连续转换模式 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; 需要时才实施转换 ADC_SoftwareStartConvCmd(ADC1, ENABLE); 转换后取消转换 ADC_SoftwareStartConvCmd(ADC1, DISABLE); 经过测试能够解决stm32 adc dma多通道采样 数据错位
[单片机]
调通STM32的串口ISP的经验
1、Boot0需接高(注意不要超过3.6V,非5V容忍脚),Boot1(PB2)需接低(电阻下拉或直接接地)。 2、VDDA/VSSA一定要接好,电压符合要求(2.4~3.6V).即使不用ADC也要接,因为VDDA还为POR/OSC/PLL等“模拟”部分供电。 3、检查复位脚的电位是否正常,JTAG仿真器有可能复位系统。 4、检查TXD/RXD信号通路。当然要畅通,呵呵。 5、如果用非mcuisp的软件,最好在TXD/RXD上加上拉电阻到MAX232电源,防止产生干扰信号。mcuisp从软件上处理了这个干扰,可不考虑这点。 6、波特率先设为9600bps或更低,调通读器件ID后再提高到115200。波特率是否能跑高,与PC串口(U
[单片机]
stm32 pc13~pc15 配置成IO口
在STM32的数据手册的管脚分配图中可以看到:PC14与OSC32_IN公用一个引脚,PC15与OSC32_OUT公用一个引脚,它们的使用方法如下: 当LSE(低速外部时钟信号)开启时,这两个公用管脚的功能是OSC32_IN和OSC32_OUT。 当LSE(低速外部时钟信号)关闭时这两个公用管脚的功能是PC14和PC15。 备用区域控制寄存器(RCC_BDCR)的LSEON用于控制LSE的开启或关闭。关于这个寄存器的用法请参看《STM3210x技术参考手册》。 文档下面有一段话: PC13,PC14和PC15引脚通过电源开关进行供电,因此这三个引脚作为输出引脚时
[单片机]
RC522读写程序代码分享
#include stm32f10x.h #include stm32f10x_spi.h #include stm32f10x_gpio.h #include stm32f10x_rcc.h #include delay.h #include mfrc522.h #include stdio.h #define SPI_CE_LOW() GPIO_ResetBits(GPIOA,GPIO_Pin_4) #define SPI_CE_HIGH() GPIO_SetBits(GPIOA,GPIO_Pin_4) void SPI1_Init(void) { RCC_AP
[单片机]