博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
STM32 系统时钟(SysTick)设置雷区
阅读量:6328 次
发布时间:2019-06-22

本文共 3075 字,大约阅读时间需要 10 分钟。

昨天在设置 STM32F103 的系统时钟的时候,按照官方文档的方法进行设置,虽然系统时钟有效,但是原本设定为1s后执行的任务却延迟了九秒左右。百思不得其解,可以确定硬件是没有问题的。

以下是系统时钟的设置代码:

void clock_init(){  if (SysTick_Config(SystemCoreClock/CLOCK_SECOND)){        while (1);  }}

SysTick_Config() 是系统时钟的设置函数,代码如下:

/** * @brief  Initialize and start the SysTick counter and its interrupt. * * @param   ticks   number of ticks between two interrupts * @return  1 = failed, 0 = successful * * Initialise the system tick timer and its interrupt and start the * system tick timer / counter in free running mode to generate  * periodical interrupts. */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<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Cortex-M0 System Interrupts */  SysTick->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 */}

参数 ticks 是两个中断之间所需要的CPU ticks。我所使用的板子是STM32F103,CPU频率为72MHz。可以通过宏 SystemCoreClock 进行访问。上面宏 CLOCK_SECOND 设置为1000。也就是说,通过上面的配置,系统每1ms进行中断函数一次,精度为1ms。

以下是中断处理函数代码:

void SysTick_Handler(void){  current_clock++;  if(etimer_pending() && etimer_next_expiration_time() <= current_clock) {    etimer_request_poll();  }  if (--second_countdown == 0) {    current_seconds++;    second_countdown = CLOCK_SECOND;  }}

主要的作用是 current_clock 计数的递增和检查定时器有没有过期。但是任务却没有像预期一样在设定的时间后运行,而是延迟了近9秒。已经可以确定板子的CPU频率确实为72MHz,但是实际上板子的频率却为8M。

解决方法:

STM32F103内部是8M的震荡,通过倍频后可以达到72M。我所使用的固件库是3.5的版本,通过查看文件system_stm32f103x.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_MD_VL之类的宏需要用户自己定义,而这里设置了SYSCLK_FREQ_72MHz为72000000。也就是说固件库在默认硬件已经接了8M晶振时,103的板子可以跑到72M。

#ifdef SYSCLK_FREQ_HSE  static void SetSysClockToHSE(void);#elif defined SYSCLK_FREQ_24MHz  static void SetSysClockTo24(void);#elif defined SYSCLK_FREQ_36MHz  static void SetSysClockTo36(void);#elif defined SYSCLK_FREQ_48MHz  static void SetSysClockTo48(void);#elif defined SYSCLK_FREQ_56MHz  static void SetSysClockTo56(void);  #elif defined SYSCLK_FREQ_72MHz  static void SetSysClockTo72(void);#endif

上面是声明时钟设置的代码,可以看到这里出现了SetSysClockTo72 函数,把系统时钟设置为72M。而这个函数会被函数 SystemInit() 调用。

所以现在问题已经明确了,你的程序是初始化的时候需要调用 SystemInit() 函数进行系统时钟的初始化。试了一下,问题完美解决。

总结:

系统时钟没有初始化,需要在用户程序中手动调用,这个大坑。

转载地址:http://rjwoa.baihongyu.com/

你可能感兴趣的文章
关键字检索高亮标出-javasript/jQuery代码实现
查看>>
Vijos P1785 同学排序【模拟】
查看>>
人物关系网络图可视化
查看>>
关于ADO.Net SqlConnection的性能优化
查看>>
docker安装及加速配置
查看>>
MRF能量优化
查看>>
什么是.Net, IL, CLI, BCL, FCL, CTS, CLS, CLR, JIT
查看>>
Atlas Control ToolKit 发布
查看>>
Dundas 系列
查看>>
Windows的命令行查看,修改,删除,添加环境变量
查看>>
iOS 图文混排
查看>>
GC是什么? 为什么要有GC?
查看>>
JQuery EasyUi之界面设计——母版页以及Ajax的通用处理(三)
查看>>
童年记忆
查看>>
Selenium Python bindings 文档一
查看>>
directX的16位和24位的色彩模式
查看>>
WINDOWS 8
查看>>
ASP.NET MVC涉及到的5个同步与异步,你是否傻傻分不清楚?[下篇]
查看>>
spring(10)
查看>>
Ubuntu 12.04 LTS 及ubuntu14.10 -- NFS安装
查看>>