STM32F4实时时间精确到ms

开发板:STM32F407

1.目的:在屏幕上能显示的实时时间精确到ms,如 时 :分:秒:毫秒;

2.方式:RTC结合systick定时器,由于RTC只能为秒级,所以毫秒需要利用systick定时器来产生;

3.代码:

(1)首先RTC日历的例程官方都有提供,此处就不赘述了,这里重点讲有关systick产生毫秒计时的部分;

(2)main.c

    SysTick_Init();      //SysTick 初始化函数,在初始函数中将中断设置为1ms中断一次
    while(1){
            RTC_TimeAndDate_Show();     //RTC时钟显示
        }

在SysTick 的中断服务函数 SysTick_Handler()中添加如下代码:

if(x==1000){         //x初值为0,为ms计次,1ms中断一次,中断1000次为1秒;
        s=s+1;          
        x=0;
        if(s==60)      //s初值为0,为s计次,s的设定是为了与RTC产生的s作对比,验证其是否同步以及准确性
            s=0;
    }
    sprintf(LCDTemp5,"The MS:%0.3d",x);          //在屏幕上打印毫秒
    ILI9806G_DispStringLine_EN(LINE(8),LCDTemp5);
    x++;

}

为了减少频繁的ms打印对systick秒的影响,方便与RTC输出的秒做比较,此处将秒s设置为全局变量在RTC_TimeAndDate_Show()函数中打印。

4.结果

由屏幕显示可以发现,systick定时器产生的秒与RTC输出的秒同步,毫秒也可正常打印。

注:在使用GPS时钟源与RTC精度对时时,要在RTC加一个逻辑(如果秒数大于30时分加一否则直接清零)这样时钟源一个信号来分钟可正常运作,否则很可能出现分不走的情况。

 

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,对于STM32F4系列,您可以使用其内部的TIM定时器模块来实现精确定时1us和1ms的功能。下面是使用HAL库编写的示例代码: 1. 精确定时1us ```c /* 定时器配置 */ TIM_HandleTypeDef htim; void TIM_Config(void) { TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; htim.Instance = TIM2; htim.Init.Prescaler = (SystemCoreClock / 1000000) - 1; // 设置时钟预分频,将系统时钟分频为1MHz htim.Init.CounterMode = TIM_COUNTERMODE_UP; htim.Init.Period = 0xFFFFFFFF; // 设置计数器自动重载值为最大值 htim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; HAL_TIM_Base_Init(&htim); sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; HAL_TIM_ConfigClockSource(&htim, &sClockSourceConfig); sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; HAL_TIMEx_MasterConfigSynchronization(&htim, &sMasterConfig); HAL_TIM_Base_Start(&htim); // 启动定时器 } /* 等待1us */ void Delay_1us(void) { uint32_t start = __HAL_TIM_GET_COUNTER(&htim); while((__HAL_TIM_GET_COUNTER(&htim) - start) < 1); } ``` 在上述代码中,我们使用了TIM2定时器模块,将时钟预分频设置为SystemCoreClock / 1000000,即1MHz,这样每计数1次就是1us。然后将计数器自动重载值设置为0xFFFFFFFF,这样定时器可以一直计数,不会因为计数溢出而停止。最后启动定时器,就可以开始计时了。在Delay_1us函数中,我们使用了__HAL_TIM_GET_COUNTER(&htim)来获取当前计数器的值,然后进行等待。 2. 精确定时1ms ```c /* 定时器配置 */ TIM_HandleTypeDef htim; void TIM_Config(void) { TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; htim.Instance = TIM2; htim.Init.Prescaler = (SystemCoreClock / 1000) - 1; // 设置时钟预分频,将系统时钟分频为1kHz htim.Init.CounterMode = TIM_COUNTERMODE_UP; htim.Init.Period = 1000 - 1; // 设置计数器自动重载值为999,这样每计数1000次就是1ms htim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; HAL_TIM_Base_Init(&htim); sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; HAL_TIM_ConfigClockSource(&htim, &sClockSourceConfig); sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; HAL_TIMEx_MasterConfigSynchronization(&htim, &sMasterConfig); HAL_TIM_Base_Start(&htim); // 启动定时器 } /* 等待1ms */ void Delay_1ms(void) { uint32_t start = __HAL_TIM_GET_COUNTER(&htim); while((__HAL_TIM_GET_COUNTER(&htim) - start) < 1000); } ``` 在上述代码中,我们使用了同样的TIM2定时器模块,将时钟预分频设置为SystemCoreClock / 1000,即1kHz,这样每计数1000次就是1ms。然后将计数器自动重载值设置为999,这样定时器可以在每计数1000次时自动重载,并触发定时器中断或事件。最后启动定时器,就可以开始计时了。在Delay_1ms函数中,我们同样使用了__HAL_TIM_GET_COUNTER(&htim)来获取当前计数器的值,然后进行等待。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值