专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
STM32
分享一个us计数器,可测试代码运行时长
2019-12-11 18:29
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
STM32/STM8
12964
10
11
本帖最后由 yanyanyan168 于 2019-4-29 20:08 编辑
从 KEIL MDK 的 Event Recorder 摘出SysTick配置,改成微秒计数器与微秒延时,可以用在M0/M0+/M3/M4等内核MCU上。
应用场景,测试某段代码的运行时长,精确微秒延时。 代码如下,献丑了
typedef struct
{
uint32_t (*init)(void);
void (*set)(uint8_t id); // 设置当前值
uint32_t (*get)(uint8_t id); // 获取与上次的差值
void (*Delay)(uint32_t nus);
}
US_DIFF_TypeDef;
/* SysTick period in cycles */
#ifndef SYSTICK_PERIOD
#define SYSTICK_PERIOD 0x01000000U
#endif
/* SysTick variables */
static volatile uint32_t SysTickCount;
static volatile uint8_t SysTickUpdated;
/* SysTick IRQ handler */
void SysTick_Handler (void) {
SysTickCount += SYSTICK_PERIOD;
SysTickUpdated = 1U;
}
/* Setup SysTick */
uint32_t SysTickSetup (void) {
SysTickCount = 0U;
SysTick->LOAD = SYSTICK_PERIOD - 1U;
SysTick->VAL = 0U;
SysTick->CTRL = SysTick_CTRL_ENABLE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_CLKSOURCE_Msk;
return 1U;
}
/* Get SysTick count */
__STATIC_INLINE uint32_t SysTickGetCount (void) {
uint32_t val;
do {
SysTickUpdated = 0U;
val = SysTickCount;
val += (SYSTICK_PERIOD - 1U) - SysTick->VAL;
} while (SysTickUpdated != 0U);
return (val);
}
#define TIMER_NUM_MAX 10 // 计数器最多可支持9个, 最后一个做延时用
static uint32_t us_count[TIMER_NUM_MAX];
/// 设置计数值初值
void set_current_count(uint8_t id)
{
// my_assert_param(id < TIMER_NUM_MAX);
us_count[id] = SysTickGetCount();
}
// 获取与上一次的差值 返回的是时钟周期数,,转换成微秒需要除以(SystemCoreClock/1000000)
uint32_t get_us_difference(uint8_t id)
{
volatile uint32_t now_tim ;
// my_assert_param(id < TIMER_NUM_MAX);
now_tim = SysTickGetCount();
now_tim -= us_count[id];
return now_tim;
}
// 微秒延时
static void usDelay(uint32_t nus)
{
nus *= (SystemCoreClock/1000000);
set_current_count(TIMER_NUM_MAX-1);
volatile uint32_t now_tim ;
do
{
now_tim = get_us_difference(TIMER_NUM_MAX-1);
}while(now_tim < nus);
}
US_DIFF_TypeDef usDiff =
{
SysTickSetup,
set_current_count,
get_us_difference,
usDelay
};
复制代码
应该方法:
uint32_t us_code_tim; // 代码运行时钟周期数,转换成微秒需要除以(SystemCoreClock/1000000)
int32_t main(void)
{
/* 其它外设初始化 */
usDiff.init();
for(;;)
{
usDiff.set(0);
/* 要测试的代码 */
us_code_tim = usDiff.get(0);
usDiff.Delay(200); // 延时200us
}
}
uint32_t us_tim3; // TIM3中断间隔时钟周期数,,转换成微秒需要除以(SystemCoreClock/1000000)
void TIM3_IRQHandler(void)
{
/* 其它代码 */
us_tim3 = usDiff.get(1); // 第一次不准
usDiff.set(1);
}
复制代码
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
10条回答
honami520
2019-12-12 11:51
这是弄了一个1us的定时器吗?还要进中断,这也太频繁了吧。不如搞个定时器1us计数。然后用查询模式,在一个需要测量的函数或者代码段,的前后都读一下。基本就知道时间了。测量10us级别的也够了。
加载中...
查看其它10个回答
一周热门
更多
>
相关问题
STM32F4上I2C(在PROTEUS中模拟)调试不通的问题
6 个回答
芯片供应紧张,准备换个MCU,MM32L系列替换STM32L系列的怎么样?
7 个回答
STM32同时使用两个串口进行数据收发时数据丢包的问题
5 个回答
STM32F103串口通信死机问题
4 个回答
STM32WLE5CC连接SX1268在LoRa模式下能与 SX1278互通吗?
2 个回答
相关文章
ST公司第一款无线低功耗单片机模块有效提高物联网设计生产效率
0个评论
如何实现对单片机寄存器的访问
0个评论
通过USB用STM32片内自带Bootloader下载程序及注意事项
0个评论
欲练此功必先自宫之STM32汇编启动,放慢是为了更好的前行
0个评论
×
关闭
采纳回答
向帮助了您的知道网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
STM32
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
×
付费偷看金额在0.1-10元之间
确定
×
关闭
您已邀请
0
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
一周热门 更多>