0

RP2040(树莓派Pico) 普通定时器&RTC

 3 years ago
source link: https://www.taterli.com/7561/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

RP2040(树莓派Pico) 普通定时器&RTC

  • TaterLi
  • 2021年2月3日2021年2月3日

定时器功能也很基础,而且只有一个,主要功能如下:

  • 64位计数器 (频率固定1MHz,所以要好几千年才能溢出!)
  • 4个闹钟 (闹钟是只匹配低32B,最大间隔4295秒.)
  • 寄存器自带映射,所以多个处理器同时访问也不用考虑竞争问题. (无需考虑竞争问题.)

其中ALARM功能只会发起一次中断,中断发生后就会清除ARMED位,所有函数都有他的毫秒版本和微秒版本.

struct repeating_timer timer;

int main() {
    // 设置两秒之后发起一次中断.
    add_alarm_in_ms(2000, alarm_callback, NULL, false);

    // 参数1:定时时间 参数2:回调函数 参数3:携带数据 参数4:定时器结构体
    // 参数1 > 0 则在回调函数执行结束后再开启下一次定时,这样每次间隔可能不一样.
    // 参数1 < 0 则在回调函数进入时就开启下一次定时器,这样可能任务还没完成下一次定时又来了.
    // 通过参数3可以多个定时器共享一个回调.
    add_repeating_timer_ms(500, repeating_timer_callback, NULL, &timer);

    // 取消周期定时器
    bool cancelled = cancel_repeating_timer(&timer);
}

另外的两个定时器例子,其中periodic_sampler演示了队列的使用,启动了一个间隔定时器,timer_lowlevel演示了从底层访问寄存器的方法来控制定时器,另外,默认的ALARM函数也不能指定用哪个ALARM,而是内部Pool自动轮询.但是由于底层的一些延迟函数等等也用到了定时器,所以不推荐使用这个方法,根据源码来看,以后可能还会出多定时器版本的芯片.

RTC和定时器有相似的功能,都可以发起ALARM,只不过是被专用设计用来储存时间,因此可以处理闰年啊之类的问题,没有专用的RTC引脚,在低功耗模式下工作需要外部输入时钟(听起来就有点扯,但这是真!),没有专门的RTC引脚,也没有专用的RTC电源,因此… (就不用多说了!)

调用rtc_init就可以使用RTC,至于复位后会怎样?我不知道,因为我没找到复位的方法?是RUN引脚还是什么?rtc_set_datetime设置时间,而rtc_get_datetime获取时间,RTC寄存器没特殊保护.从hello_rtc能获取到不少内容,特别注意的是,他的时钟引用于XOSC,这个时钟足足1000ppm,每天就可能误差86.4秒.

比较关键是rtc_set_alarm函数,只有1个ALARM,设定方法和Linux的cron很类似.

datetime_t alarm = {
    .year  = -1,
    .month = -1,
    .day   = -1,
    .dotw  = -1,
    .hour  = -1,
    .min   = -1,
    .sec   = 30
};

rtc_set_alarm(&alarm, &alarm_callback);

就像上面的代码,-1即任意匹配,上面的代码会在每年每月每天不管星期几每小时每分30秒发起中断,而且是周期性的,如果全部数值都是确定值,则发生一次后再也不会被匹配到,就是一次性.

发表评论 取消回复

邮箱地址不会被公开。 必填项已用*标注

评论

名称 *

电子邮件 *

站点


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK