STM32单片机示例:64位全局时间戳发生器

文章目录

  • 目的
  • 基础说明
  • 测试代码
  • 总结
  • 示例链接

目的

STM32H743 / H750 系列的芯片有一个64位的全局时间戳发生器( Global timestamp generator ),这篇文章将对它的使用做个记录。

基础说明

全局时间戳发生器相关的内容可以参考官方参考手册:
STM32单片机示例:64位全局时间戳发生器_第1张图片

TGS时钟来源与APB总线时钟,这就是TGS计数器时钟了,并且用于TGS计数时没法对其进行分频操作。我们使用TGS时通常只要开启和停止计数器、清除和读取计数值几个操作,直接使用寄存器操作即可。

测试代码

int main(void)
{
	HAL_Init();
	MPU_Config();
	SystemClock_Config();
	MX_GPIO_Init();

    // 全局时间戳发生器相关寄存器
    #define TSG_CNTCR *(volatile unsigned int *)0x5C005000  // 计数器控制寄存器
    #define TSG_CNTCVL *(volatile unsigned int *)0x5C005008 // 当前计数器计数值低字寄存器
    #define TSG_CNTCVU *(volatile unsigned int *)0x5C00500C // 当前计数器计数值高字寄存器

    // 初始化并启动全局时间戳发生器
    TSG_CNTCR = 0x00000000; // 停止计数器
    TSG_CNTCVL = 0;         // 清空计数器计数值低字
    TSG_CNTCVU = 0;         // 清空计数器计数值高字
    TSG_CNTCR = 0x00000001; // 启动计数器

    uint64_t pred = 0;
    while (1)
    {
        uint64_t d; // 用于保存当前时间
        uint32_t du = TSG_CNTCVU; // 读取计数器高字
        uint32_t dl = TSG_CNTCVL; // 读取计数器低字

        if (du == TSG_CNTCVU) // 和前次读取TSG_CNTCVU时, TSG_CNTCVL并未发生溢出
        {
            d = ((uint64_t)du << 32) + dl;
        }
        else // 和前次读取TSG_CNTCVU时, TSG_CNTCVL发生溢出
        {
            d = ((uint64_t)TSG_CNTCVU << 32) + TSG_CNTCVL;
        }

        // TSG是接在APB总线上的,目前设置下APB总线速度是240MHz
        // 因此每计数240000为1ms,下面代码下IO口每1ms变化一次
        if ((d - pred) > 240000)
        {
            pred = d;                              // 保存当前时间
            HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_4); // 翻转IO口
        }
    }
}

上面代码的功能是启动全局时间戳发生器,然后根据时间每1ms翻转PA4的输出电平,使用示波器或者逻辑分析仪抓取可以看到测试结果。

总结

TSG没法对时钟源进行分频设置,也不是所有系列单片机都有该功能的,很多时候并没有定时器来的好用。并且这里并没有测试开启ST-Link调试时该功能是否会有冲突。

示例链接

仓库地址: https://github.com/NaisuXu/STM32_MCU_Examples

本示例为仓库中 Global_Timestamp_Generator_H750

你可能感兴趣的:(RTOS与单片机相关,单片机,STM32,时间戳,定时器,嵌入式)