OpenEdv-开源电子网

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

库函数版中自己重新设置时钟怎么操作,关于时钟的设置不懂

[复制链接]

19

主题

85

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
202
金钱
202
注册时间
2014-9-16
在线时间
11 小时
发表于 2015-11-15 18:19:16 | 显示全部楼层 |阅读模式
5金钱
原子大哥的库函数版程序,默认72M时很好用,也没有去管他。
现在换了一个STMF103R8,最大频率只有48M,
想在原子哥的程序基础上改,但是看了半天很晕,不知道在哪个地方设置的系统时钟。
PLL的9倍频在哪呢?
#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
就这个地方设置就可以么,看不出倍频设置在哪?难道默认9倍频?可是我的外部时钟是8M,岂不是72M了,
可是最大只能48M,谁能详细解释一下原子哥的时钟设置过程。加入外部时钟换成12M怎么办,8倍频在哪改。谢谢

最佳答案

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

时钟配置寄存器(RCC_CFGR) 原子哥倍频寄存器版本是直接配置寄存器的,而库函数是有个设置为72M的库函数,在设为72M的函数里面启动HSE,等待启动完毕后再9倍频的,如果你的外部时钟改了,在启动好了HSE后把倍频数改了就好了,如果你的外部高速为8M,那么直接改成上面的#define SYSCLK_FREQ_48MHz就好了,如果你的外部高速为12M,还是需要最大48M的话也是直接#define SYSCLK_FREQ_48MHz那个就好了,但是需要在SetSysClockTo48()里 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

15

主题

786

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3223
金钱
3223
注册时间
2015-7-26
在线时间
811 小时
发表于 2015-11-15 18:19:17 | 显示全部楼层
时钟配置寄存器(RCC_CFGR)

原子哥倍频寄存器版本是直接配置寄存器的,而库函数是有个设置为72M的库函数,在设为72M的函数里面启动HSE,等待启动完毕后再9倍频的,如果你的外部时钟改了,在启动好了HSE后把倍频数改了就好了,如果你的外部高速为8M,那么直接改成上面的#define SYSCLK_FREQ_48MHz就好了,如果你的外部高速为12M,还是需要最大48M的话也是直接#define SYSCLK_FREQ_48MHz那个就好了,但是需要在SetSysClockTo48()里面把RCC_CFGR_PLLMULL6改成RCC_CFGR_PLLMULL4

似乎这句也可以改倍频,具体没试过
RCC_HSEConfig(RCC_HSE_ON);
RCC_WaitForHSEStartUp();
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9); (这句是设置PLL倍频的)
RCC_PLLCmd(ENABLE); (这句使能PLL)




我的博客:http://blog.csdn.net/itdo_just
回复

使用道具 举报

15

主题

786

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3223
金钱
3223
注册时间
2015-7-26
在线时间
811 小时
发表于 2015-11-15 19:05:41 | 显示全部楼层
具体可以看下这个函数里面的设置,SetSysClockTo72();对照手册看一下里面寄存器的设置

寄存器里面有个开启HSE的,开启后再用上面那个寄存器PLLMUL倍频

HSEON:外部高速时钟使能 (External high-speed clock enable)
由软件置’1’或清零。
当进入待机和停止模式时,该位由硬件清零,关闭外部3-25MHz振荡器。当外部3-25MHz振荡
器被用作或被选择将要作为系统时钟时,该位不能被清零。
0: HSE振荡器关闭;
1: HSE振荡器开启。
我的博客:http://blog.csdn.net/itdo_just
回复

使用道具 举报

15

主题

786

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3223
金钱
3223
注册时间
2015-7-26
在线时间
811 小时
发表于 2015-11-15 19:30:58 | 显示全部楼层
如果还是不明白,下面这三个网址应该能解决你的问题
http://www.51hei.com/bbs/dpj-35928-1.html
http://blog.sina.com.cn/s/blog_4a08d4a90101dwwe.html
http://blog.csdn.net/abclixu123/article/details/8265250
我的博客:http://blog.csdn.net/itdo_just
回复

使用道具 举报

19

主题

85

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
202
金钱
202
注册时间
2014-9-16
在线时间
11 小时
 楼主| 发表于 2015-11-15 20:19:18 | 显示全部楼层
回复【4楼】229382777@qq.com:
---------------------------------
谢谢高人指点!!
回复

使用道具 举报

3

主题

2165

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
5773
金钱
5773
注册时间
2013-11-22
在线时间
1211 小时
发表于 2015-11-15 20:19:29 | 显示全部楼层
改SYSCLK_FREQ_48MHz  宏定义之后,时钟初始化调用 SetSysClockTo48,你全局搜索SetSysClockTo48,里面默认配置 6倍PLL
回复

使用道具 举报

15

主题

786

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3223
金钱
3223
注册时间
2015-7-26
在线时间
811 小时
发表于 2015-11-15 20:23:11 | 显示全部楼层
回复【5楼】laoguren1122:
---------------------------------
都是初学者,只是学的比较细而已,注意那三个网站有提到一点,如果晶振换了,这个记得要改#defineHSE_VALUE   ((uint32_t)8000000),否则会造成未知的错误,例如串口出错等
我的博客:http://blog.csdn.net/itdo_just
回复

使用道具 举报

19

主题

85

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
202
金钱
202
注册时间
2014-9-16
在线时间
11 小时
 楼主| 发表于 2015-11-15 20:28:44 | 显示全部楼层
回复【7楼】229382777@qq.com:
---------------------------------
又遇到另外一个问题,我直接SetSysClockTo48应该时钟设置为了48M,
但在delay_ms(1000)的时候发现是8倍的关系,然后将delay_init()中的
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //HCLK/8
改为
      SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
就正常了,但为什么呢?不明白,原来是原子哥72M的程序,下一个是我自己48M的,这样直接SetSysClockTo48
需要更改其他外设的时钟么?明显已经影响delay_ms()了。
回复

使用道具 举报

15

主题

786

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3223
金钱
3223
注册时间
2015-7-26
在线时间
811 小时
发表于 2015-11-15 21:01:31 | 显示全部楼层
回复【8楼】laoguren1122:
---------------------------------
首先里面的8不是什么8倍的关系,这个8代表是的HCLK的时钟是系统时钟的8分频,SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK)是将Systick的时钟选为了内核时钟,是Cortex的自由运行时钟,我对这个时钟不了解,不过原子哥的教程中有这么一句话:SysTick->CTRL&=0xfffffffb;这一句把 SysTick 的时钟选择外部时钟,这里需要注意的是: SysTick 的时钟源自 HCLK 的 8 分频,假设我们外部晶振为 8M,然后倍频到 72M,那么 SysTick 的时钟即为 9Mhz,也就是 SysTick 的计数器 VAL 每减 1,就代表时间过了 1/9us。

那么你的Systick时钟应该为48/8=6Mhz,就是 SysTick 的计数器 VAL 每减 1,就代表时间过了 1/6us。
fac_us=SYSCLK/8;那么这句为48/8=6,也就是1us计6次,这里你只需要把delay_init(72);改成delay_init(48);就好了
我的博客:http://blog.csdn.net/itdo_just
回复

使用道具 举报

15

主题

786

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3223
金钱
3223
注册时间
2015-7-26
在线时间
811 小时
发表于 2015-11-15 22:36:08 | 显示全部楼层
回复【8楼】laoguren1122:
---------------------------------
但是如果你改成了delay_init(48);还是不行的话,我觉得要考虑一下你48M的外部晶振有没有问题了,如果HSE振荡器被直接或间接地作为系统时钟, (间接的意思是:它被作为PLL输入时钟,并且PLL时钟被作为系统时钟),时钟故障将导致系统时钟自动切换到HSI振荡器,同时外部HSE振荡器被关闭。在时钟失效时,如果HSE振荡器时钟(被分频或未被分频)是用作系统时钟的PLL的输入时钟, LL也将被关闭。也就是说你的主频变为了HSI,也就是8M,如果你还继续使用HCLK作为systick时钟(SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8)你这句就是设置了HCLK作为systick时钟),那么你的SysTick 的时钟=HCLK/8=1M,计数值递减1就是1us,但是程序中fac_us=SYSCLK/8=48/8=6M,递减6次才是1us,最后可能导致你的delay_ms(1000)实际跑出来延时是6s。但是如果你把程序改成SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK),就表明你启动内核时钟FCLK来作为SysTick 的时钟,SysTick的时钟 = FCLK = 8M,没有分频,递减8次才是1us,最后delay_ms(1000)实际跑出来可能是0.75秒而不是你说的正常,不知道你是不是这种情况,也属于自己猜测而已。
我的博客:http://blog.csdn.net/itdo_just
回复

使用道具 举报

19

主题

85

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
202
金钱
202
注册时间
2014-9-16
在线时间
11 小时
 楼主| 发表于 2015-11-17 20:53:52 | 显示全部楼层
回复【10楼】229382777@qq.com:
---------------------------------
觉得有点绕,还是糊涂的,我觉得假如程序中fac_us=SYSCLK/8=48/8=6M,递减1/6次才是1us,而不是6次1us,delay_ms(1000)实际跑出来延时是1/6s才对吧
回复

使用道具 举报

15

主题

786

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3223
金钱
3223
注册时间
2015-7-26
在线时间
811 小时
发表于 2015-11-17 21:05:31 | 显示全部楼层
回复【11楼】laoguren1122:
---------------------------------
你再自己理解下吧,原子哥教程原话: 以 delay_us 为例,比如delay_us(50),在刚进入 delay_us 的时候先计算好这段延时需要等待的 SysTick 计数次数,这里为 50*9(假设系统时钟为 72Mhz,那么 SysTick 每增加 1,就是 1/9us),然后我们就一直统计SysTick 的计数变化,直到这个值变化了 50*9,一旦检测到变化达到或者超过这个值,就说明延时 50us 时间到了。
我的博客:http://blog.csdn.net/itdo_just
回复

使用道具 举报

8

主题

163

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
5508
金钱
5508
注册时间
2013-3-16
在线时间
649 小时
发表于 2016-2-15 10:47:10 | 显示全部楼层
一直没有弄明白。。。。
回复

使用道具 举报

9

主题

46

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1131
金钱
1131
注册时间
2016-11-9
在线时间
97 小时
发表于 2016-11-9 16:56:10 | 显示全部楼层
229382777@qq.co 发表于 2015-11-15 21:01
回复【8楼】laoguren1122:
---------------------------------
首先里面的8不是什么8倍的关系,这个8代 ...

您好,我想问一下,您说的把delay_init(72);改成delay_init(48);是在寄存器版本里面的修改,如果相同条件下,我用的是库函数版本,如何修改呢,我个人感觉好像是不需要修改void delay_init()        这个函数,但是不知道理解的对不对,新手,谢谢指教
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-25 03:01

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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