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

目的

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

基础说明

全局时间戳发生器相关的内容可以参考官方参考手册:
在这里插入图片描述

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

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
可以使用Java中的Calendar和TimeZone类来获取美国时区当天的00:00:00时间戳和23:59:59时间戳。具体步骤如下: 1.将时间戳转换为Date对象。 2.创建一个Calendar对象,并将其时区设置为美国时区。 3.将Calendar对象的时间设置为步骤1中的Date对象。 4.将Calendar对象的时间设置为当天的00:00:00,并获取其时间戳。 5.将Calendar对象的时间设置为当天的23:59:59,并获取其时间戳。 下面是Java代码示例: ```java import java.util.Calendar; import java.util.TimeZone; public class Main { public static void main(String[] args) { long timestamp = 1629345600; // 时间戳,单位为秒 // 将时间戳转换为Date对象 Calendar calendar = Calendar.getInstance(); calendar.setTimeZone(TimeZone.getTimeZone("UTC")); calendar.setTimeInMillis(timestamp * 1000L); System.out.println("Date: " + calendar.getTime()); // 创建一个Calendar对象,并将其时区设置为美国时区 Calendar usCalendar = Calendar.getInstance(TimeZone.getTimeZone("America/New_York")); usCalendar.setTimeInMillis(calendar.getTimeInMillis()); // 将Calendar对象的时间设置为当天的00:00:00,并获取其时间戳 usCalendar.set(Calendar.HOUR_OF_DAY, 0); usCalendar.set(Calendar.MINUTE, 0); usCalendar.set(Calendar.SECOND, 0); long startTimestamp = usCalendar.getTimeInMillis() / 1000L; System.out.println("Start timestamp: " + startTimestamp); // 将Calendar对象的时间设置为当天的23:59:59,并获取其时间戳 usCalendar.set(Calendar.HOUR_OF_DAY, 23); usCalendar.set(Calendar.MINUTE, 59); usCalendar.set(Calendar.SECOND, 59); long endTimestamp = usCalendar.getTimeInMillis() / 1000L; System.out.println("End timestamp: " + endTimestamp); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Naisu Xu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值