所谓初始化呢,实际就是对于定时器的参数的设置,这里实际只有一个函数,SysTick_Config,这个函数如下
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1);
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
SysTick->VAL = 0;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
return (0);
}
第一句呢,是一句判断,进行查询,SysTick_LOAD_RELOAD_Msk由一下语句定义
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos)
ul表示长整形无符号的数,由于#define SysTick_LOAD_RELOAD_Pos 0;因此程序中的装载值为变量0xFFFFFF,就是对于传入参量的大小进行判断,如果超出则跳出。
这里涉及到初始化函数中的形参ticks,ticks在程序中的赋值为SystemCoreClock / 1000000,而SystenCoreClock只是在system_stm32f10x.c中才有定义,因此顺便研究一下系统时钟的选择。
在system_stm32f10x.c中
#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
* #define SYSCLK_FREQ_HSE HSE_VALUE */
#define SYSCLK_FREQ_24MHz 24000000
#else
* #define SYSCLK_FREQ_HSE HSE_VALUE */
* #define SYSCLK_FREQ_24MHz 24000000 */
* #define SYSCLK_FREQ_36MHz 36000000 */
* #define SYSCLK_FREQ_48MHz 48000000 */
* #define SYSCLK_FREQ_56MHz 56000000 */ (这些实际是注释号,不去掉个/,居然可以被博客注释掉)
#define SYSCLK_FREQ_72MHz 72000000
#endif
在stm32f10x.h中的起始有这样一段
#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_HD_VL) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL)
* #define STM32F10X_LD */
* #define STM32F10X_MD */
* #define STM32F10X_MD_VL */
* #define STM32F10X_HD */
* #define STM32F10X_HD_VL */
* #define STM32F10X_XL */
* #define STM32F10X_CL */
#endif (这堆注释号跟上面同理。。。写全了会注释掉)
为什么这段要预定义这么多呢,实际就是ST库为了移植的方便性,这里涵盖了stm32的所有类型,对于不同的stm32,通过预定义就可以确定系统时钟的大小。
我们使用的是F103ZET6,是属于大容量的,因此上面两段程序的结果就是定义了SYSCLK_FREQ_72MHz 为 72000000。
同样在system_stm32f10x.c中,可以看到如下定义
#ifdef SYSCLK_FREQ_HSE
uint32_t SystemCoreClock = SYSCLK_FREQ_HSE;
#elif defined SYSCLK_FREQ_24MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_24MHz;
#elif defined SYSCLK_FREQ_36MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_36MHz;
#elif defined SYSCLK_FREQ_48MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz;
#elif defined SYSCLK_FREQ_56MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz;
#elif defined SYSCLK_FREQ_72MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz;
#else
uint32_t SystemCoreClock = HSI_VALUE;
#endif
由于定义了SYSCLK_FREQ__72MHz,因此变量SystemCoreClock为72000000,上面提到形参中传值为SystemCoreClock / 1000000,即传值为72(0x48)。
Systick的LOAD寄存器写入的是0x47,倒数为0时重新装载的计数值。
SysTick->VAL = 0;这个就是当前计数值清零,同时清除countflag位
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
这几个常量查询一下
#define SysTick_CTRL_CLKSOURCE_Pos 2
#define SysTick_CTRL_CLKSOURCE_Msk (1ul << SysTick_CTRL_CLKSOURCE_Pos)
#define SysTick_CTRL_TICKINT_Pos 1
#define SysTick_CTRL_TICKINT_Msk (1ul << SysTick_CTRL_TICKINT_Pos)
#define SysTick_CTRL_ENABLE_Pos 0
#define SysTick_CTRL_ENABLE_Msk (1ul << SysTick_CTRL_ENABLE_Pos)
也就是说给控制寄存器写入了111,即内核时钟,使能,产生中断 。
这里剩了一句滴答定时器中断优先级设定函数NVIC_SetPriority没讲,下一篇讲这个函数以及它涉及的系统控制块SCB。
上一篇:stm32之滴答定时器(4):滴答定时器的优先级设置
下一篇:stm32之nRF24L01无线模块(1):SPI2到SPI1的移植
推荐阅读最新更新时间:2024-03-16 16:16