请选择 进入手机版 | 继续访问电脑版
搜索
查看: 1866|回复: 3

[已解决] 利用DWT进行精准us延迟

[复制链接]

该用户从未签到

6

主题

14

帖子

0

蝴蝶豆

中级会员

最后登录
2021-1-13
发表于 2018-12-20 16:50:37 | 显示全部楼层 |阅读模式
10ST金币
我使用STM32L151芯片,采用内部MSI时钟,4.194MHz,在利用DWT进行us延时的时候发现差距特别大,代码如下
void PUB_DelayInit(WORD32 SYSClock)
{
    SystemCoreClock = SYSClock;

    DEM_CR      |= (unsigned int)DEM_CR_TRCENA;     // 开启DWT调试
        DWT_CYCCNT   = (unsigned int)0u;                // 清零
        DWT_CR      |= (unsigned int)DWT_CR_CYCCNTENA;  // 使能
}

void PUB_DelayUs(WORD16 us)
{
    WORD32 tCnt, tDelayCnt;
        WORD32 tStart;
               
        tStart = DWT_CYCCNT;                            // 刚进入时的计数器值
        tCnt = 0;
        tDelayCnt = us * (SystemCoreClock/1000000.0);        // 需要的节拍数                      

        while(tCnt < tDelayCnt)
        {
                tCnt = DWT_CYCCNT - tStart;               
        }
}


先进行PUB_DelayInit(4194000);然后调用PUB_DelayUs(5),示波器观察是10us,不知道为什么会出现这种情况呢?和网上说的精度差距有点大

回复

使用道具 举报

该用户从未签到

20

主题

621

帖子

152

蝴蝶豆

论坛元老

最后登录
2023-11-13
发表于 2018-12-21 00:40:21 | 显示全部楼层
本帖最后由 radio2radio 于 2018-12-21 00:42 编辑

我的精准us延迟是这样得到的:


  1. //-----uS delay ( >=1us)---------------
  2. void vDelayUS(uint32_t u32DelayUS)
  3. {
  4.         uint32_t i;
  5.        
  6.         if (u32DelayUS <= 15)
  7.         {
  8.                 switch(u32DelayUS)
  9.                 {
  10.                         case 1:
  11.                                 __NOP();
  12.                                 __NOP();
  13.                                 __NOP();
  14.                                 return;
  15.                        
  16.                         case 2:
  17.                                 i = 3;
  18.                                 __NOP();
  19.                                 break;
  20.                         case 3:
  21.                                 i = 6;
  22.                                 __NOP();
  23.                                 __NOP();
  24.                                 __NOP();
  25.                                 break;
  26.                         case 4:
  27.                                 i = 10;
  28.                                 __NOP();
  29.                                 __NOP();
  30.                                 break;
  31.                         default:
  32.                                 i = (u32DelayUS - 2) << 2;
  33.                                 i++;
  34.                                 i++;
  35.                 }
  36. loop:        if (--i > 0) goto loop;
  37.                 return;
  38.         }
  39.         // >=16us
  40.         u32DelayUS = (DELAY_US_FACTOR * u32DelayUS) >> 12;
  41.         for (i = 0;  i < u32DelayUS; i++) {}
  42. }
复制代码

上面的代码是在NXP的MCU上面,调试以后得到的。 注意,
1. CPU的时钟频率,直接影响结果。
2. 编译器的优化选择项,直接影响结果。
3. 使用时,必须用示波器,校准。


评分

参与人数 1蝴蝶豆 +3 收起 理由
STMCU + 3

查看全部评分

回复

使用道具 举报

该用户从未签到

6

主题

14

帖子

0

蝴蝶豆

中级会员

最后登录
2021-1-13
 楼主| 发表于 2018-12-21 10:12:34 | 显示全部楼层
radio2radio 发表于 2018-12-21 00:40
我的精准us延迟是这样得到的:

还有这种操作,厉害了
回复

使用道具 举报

  • TA的每日心情
    开心
    2017-12-6 11:47
  • 签到天数: 1 天

    [LV.1]初来乍到

    49

    主题

    3724

    帖子

    429

    蝴蝶豆

    论坛元老

    最后登录
    2021-8-7
    发表于 2018-12-21 11:07:06 | 显示全部楼层
    本帖最后由 toofree 于 2018-12-21 11:12 编辑

    楼主,设置延时时间长一点。
    就这么个程序,做乘除法都得一段时间,还有程序进出的进栈、出栈时间。或者把IO电平反转放在紧挨着while的前后,看看相隔多长时间。
    另外SystemCoreClock不应该是PUB_DelayInit(4194000)用户指定的吧,除非确定实际时间就是这个,一般是库函数中设置了。

    评分

    参与人数 1蝴蝶豆 +2 收起 理由
    STMCU + 2

    查看全部评分

    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|论坛-意法半导体STM32/STM8技术社区

    GMT+8, 2024-3-29 08:18 , Processed in 0.178881 second(s), 35 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

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