硬汉嵌入式论坛

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

[STM32H7] 使用DWT中的时钟节拍解决短延时问题,目前已经时间在GD32E103,希望大家指点!

[复制链接]

4

主题

25

回帖

37

积分

新手上路

积分
37
发表于 2022-10-7 16:47:45 | 显示全部楼层 |阅读模式
本帖最后由 yjvijfhvk 于 2022-10-8 11:31 编辑


[C] 纯文本查看 复制代码
#include<stdio.h>

static unsigned int s_u32Speed;                //DEBUG Stopwatch stop cycle counter value

#define DEMCR_TRCENA    0x01000000

/* Core Debug registers */
#define DEMCR           (*((volatile unsigned int *)0xE000EDFC))
#define DWT_CTRL        (*(volatile unsigned int *)0xe0001000)
#define CYCCNTENA       (1<<0)
#define DWT_CYCCNT      ((volatile unsigned int *)0xE0001004)
#define CPU_CYCLES      *DWT_CYCCNT
//#define CLK_SPEED        72000000 // EXAMPLE for CortexM4, EDIT as needed

/*****************************************************************************
 Prototype    : i32DWT_IfSupport
 Description  : 检测芯片是否支持DWT
 Input        : void  
 Output       : None
 Return Value : 
 Calls        : 
 Called By    : 
 
  History        :
  1.Date         : 2022/10/7
    Author       : liusuchao
    Modification : Created function

*****************************************************************************/
int i32DWT_IfSupport(void){

        if(DWT_CTRL == 0x00)
                return -1;
        return 0;
}

/*****************************************************************************
 Prototype    : u32DWT_Getticks
 Description  : 获取失踪周期
 Input        : void  
 Output       : None
 Return Value : unsigned
 Calls        : 
 Called By    : 
 
  History        :
  1.Date         : 2022/10/7
    Author       : liusuchao
    Modification : Created function

*****************************************************************************/
unsigned int u32DWT_Getticks(void)
{
    return CPU_CYCLES;
}

/*****************************************************************************
 Prototype    : vDWT_Init
 Description  : 初始化DWT
 Input        : unsigned int u32M  
 Output       : None
 Return Value : 
 Calls        : 
 Called By    : 
 
  History        :
  1.Date         : 2022/10/7
    Author       : liusuchao
    Modification : Created function

*****************************************************************************/
void vDWT_Init(unsigned int u32M)
{
        s_u32Speed = u32M *1000000;
    /* Enable DWT */
    DEMCR |= DEMCR_TRCENA; 
    *DWT_CYCCNT = 0;             
    /* Enable CPU cycle counter */
    DWT_CTRL |= CYCCNTENA;
        
}

/*****************************************************************************
 Prototype    : vDWT_Delay
 Description  : 延时函数,我一般会用示波器测试一下 72M时钟 vDWT_Delay(300) = 5us
 Input        : unsigned int ticks  
 Output       : None
 Return Value : 
 Calls        : 
 Called By    : 
 
  History        :
  1.Date         : 2022/10/7
    Author       : liusuchao
    Modification : Created function

*****************************************************************************/
void vDWT_Delay(unsigned int ticks)
{
    unsigned int end_ticks = ticks + u32DWT_Getticks();
    while(1)
    {
                if (u32DWT_Getticks() >= end_ticks)
                        break;
    }
}

/*****************************************************************************
 Prototype    : u32DWT_CalcNanosecondsFromStopwatch
 Description  : 用于计算程序执行时间
 Input        : unsigned int u32StopCount   
                unsigned int u32StartCount  
 Output       : None
 Return Value : unsigned
 Calls        : 
 Called By    : 
 
  History        :
  1.Date         : 2022/10/7
    Author       : liusuchao
    Modification : Created function

*****************************************************************************/
unsigned int u32DWT_CalcNanosecondsFromStopwatch(unsigned int u32StopCount, unsigned int u32StartCount)
{
    unsigned int nDiffTicks;
    unsigned int nSystemCoreTicksPerMicrosec;

    // Convert (clk speed per sec) to (clk speed per microsec)
    nSystemCoreTicksPerMicrosec = s_u32Speed / 1000000;

    // Elapsed ticks
    nDiffTicks = u32StopCount - u32StartCount;

    // Elapsed nanosec = 1000 * (ticks-elapsed / clock-ticks in a microsec)
    return 1000 * nDiffTicks / nSystemCoreTicksPerMicrosec;
} 

image.png
回复

使用道具 举报

3

主题

337

回帖

346

积分

高级会员

积分
346
发表于 2022-10-8 10:45:24 | 显示全部楼层
本帖最后由 glory 于 2022-10-8 10:46 编辑

vDWT_Delay()明显有漏洞啊,就是当end_ticks整数溢出时,立马就break了。
改成这样,就不会有漏洞了:
[C] 纯文本查看 复制代码
void vDWT_Delay(unsigned int ticks)
{
    unsigned int tstart = u32DWT_Getticks();
    while(1)
    {
        if ((u32DWT_Getticks() - tstart) >= ticks)
            break;
    }
}
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106978
QQ
发表于 2022-10-8 00:43:31 | 显示全部楼层
参考我这个,看看是微小误差还是怎么个情况。可以IO翻转实际测量下

DWT实现一个精确微秒延迟的参考例程
https://www.armbbs.cn/forum.php? ... 9128&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

210

主题

1045

回帖

1685

积分

至尊会员

More we do, more we can do.

积分
1685
发表于 2022-10-8 09:28:08 | 显示全部楼层
看标题有点像看门狗,原来是打错了字。操作系统上怎么解决不可重入的问题?
回复

使用道具 举报

4

主题

25

回帖

37

积分

新手上路

积分
37
 楼主| 发表于 2022-10-8 10:06:07 | 显示全部楼层
本帖最后由 yjvijfhvk 于 2022-10-8 11:29 编辑
emwin 发表于 2022-10-8 09:28
看标题有点像看门狗,原来是打错了字。操作系统上怎么解决不可重入的问题?

是的,打错字了。我们论坛好像不可以重新修改标题吧?目前我用的是伪操作系统(状态机),没考虑可重入的问题。
回复

使用道具 举报

4

主题

25

回帖

37

积分

新手上路

积分
37
 楼主| 发表于 2022-10-8 11:28:17 | 显示全部楼层
glory 发表于 2022-10-8 10:45
vDWT_Delay()明显有漏洞啊,就是当end_ticks整数溢出时,立马就break了。
改成这样,就不会有漏洞了:
[m ...

谢谢,大佬扶正!确实有你说的这个问题。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-13 01:47 , Processed in 0.174286 second(s), 30 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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