OpenEdv-开源电子网

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

战舰资料A盘 程序源码勘误

[复制链接]

15

主题

78

帖子

0

精华

初级会员

Rank: 2

积分
192
金钱
192
注册时间
2015-7-22
在线时间
126 小时
发表于 2016-5-13 10:48:39 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 sanv 于 2016-5-13 10:54 编辑

        最近在细看STM32的基本设置。发下战舰板子的程序源码好像在延迟函数初始化时候有个错误。战舰板程序源码如下

void delay_init()
{
#if SYSTEM_SUPPORT_OS                                                          //如果需要支持OS.
        u32 reload;
#endif
        SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);        //选择外部时钟  HCLK
        fac_us=SystemCoreClock/8000000;                                //为系统时钟的1/8  
#if SYSTEM_SUPPORT_OS                                                          //如果需要支持OS.
        reload=SystemCoreClock/8000000;                                //每秒钟的计数次数 单位为K           
        reload*=1000000/delay_ostickspersec;                //根据delay_ostickspersec设定溢出时间
                                                                                                //reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右        
        fac_ms=1000/delay_ostickspersec;                        //代表OS可以延时的最少单位           

        SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;           //开启SYSTICK中断
        SysTick->LOAD=reload;                                                 //每1/delay_ostickspersec秒中断一次        
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;           //开启SYSTICK   

#else
        fac_ms=(u16)fac_us*1000;                                        //非OS下,代表每个ms需要的systick时钟数   
#endif
}                                                                    



这里好像不应该把Systick系统时钟初始化为系统时钟的8分频吧!应该是系统时钟频率才对吧。[size=18.018px]fac_us=SystemCoreClock/8000000;不是9次么?
Systick的时钟如果是8分频的话那应该是900000次1秒吧。那么[size=18.018px]fac_us=[size=18.018px]900000[size=18.018px]/8000000吧!所以应该改为以下两种方式的一种吧
第一种
[size=18.018px]void delay_init()
[size=18.018px]{
[size=18.018px]#if SYSTEM_SUPPORT_OS                                                          //如果需要支持OS.
[size=18.018px]        u32 reload;
[size=18.018px]#endif
[size=18.018px]        [size=18.018px]SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK[size=18.018px]);        //直接使用系统时钟72MHz
[size=18.018px]        fac_us=SystemCoreClock/8000000;                                //为系统时钟的1/8  
[size=18.018px]#if SYSTEM_SUPPORT_OS                                                          //如果需要支持OS.
[size=18.018px]        reload=SystemCoreClock/8000000;                                //每秒钟的计数次数 单位为K           
[size=18.018px]        reload*=1000000/delay_ostickspersec;                //根据delay_ostickspersec设定溢出时间
[size=18.018px]                                                                                                //reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右        
[size=18.018px]        fac_ms=1000/delay_ostickspersec;                        //代表OS可以延时的最少单位           

[size=18.018px]        SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;           //开启SYSTICK中断
[size=18.018px]        SysTick->LOAD=reload;                                                 //每1/delay_ostickspersec秒中断一次        
[size=18.018px]        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;           //开启SYSTICK   

[size=18.018px]#else
[size=18.018px]        fac_ms=(u16)fac_us*1000;                                        //非OS下,代表每个ms需要的systick时钟数   
[size=18.018px]#endif
[size=18.018px]}
[size=18.018px]

[size=18.018px]第二种
[size=18.018px]void delay_init()
[size=18.018px]{
[size=18.018px]#if SYSTEM_SUPPORT_OS                                                          //如果需要支持OS.
[size=18.018px]        u32 reload;
[size=18.018px]#endif
[size=18.018px]        [size=18.018px]SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);        //选择外部时钟  HCLK的8分频
[size=18.018px]        fac_us=SystemCoreClock/8/8000000;                                //1us所需次数  
[size=18.018px]#if SYSTEM_SUPPORT_OS                                                          //如果需要支持OS.
[size=18.018px]        reload=SystemCoreClock/8000000;                                //每秒钟的计数次数 单位为K           
[size=18.018px]        reload*=1000000/delay_ostickspersec;                //根据delay_ostickspersec设定溢出时间
[size=18.018px]                                                                                                //reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右        
[size=18.018px]        fac_ms=1000/delay_ostickspersec;                        //代表OS可以延时的最少单位           

[size=18.018px]        SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;           //开启SYSTICK中断
[size=18.018px]        SysTick->LOAD=reload;                                                 //每1/delay_ostickspersec秒中断一次        
[size=18.018px]        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;           //开启SYSTICK   

[size=18.018px]#else
[size=18.018px]        fac_ms=(u16)fac_us*1000;                                        //非OS下,代表每个ms需要的systick时钟数   
[size=18.018px]#endif
[size=18.018px]}                                                                    
[size=18.018px]                                                                    

[size=18.018px]不知道这个理解对不对,原子哥出来解释一下。
[size=18.018px]


最佳答案

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

http://www.openedv.com/posts/list/26038.htm
work is work!!!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

8

主题

570

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2914
金钱
2914
注册时间
2016-5-13
在线时间
184 小时
发表于 2016-5-13 10:48:40 | 显示全部楼层
虽然不明白你们在说什么,但感觉很厉害的样子。
回复

使用道具 举报

70

主题

6761

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
13118
金钱
13118
注册时间
2012-11-26
在线时间
3813 小时
发表于 2016-5-13 11:30:36 | 显示全部楼层
你觉得你对,那就按照你理解的来
学无止境
回复

使用道具 举报

15

主题

78

帖子

0

精华

初级会员

Rank: 2

积分
192
金钱
192
注册时间
2015-7-22
在线时间
126 小时
 楼主| 发表于 2016-5-13 13:14:36 | 显示全部楼层
jermy_z 发表于 2016-5-13 11:30
你觉得你对,那就按照你理解的来

不是啊,我又试过了,用资料盘里的delay_init函数初始化,延迟是不准确的啊?这不是按谁的理解的问题,是对的就是对的,是错的就是错的。大神能否帮我解释一下?
work is work!!!
回复

使用道具 举报

2

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
174
金钱
174
注册时间
2015-12-3
在线时间
71 小时
发表于 2016-5-13 13:33:47 | 显示全部楼层
sanv 发表于 2016-5-13 13:14
不是啊,我又试过了,用资料盘里的delay_init函数初始化,延迟是不准确的啊?这不是按谁的理解的问题,是 ...

你更改后的延时准确吗?
回复

使用道具 举报

15

主题

78

帖子

0

精华

初级会员

Rank: 2

积分
192
金钱
192
注册时间
2015-7-22
在线时间
126 小时
 楼主| 发表于 2016-5-13 13:35:59 | 显示全部楼层
void 发表于 2016-5-13 13:33
你更改后的延时准确吗?

修改后至少看起来准确!我delay_ms(1000)跑秒钟是准确的。不会像原来那样,根本不对。有兴趣你也可以试试。看看是不是这么回事。
work is work!!!
回复

使用道具 举报

2

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
174
金钱
174
注册时间
2015-12-3
在线时间
71 小时
发表于 2016-5-13 14:08:10 | 显示全部楼层
sanv 发表于 2016-5-13 13:35
修改后至少看起来准确!我delay_ms(1000)跑秒钟是准确的。不会像原来那样,根本不对。有兴趣你也可以试试 ...

从理解上,原子的应该没问题呀。http://www.openedv.com/forum.php?mod=viewthread&tid=29453
回复

使用道具 举报

8

主题

570

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2914
金钱
2914
注册时间
2016-5-13
在线时间
184 小时
发表于 2016-5-13 14:11:20 | 显示全部楼层
楼主 你的理解是错的哦
虽然不明白你们在说什么,但感觉很厉害的样子。
回复

使用道具 举报

8

主题

570

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2914
金钱
2914
注册时间
2016-5-13
在线时间
184 小时
发表于 2016-5-13 14:12:32 | 显示全部楼层
本帖最后由 电脑小白 于 2016-5-13 14:19 编辑

SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);----选择外部时钟
这一句把 SysTick 的时钟 选择外部时钟,这里需要注意的是: SysTick的时钟源自HCLK的 8分频,假设我们外部 晶振为 8M ,然后倍频到72M ,那么 SysTick的时钟即为9Mhz ,也就是  SysTick 的计数器 VAL每减 1,就代表时间过了 1/9us 。
虽然不明白你们在说什么,但感觉很厉害的样子。
回复

使用道具 举报

8

主题

570

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2914
金钱
2914
注册时间
2016-5-13
在线时间
184 小时
发表于 2016-5-13 14:22:40 | 显示全部楼层
如果按照楼主你的算法延时是对的话,那么应该是你的外部晶振没有工作,运行的是内部8M的时钟源。
虽然不明白你们在说什么,但感觉很厉害的样子。
回复

使用道具 举报

8

主题

570

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2914
金钱
2914
注册时间
2016-5-13
在线时间
184 小时
发表于 2016-5-13 14:30:52 | 显示全部楼层
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);        //外部时钟  HCLK/8
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);                //内核时钟  FCLK
STM32不完全手册(库函数版)V3.0   107页有详细介绍。
虽然不明白你们在说什么,但感觉很厉害的样子。
回复

使用道具 举报

15

主题

78

帖子

0

精华

初级会员

Rank: 2

积分
192
金钱
192
注册时间
2015-7-22
在线时间
126 小时
 楼主| 发表于 2016-5-13 14:39:33 | 显示全部楼层
电脑小白 发表于 2016-5-13 14:22
如果按照楼主你的算法延时是对的话,那么应该是你的外部晶振没有工作,运行的是内部8M的时钟源。

我使用keil仿真的,外部时钟估计是没有起作用。
work is work!!!
回复

使用道具 举报

15

主题

78

帖子

0

精华

初级会员

Rank: 2

积分
192
金钱
192
注册时间
2015-7-22
在线时间
126 小时
 楼主| 发表于 2016-5-13 14:42:42 | 显示全部楼层
电脑小白 发表于 2016-5-13 14:30
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);        //外部时钟  HCLK/8
SysTick_CLKSourceConfig(Sy ...


SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); 这句话不是把Systick时钟设置为系统时钟的8分频吗?那也是9MHz啊,外部晶振是8MHz的啊
work is work!!!
回复

使用道具 举报

15

主题

78

帖子

0

精华

初级会员

Rank: 2

积分
192
金钱
192
注册时间
2015-7-22
在线时间
126 小时
 楼主| 发表于 2016-5-13 14:47:25 | 显示全部楼层
电脑小白 发表于 2016-5-13 14:22
如果按照楼主你的算法延时是对的话,那么应该是你的外部晶振没有工作,运行的是内部8M的时钟源。

Core_m3.h里面定义了
#define SysTick_CTRL_CLKSOURCE_Pos          2                                             /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk         (1ul << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */

这里应该是设置成了内核时钟了吧
work is work!!!
回复

使用道具 举报

15

主题

78

帖子

0

精华

初级会员

Rank: 2

积分
192
金钱
192
注册时间
2015-7-22
在线时间
126 小时
 楼主| 发表于 2016-5-13 15:11:36 | 显示全部楼层
电脑小白 发表于 2016-5-13 15:04
http://www.openedv.com/posts/list/26038.htm

也就是说,STM32的Systic系统时钟可以设置成内部的和外部的,内部时钟有系统时钟和系统时钟的8分频。那看来这句话确实是设置成系统时钟的8分频了
work is work!!!
回复

使用道具 举报

15

主题

78

帖子

0

精华

初级会员

Rank: 2

积分
192
金钱
192
注册时间
2015-7-22
在线时间
126 小时
 楼主| 发表于 2016-5-13 16:48:27 | 显示全部楼层
电脑小白 发表于 2016-5-13 15:04
http://www.openedv.com/posts/list/26038.htm

此贴要了结了。整个过程是这样的:SysTick_CLKSourceConfig设置的是多少MHz频率,那么1us因子就是多少。SysTick时钟是系统时钟的8分频即9MHz,那么1us的因子就是9。如果是系统时钟的72MHz的话,因子就是72.fac_us=SystemCoreClock/8000000; 这里这句话不是很容易懂,其实直接根据systick的时钟就直接写fac_us就好了,是几MHz因子就是几。简单明了。
work is work!!!
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-9 07:26

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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