#include "includes.h"
#include "Timestamp.h"
/*
************************************************************************************************************************
* 时间戳相关寄存器定义
************************************************************************************************************************
*/
/*
在Cortex-M3里面有一个外设叫DWT(Data Watchpoint and Trace),该外设有一个32位的寄存器叫CYCCNT,它是一个向上的
计数器,记录的是内核时钟运行的个数,最长能记录的时间为:
1、60s=2的32次方/72000000(stm32F103内核频率为72M,内核跳一次的时间大概为1/72M=14ns)
2、25.56s=2的32次方/168000000(stm32F407内核频率为168M,内核跳一次的时间大概为1/168M=5.9524ns)
当CYCCNT溢出之后,会清0重新开始向上计数。
使能CYCCNT计数的操作步骤:
1、先使能DWT外设,这个由另外内核调试寄存器DEMCR的位24控制,写1使能
2、使能CYCCNT寄存器之前,先清0
3、使能CYCCNT寄存器,这个由DWT_CTRL(代码上宏定义为DWT_CR)的位0控制,写1使能
*/
/*
************************************************************************************************************************
* 使用说明
************************************************************************************************************************
*/
// typedef struct {
// u32 time_old;
// u32 time_now;
// u32 time_run;
// u32 time_runmax;
// u32 time_runmin;
// int timetype; //1为ms,2为us
// float time_run_f;
// float time_runmax_f;
// float time_runmin_f;
// int flag_bit; //为0时清空当前最大最小值,并自动置位为1
//} TimeStamp;
/* TimeStamp timetext = {0,0,0,0,0xffffffff,1,0.0,0.0,1}; //参数初始化
Timestamp_Start(&timetext); //放于测试程序片段之前
//测试程序
Timestamp_End(&timetext);//放于测试程序片段之之后
*/
#define DWT_CR *(uint32_t *)0xE0001000
#define DWT_CYCCNT *(uint32_t *)0xE0001004
#define DEM_CR *(uint32_t *)0xE000EDFC
#define DEM_CR_TRCENA (1 << 24)
#define DWT_CR_CYCCNTENA (1 << 0)
/* 初始化时间戳 */
void CPU_TS_TmrInit(void)
{
/* 使能DWT外设 */
DEM_CR |= (uint32_t)DEM_CR_TRCENA;
/* DWT CYCCNT寄存器计数清0 */
DWT_CYCCNT = (uint32_t)0u;
/* 使能Cortex-M3 DWT CYCCNT寄存器 */
DWT_CR |= (uint32_t)DWT_CR_CYCCNTENA;
}
uint32_t OS_TS_GET(void)
{
return ((uint32_t)DWT_CYCCNT);
}
/* CPU相关初始化 */
void CPU_Init (void)
{
/* 初始化时间戳 */
CPU_TS_TmrInit();
}
float time_u32tofloat(int timetype,int time)
{ //time为内核时钟运行的个数
switch(timetype)
{
case 1 : return ((float)time*5.9524/1000000); //ms 主频168M,每个CPU时钟周期为1/168M约等于5.9纳秒
break;
case 2 : return (((float)time*5.9524/1000)); //us
break;
default : return(0);
break;
}
}
uint32_t maxruntime(int time_now,int time_max , int flag_bit)
{
if(time_now > time_max)
{
time_max = time_now *(flag_bit);
}
return time_max;
}
/* 放在程序片段之前,记录时间戳*/
void Timestamp_Start(TimeStamp *para)
{
CPU_Init();
para->time_old = OS_TS_GET();
}
/* 放在程序片段之后,记录时间戳*/
void Timestamp_End(TimeStamp *para)
{
para->time_now = OS_TS_GET();
//para->time_runmax = maxruntime(para->time_now, para->time_runmax,para->flag_bit);
para->time_run = para->time_now - para->time_old;
if((para->time_run > para->time_runmax)&& para->flag_bit)
{
para->time_runmax = para->time_run ;
}
if((para->time_run < para->time_runmin)&& para->flag_bit)
{
para->time_runmin = para->time_run ;
}
if(para->flag_bit ==0)
{
para->time_runmax = 0;
para->time_runmin = 0xffffffff;
para->flag_bit = 1;
}
para->time_run_f = time_u32tofloat(para->timetype, para->time_run);
para->time_runmax_f = time_u32tofloat(para->timetype,para->time_runmax);
para->time_runmin_f = time_u32tofloat(para->timetype,para->time_runmin);
}
评论0