1. volatile关键字
C语言中变量的定义:
存储类型 特征修饰 数据类型 变量名
存储类型:决定变量的存储位置
auto 自动类型,局部变量,存在栈中,
static 静态变量,静态区(数据段),生命周期长
extern
register 局部变量,寄存器或内存,只能是整形,不能取地址操作
特征修饰: 决定变量的特征属性 const,voatile
代码优化(减少内存访问的速度):
1. 硬件:引入高速缓存
2. 软件: 编码优化;编译优化;
volatile应用场合:
1. 中断
2. 多线程
3. 硬件寄存器
作用:告诉编译器每次都要去内存存取,不是直接使用寄存器中的备份
数据类型: 决定变量的存储空间及数据范围
变量名:决定变量的引用标识
2. 源码
因为SysTick定时器向下计数器是24位,所以传入变量大于0xFFFFFF时返回1,标识不是正常返回;
上表分别对应代码中SysTick_Type结构体的CTRL,LOAD,VAL,CALIB
SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk即将CTRL寄存器的0,1,2位置1;
//core_m4.h 源码
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
#define __NVIC_PRIO_BITS 4 /*!< GD32F4xx uses 4 bits for the priority levels */
#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
#define NVIC_SetPriority __NVIC_SetPriority
__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if ((int32_t)(IRQn) >= 0)
{
NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
}
else
{
SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
}
}
typedef struct
{
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
// SysTick 定时器配置
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
{
return (1UL); /* Reload value impossible */
}
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
SysTick->VAL = 0UL; /* 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 (0UL); /* Function successful */
}
#include "gd32f4xx.h"
#include "systick.h"
volatile static uint32_t delay;
*/
/*!
\brief configure systick
\param[in] none
\param[out] none
\retval none
*/
void systick_config(void)
{
/* setup systick timer for 1000Hz interrupts */
if (SysTick_Config(SystemCoreClock / 1000U)){ // 120000次
// #define __SYSTEM_CLOCK_120M_PLL_8M_HXTAL (uint32_t)(120000000)
// uint32_t SystemCoreClock = __SYSTEM_CLOCK_120M_PLL_8M_HXTAL;
/* capture error */
while (1){
}
}
/* configure the systick handler priority */
NVIC_SetPriority(SysTick_IRQn, 0x00U);
}
/*!
\brief delay a time in milliseconds
\param[in] count: count in milliseconds
\param[out] none
\retval none
*/
void delay_1ms(uint32_t count)
{
delay = count;
while(0U != delay){
}
}
/*!
\brief delay decrement
\param[in] none
\param[out] none
\retval none
*/
void delay_decrement(void)
{
if (0U != delay){
delay--;
}
}
// gd32f4xx_it.c
void SysTick_Handler(void)
{
delay_decrement();
}