OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3288|回复: 2

STM32F103使用内部时钟SysTick延时设置问题

[复制链接]

3

主题

7

帖子

0

精华

新手上路

积分
49
金钱
49
注册时间
2016-3-1
在线时间
13 小时
发表于 2020-4-22 16:47:14 | 显示全部楼层 |阅读模式
1金钱
问题:单片机使用内部高速时钟,Systick不准确:

单片机型号:STM32F103C8T6

1./main 函数设置如下:
  1. int main(void)
  2. {                
  3.         RCC_Configuration();
  4.         RCC_ClocksTypeDef get_rcc_clock;    //获取系统时钟状态
  5.         RCC_GetClocksFreq(&get_rcc_clock);  //仿真的时候就可以在结构体get_rcc_clock中看见各个外设的时钟了
  6.         delay_init();                     //延时函数初始化       
  7.         delay_ms(1000);       
复制代码
2./RCC配置函数:
  1. /*
  2. 描述:使用HSI作为PLL的输入时钟
  3. 注意:1.需要注释SystemInit()函数及相关配置
  4.         2.使用HSI进行PLL后最高频率只能到64M,不能使用72M
  5. PLL = SYSCLK = HCLK = PCLK2 = 36M
  6. PCLK1= HCLK/2 = 36M
  7. */
  8. void RCC_Configuration(void)
  9. {
  10.     RCC_DeInit();//将外设 RCC寄存器重设为缺省值

  11.     RCC_HSICmd(ENABLE);//使能HSI  
  12.     while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);//等待HSI使能成功

  13.     //FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
  14.     //FLASH_SetLatency(FLASH_Latency_2);
  15.    
  16.     RCC_HCLKConfig(RCC_SYSCLK_Div1);//配置AHB时钟频率与系统时钟频率一致  8M
  17.     RCC_PCLK1Config(RCC_HCLK_Div2);//配置APB1低速时钟频率为AHB时钟频率的1/2 4M
  18.     RCC_PCLK2Config(RCC_HCLK_Div1);//配置APB2高速时钟频率与AHB时钟频率一致 8M
  19.    
  20.     //设置 PLL 时钟源及倍频系数
  21.         //将内部晶振时钟2分频后作为PLL时钟源,倍频系数为9(即系统时钟为36MHz)
  22.     RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_9);//使能或者失能 PLL,这个参数可以取:ENABLE或者DISABLE
  23.     RCC_PLLCmd(ENABLE);//如果PLL被用于系统时钟,那么它不能被失能
  24.     //等待指定的 RCC 标志位设置成功 等待PLL初始化成功
  25.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

  26.     //设置系统时钟(SYSCLK) 设置PLL为系统时钟源
  27.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//选择想要的系统时钟
  28.     //等待PLL成功用作于系统时钟的时钟源
  29.     //  0x00:HSI 作为系统时钟
  30.     //  0x04:HSE作为系统时钟
  31.     //  0x08:PLL作为系统时钟  
  32.     while(RCC_GetSYSCLKSource() != 0x08);//需与被选择的系统时钟对应起来,RCC_SYSCLKSource_PLL
  33. }
复制代码
3./delay_init()        设置,
  1. ///初始化延迟函数
  2. //当使用ucos的时候,此函数会初始化ucos的时钟节拍
  3. //SYSTICK的时钟固定为HCLK时钟的1/8
  4. //SYSCLK:系统时钟
  5. void delay_init()         
  6. {

  7. #ifdef OS_CRITICAL_METHOD         //如果OS_CRITICAL_METHOD定义了,说明使用ucosII了.
  8.         u32 reload;
  9. #endif
  10.         SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);        //systick的时钟频率是36/8Mhz;  HCLK/8
  11.         fac_us=<font color="#ff0000"><b>SystemCoreClock</b></font>/8000000;        //为系统时钟的1/8  
  12. //        SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);        //选择外部时钟  HCLK/8
  13. //        fac_us=SystemCoreClock;        //为系统时钟的1/8  
  14.          
  15. #ifdef OS_CRITICAL_METHOD         //如果OS_CRITICAL_METHOD定义了,说明使用ucosII了.
  16.         reload=SystemCoreClock/8000000;                //每秒钟的计数次数 单位为K          
  17.         reload*=1000000/OS_TICKS_PER_SEC;//根据OS_TICKS_PER_SEC设定溢出时间
  18.                                                         //reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右       
  19.         fac_ms=1000/OS_TICKS_PER_SEC;//代表ucos可以延时的最少单位          
  20.         SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;           //开启SYSTICK中断
  21.         SysTick->LOAD=reload;         //每1/OS_TICKS_PER_SEC秒中断一次       
  22.         SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;           //开启SYSTICK   
  23. #else
  24.         fac_ms=(u16)fac_us*1000;//非ucos下,代表每个ms需要的systick时钟数   
  25. #endif
  26. }
复制代码
4./跟踪SystemCoreClock,发现其依然为72M,
微信图片_20200422163328.png

5./将其手动改为36M
  1. SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);        //systick的时钟频率是36/8Mhz;  HCLK/8
  2.         fac_us=36000000/8000000;        //为系统时钟的1/8  
复制代码
6./测试发现时间差了好多:800ms左右,与设定值1000ms差太多
1587544904522.jpg

大循环:
  1. while(1)
  2.         {       
  3.                 delay_ms(1000);//等待接收中断
  4.                 LED3_REV;
复制代码




最佳答案

查看完整内容[请看2#楼]

找到答案: 36除以8==4.5,而fac_us是整型,所以计时会出现偏差!!! 将系统时钟设置为48M,再次测试,延时准确! 新的问题:能否通过某个变量灵活的设置SystemCoreClock???
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

7

帖子

0

精华

新手上路

积分
49
金钱
49
注册时间
2016-3-1
在线时间
13 小时
 楼主| 发表于 2020-4-22 16:47:15 | 显示全部楼层
本帖最后由 781354052 于 2020-4-22 17:12 编辑

找到答案:

  1. static u8  fac_us=0;//us延时倍乘数
复制代码

  1. fac_us=36000000/8000000;        //为系统时钟的1/8  
复制代码



36除以8==4.5,而fac_us是整型,所以计时会出现偏差!!!
将系统时钟设置为48M,再次测试,延时准确!

新的问题:能否通过某个变量灵活的设置SystemCoreClock???

回复

使用道具 举报

3

主题

7

帖子

0

精华

新手上路

积分
49
金钱
49
注册时间
2016-3-1
在线时间
13 小时
 楼主| 发表于 2020-4-22 17:23:01 | 显示全部楼层
stm32f10x.c对应修改系统频率
111111111172129.png
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-25 23:39

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表