完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
之前一直对stm32的上电后的system tick timer时钟配置存疑,为什么定时时间不随频率改变总能保持1ms,cude生成的两个函数HAL_Init()、SystemClock_Config()具体做了什么。趁着空闲把困惑已久又不起眼的问题解答了。 首先分析main中第一个调用的函数HAL_Init(): HAL_StatusTypeDef HAL_Init(void) { /* Configure Flash prefetch */ #if (PREFETCH_ENABLE != 0) #if defined(STM32F101x6) || defined(STM32F101xB) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC) /* Prefetch buffer is not available on value line devices */ __HAL_FLASH_PREFETCH_BUFFER_ENABLE(); #endif #endif /* PREFETCH_ENABLE */ /* Set Interrupt Group Priority */ HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); /* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */ HAL_InitTick(TICK_INT_PRIORITY); /* Init the low level hardware */ HAL_MspInit(); /* Return function status */ return HAL_OK; } 在stm32f1xx_hal_conf.h中可以看到PREFETCH_ENABLE被宏定义为1,STM32F103xE已经在keil的设置中被预定义 //stm32f1xx_hal_conf.h #define PREFETCH_ENABLE 1U 所以函数__HAL_FLASH_PREFETCH_BUFFER_ENABLE()就能被调用,这个函数使能了flash的预取缓冲区 _ __HAL_FLASH_PREFETCH_BUFFER_ENABLE(); #define __HAL_FLASH_PREFETCH_BUFFER_ENABLE() 在cube中我对中断优先级设置了4bit主优先级,0bit的次优先级,所以 HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4)参数为NVIC_PRIORITYGROUP_4 然后就是函数HAL_InitTick(TICK_INT_PRIORITY) __weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) { /* Configure the SysTick to have interrupt in 1ms time basis*/ if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U) { return HAL_ERROR; } /* Configure the SysTick IRQ priority */ if (TickPriority < (1UL << __NVIC_PRIO_BITS)) { HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U); uwTickPrio = TickPriority; } else { return HAL_ERROR; } /* Return function status */ return HAL_OK; } SystemCoreClock 是个被初始化为16000000的变量,uwTickFreq被宏定义为1,所以调用参数为HAL_SYSTICK_Config(16000),经过重重查找找到 //stm32f1xx_hal_cortex.c uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb) { return SysTick_Config(TicksNumb); } //core_cm3.h __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 */ } ick(16000) < SysTick_LOAD_RELOAD_Msk(0xFFFFFF), 这里SySTick的重装寄存器LOAD设为16000-1,计数寄存器设为0,SysTick_CTRL_CLKSOURCE_Msk设置systick时钟源为AHB而不是AHB/8, SysTick_CTRL_TICKINT_Msk 使能systick中断,SysTick_CTRL_ENABLE_Msk使能systick timer。那么关于systick timer周期设置流程由此得出:系统后面调用SystemClock_Config()初始化完成OSC CLK和AHB CLK与systick时钟源为AHB后,SYSTICK CLK频率就固定为72MHZ,变量SystemCoreClock被改变为72MHZ, 通过再次调用HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq),timer定时器周期=(72000000/1000)*72000000=1/1000(s)==1ms |
|
|
|
只有小组成员才能发言,加入小组>>
3316 浏览 9 评论
2995 浏览 16 评论
3494 浏览 1 评论
9060 浏览 16 评论
4088 浏览 18 评论
1180浏览 3评论
605浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
599浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2335浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1896浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 05:02 , Processed in 1.107230 second(s), Total 47, Slave 38 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号