硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2670|回复: 6
收起左侧

[有问必答] 想问下bsp_DelayUS的溢出问题

[复制链接]

6

主题

13

回帖

31

积分

新手上路

积分
31
发表于 2018-4-10 10:58:16 | 显示全部楼层 |阅读模式
UCOS里面关于US延时的函数里面是这样的9#if 0里面我自己加上去的):
       {
                tStart = (uint32_t)CPU_TS_TmrRd();                       /* 刚进入时的计数器值 */
                tCnt = 0;
                tDelayCnt = _ulDelayTime * (SystemCoreClock / 1000000);         /* 需要的节拍数 */                      

                while(tCnt < tDelayCnt)
                {
                        tCnt = (uint32_t)CPU_TS_TmrRd() - tStart; /* 求减过程中,如果发生第一次32位计数器重新计数,依然可以正确计算 */       
                        #if 0
                        TestTick = (uint32_t)CPU_TS_TmrRd();
                        if(TestTick >= tStart)
                        {
                                tCnt = TestTick - tStart;
                        }
                        else
                        {
                                tCnt = 0xFFFFFFFF + TestTick - tStart;
                        }
                        TestTime = (uint32_t)CPU_TS_TmrRd();
                        #endif
                }
        }
问题1:这里不是应该考虑tCnt 的越界问题么,上面注释都写着 如果A < B  那么A - B = C, C的数值就是0xFFFFFFFF - B + A + 1;
问题2:bsp_Init()用到us或者ms延时时,是不是要放到BSP_Tick_Init()之后?但是我看综合例程是先bsp_Init()后BSP_Tick_Init()的,这样不会有问题么?

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106959
QQ
发表于 2018-4-10 12:10:27 | 显示全部楼层
1、不用,看我上面的注释,细细体会下其中的用意。
2、这个跟滴答定时器没关系,这个是DWT组件。
回复

使用道具 举报

3

主题

105

回帖

114

积分

初级会员

积分
114
发表于 2018-4-10 12:51:43 | 显示全部楼层
这种死循环delay在rtos里没多少用处的,太浪费CPU了。intel处理器给你也枉然!况且延迟并不准确:虽然硬件计时是准的,但你在循环检测过程中会有中断产生,可能刚好把最后一个循环给延误到中断后了。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106959
QQ
发表于 2018-4-10 13:01:36 | 显示全部楼层
公仆 发表于 2018-4-10 12:51
这种死循环delay在rtos里没多少用处的,太浪费CPU了。intel处理器给你也枉然!况且延迟并不准确:虽然硬件 ...

你理解稍有偏差,这个函数主要是用于RTOS启动前的硬件外设初始化,很多外设启动需要微妙延迟等操作,无需任何额外硬件资源。而且我们设计的中断执行时间都超短,1us内戳戳有余,抖动很小的。

这个是硬件的DWT组件,时钟周期计数器,系统时钟计数就靠它,比较准确。
回复

使用道具 举报

6

主题

13

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2018-4-10 14:01:26 | 显示全部楼层
eric2013 发表于 2018-4-10 12:10
1、不用,看我上面的注释,细细体会下其中的用意。
2、这个跟滴答定时器没关系,这个是DWT组件。

CPU_TS_TmrRd()刚好是0xFF..FE的时候被tStart取值了,tDelayCnt 是一个延时长度,待跑到while里面的时候假设CPU_TS_TmrRd()已经变成了0x00..0A,按照你的注释 tCnt  = 0xFF..FF - 0x00..0A + 0xFF..FE + 1,取32位已经变成一个好大的数了,但是实际0xFF..FE变成0x00..0A只是相差了12,不对啊,我的理解有哪里错了吗
回复

使用道具 举报

6

主题

13

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2018-4-10 14:05:07 | 显示全部楼层
公仆 发表于 2018-4-10 12:51
这种死循环delay在rtos里没多少用处的,太浪费CPU了。intel处理器给你也枉然!况且延迟并不准确:虽然硬件 ...

用在一些逻辑芯片的延时上面的,us级别就够了,有些器件还必须要有这类延时才能跑起来,但是RTOS的系统时钟都是在ms级别的,满足不了延时需求,我一般都是用定时器的CNT去做这类延时,延时的时候把调度关掉,看到版主大大有个很好的us级别延时例程,所以研究学习一下
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106959
QQ
发表于 2018-4-10 14:20:44 | 显示全部楼层
kaxilion 发表于 2018-4-10 14:01
CPU_TS_TmrRd()刚好是0xFF..FE的时候被tStart取值了,tDelayCnt 是一个延时长度,待跑到while里面的时候 ...

没问题,你好好捋捋。
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-11 12:21 , Processed in 0.162566 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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