【野火】完成延时模块自己测试基于麒麟座

#ifndef __GDWT_DELAY_H
#define __GDWT_DELAY_H

//#include "stm32f7xx.h"
//#include "stm32l4xx.h"
#include "stm32f1xx.h"



HAL_StatusTypeDef GHAL_InitTick(uint32_t TickPriority);


void CPU_TS_Tmr_Delay_US(uint32_t us);//最大延时值为8秒


#endif 
#include "gdwt_delay.h"   

/* 获取内核时钟频率 */
#define GET_CPU_ClkFreq()       HAL_RCC_GetSysClockFreq()


/*
**********************************************************************
*         时间戳相关寄存器定义
**********************************************************************
*/
/*
 在Cortex-M里面有一个外设叫DWT(Data Watchpoint and Trace),
 该外设有一个32位的寄存器叫CYCCNT,它是一个向上的计数器,
 记录的是内核时钟运行的个数,最长能记录的时间为:
 10.74s=2的32次方/400000000
 (假设内核频率为400M,内核跳一次的时间大概为1/400M=2.5ns)
 当CYCCNT溢出之后,会清0重新开始向上计数。
 使能CYCCNT计数的操作步骤:
 1、先使能DWT外设,这个由另外内核调试寄存器DEMCR的位24控制,写1使能
 2、使能CYCCNT寄存器之前,先清0
 3、使能CYCCNT寄存器,这个由DWT_CTRL(代码上宏定义为DWT_CR)的位0控制,写1使能
 */

#define  DEM_CR      *(__IO uint32_t *)0xE000EDFC
#define  DEM_CR_TRCENA                   (1 << 24)


#define  DWT_CR      *(__IO uint32_t *)0xE0001000
#define  DWT_CYCCNT  *(__IO uint32_t *)0xE0001004
#define  DWT_CR_CYCCNTENA                (1 <<  0)


/**
  * @brief  初始化时间戳
  * @param  无
  * @retval 无
  * @note   使用延时函数前,必须调用本函数
  *****注意 MX已经有了__weak这个函数*******
  */
HAL_StatusTypeDef GHAL_InitTick(uint32_t TickPriority)
{
    /* 使能DWT外设 */
    DEM_CR |= (uint32_t)DEM_CR_TRCENA;                

    /* DWT CYCCNT寄存器计数清0 */
    DWT_CYCCNT = (uint32_t)0u;

    /* 使能Cortex-M DWT CYCCNT寄存器 */
    DWT_CR |= (uint32_t)DWT_CR_CYCCNTENA;
  
    return HAL_OK;
}


/**
  * @brief  读取当前时间戳
  * @param  无
  * @retval 当前时间戳,即DWT_CYCCNT寄存器的值
  */
uint32_t CPU_TS_TmrRd(void)
{        
  return ((uint32_t)DWT_CYCCNT);
}


/**
  * @brief  采用CPU的内部计数实现精确延时,32位计数器
  * @param  us : 延迟长度,单位1 us
  * @retval 无
  * @note   使用本函数前必须先调用CPU_TS_TmrInit函数使能计数器,
            或使能宏CPU_TS_INIT_IN_DELAY_FUNCTION
            最大延时值为8秒,即8*1000*1000
  */
  uint32_t told,tnow,tcnt=0;
void CPU_TS_Tmr_Delay_US(uint32_t us)
{
  uint32_t ticks;


  
  ticks = us * (GET_CPU_ClkFreq() / 1000000);  /* 需要的节拍数 */      
  tcnt = 0;
  told = (uint32_t)CPU_TS_TmrRd();         /* 刚进入时的计数器值此时0XA6 */

  while(1)
  {
    tnow = (uint32_t)CPU_TS_TmrRd(); //此时是0XA9
    if(tnow != told)
    { 
        /* 32位计数器是递增计数器 */    
      if(tnow > told)
      {
        tcnt += tnow - told;  
      }
      /* 重新装载 */
      else 
      {
        tcnt += UINT32_MAX - told + tnow; 
      } 
      
      told = tnow;

      /*时间超过/等于要延迟的时间,则退出 */
      if(tcnt >= ticks)break;
    }  
  }
}

/*********************************************END OF FILE**********************/

测试main

    GHAL_InitTick(0);

  while (1)
  {

        LEDPC78TESTE();

  }

 

 

void LEDPC78TESTE(void)
{
    uint32_t value ;

    value = GReadGPIOOutput(GPIOC);
    value ^=0X0180;
    GWriteGPIOOutput(GPIOC,value);
    CPU_TS_Tmr_Delay_US(1000000);
}

可以看到和HAL_DELAY(1000)效果差不多1S一次

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值