micropython stm32f411 RTC时钟任务调度器

micropython stm32f411 RTC时钟任务调度器

​ 如下图,F4的外部低速时钟为32.768K,经过第一个RTC_PRER(默认128分频)分频变为256Hz,也就是RTC时钟里的亚秒,然后经过第二个RTC_PRER(默认256分频)分频变为1Hz,也就是1秒。我们这里用到的是亚秒,也就是一个256Hz的频率

请添加图片描述

​ 初始化RTC时钟之后,在主函数循环中不断获取当前时间,然后将亚秒的值赋给一个变量new,将变量new与变量old进行对比,如果不同,时间刻度(1/256秒)加一,将new的值赋给old,然后重新获取亚秒的值赋给new,当计时达到预定数值时,比如128(也就是500ms)调用一次预定函数。

核心代码

from pyb import Pin,LED,delay,Timer,RTC


# RTC时钟初始化Start
rtc=RTC()
rtc.datetime((2023,04,26,03,10,0,0,0)) # 年 月 日 星期 时 分 秒 亚秒
# RTC时钟初始化End

# 任务调度器Start
buf1=rtc.datetime()
old=0
new=buf1[7] # 亚秒的频率为256Hz
times=0
# 任务调度器End

# 每500ms需要调用一次函数Start
def func_128():
    pass
# 每500ms需要调用一次函数End

# 每250ms需要调用一次函数Start
def func_64():
    pass
# 每250ms需要调用一次函数End

# 每125ms需要调用一次函数Start
def func_32():
    pass
# 每125ms需要调用一次函数End

# 每62.5ms需要调用一次函数Start
def func_16():
    pass
# 每62.5ms需要调用一次函数End

# 每15.625ms需要调用一次函数Start
def func_4():
    pass
# 每15.625ms需要调用一次函数End

while True:
    buf1=rtc.datetime()
    new=buf1[7]
    if new!=old:
        old=new
        times=times+1
        if (times%128)==0:
            flag_128=1
        if (times%64)==0:
            flag_64=1
        if (times%32)==0:
            flag_32=1
        if (times%8)==0:
            flag_16=1
        if (times%3)==0:
            flag_4=1

    # 计数器归零Start
    if times>=5120: # 最大计时5120/256=20s
        times=0
    # 计数器归零End

    if flag_128==1:
        func_128()
        flag_128=0
    if flag_64==1:
        func_64()
        flag_64=0
    if flag_32==1:
        func_32()
        flag_32=0
    if flag_16==1:
        func_16()
        flag_16=0
    if flag_4==1:
        func_4()
        flag_4=0


​ 此使用RTC时钟作为任务调度器的时钟源有一定缺陷,首先时RTC的频率太低,计时不太准确,实际测试的时候,RTC亚秒的频率为250到270的一个大概值,其次是需要在循环里不断检测,当代码量增多时,检测不及时,会出现漏拍情况,减慢程序运行速度。

时RTC的频率太低,计时不太准确,实际测试的时候,RTC亚秒的频率为250到270的一个大概值,其次是需要在循环里不断检测,当代码量增多时,检测不及时,会出现漏拍情况,减慢程序运行速度。

​ 这里还可以采用TIM定时器作为时钟源,首先是频率较高。还可以通过定时器中断实现时间前进效果,不需要在主函数判断,提供程序运行速度。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32F407的RTC实时时钟可以通过以下步骤进行设置: 1. 打开PWR和BKP外设时钟。 2. 配置RTC时钟,使其与LSE低速外部晶振同步。 3. 配置RTC预分频和计数,以确定RTC时钟的更新频率。 4. 配置RTC时钟日历,包括时间和日期。 5. 使能RTC时钟RTC中断,以便在时间更新时进行相应处理。 下面是一个简单的示例代码,用于初始化RTC实时时钟: ```c RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); // 使能PWR外设时钟 PWR_BackupAccessCmd(ENABLE); // 允许修改RTC寄存 // 选择LSE作为RTC时钟源 RCC_LSEConfig(RCC_LSE_ON); while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET); // 使能RTC外设时钟 RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); RCC_RTCCLKCmd(ENABLE); // 配置RTC预分频和计数 RTC_InitStructure.RTC_AsynchPrediv = 0x7F; // 异步预分频RTC_InitStructure.RTC_SynchPrediv = 0xFF; // 同步预分频RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; // 24小时格式 RTC_Init(&RTC_InitStructure); // 配置RTC时钟日历 RTC_DateTypeDef RTC_DateStructure; RTC_TimeTypeDef RTC_TimeStructure; RTC_DateStructure.RTC_Year = 0x21; // 年份 RTC_DateStructure.RTC_Month = RTC_Month_November; // 月份 RTC_DateStructure.RTC_Date = 0x01; // 日 RTC_DateStructure.RTC_WeekDay = RTC_Weekday_Sunday; // 星期几 RTC_SetDate(RTC_Format_BCD, &RTC_DateStructure); RTC_TimeStructure.RTC_Hours = 0x10; // 小时 RTC_TimeStructure.RTC_Minutes = 0x30; // 分钟 RTC_TimeStructure.RTC_Seconds = 0x00; // 秒 RTC_SetTime(RTC_Format_BCD, &RTC_TimeStructure); // 使能RTC中断 RTC_ITConfig(RTC_IT_SEC, ENABLE); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); // 使能RTC时钟 RTC_WaitForSynchro(); RTC_Cmd(ENABLE); ``` 在上述代码中,我们首先打开PWR和BKP外设时钟,然后配置RTC时钟使用LSE低速外部晶振。接下来,我们设置RTC的异步预分频和同步预分频,以确定RTC时钟的更新频率。然后,我们配置RTC时钟日历,包括时间和日期。最后,我们使能RTC中断,以便在时间更新时进行相应处理,并启用RTC时钟

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值