RP2040 C SDK RTC功能使用

RP2040 C SDK RTC功能使用


  • 📍《RP2040 C SDK串口功能使用
  • 🥕RP2040 RTC API官方文档说明:https://www.raspberrypi.com/documentation/pico-sdk/hardware.html#group_hardware_rtc
  • 🥕官方例程参考:https://github.com/raspberrypi/pico-examples

📑RTC 相关API接口函数介绍

  • 🌿void rtc_init (void):初始化rtc。
  • 🌿bool rtc_set_datetime (const datetime_t *t):设置rtc
  • 形参1:
datetime_t t = {
    .year = 2024,
    .month = 9,//注意这里不能写09,编译会报错,可以用16进制:0x09
    .day = 04,
    .dotw = 3, // 0 is Sunday, so 5 is Friday
    .hour = 23,
    .min = 30,
    .sec = 00};
  • 🌿bool rtc_get_datetime (datetime_t *t):获取时间。
  • 形参1:参考上面的。
  • 🌿bool rtc_running (void):查询rtc运行状态。
  • 🌿void rtc_set_alarm (const datetime_t *t, rtc_callback_t user_callback):设置报警中断
  • 形参1:时间句柄。
  • 形参2:回调函数。
  • 🌿void rtc_enable_alarm (void):使能rtc报警。
  • 🌿void rtc_disable_alarm (void):失能rtc报警
✨使用rtc功能外设,需要在CMakeLists.txt文件中,添加hardware_rtc配置
# Add the standard library to the build
target_link_libraries(RP2040_RTC
        pico_stdlib
        hardware_rtc)

📙例程

  • 📘hello_rtc官方给出的使用例程:
/**
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <stdio.h>
#include "hardware/rtc.h"
#include "pico/stdlib.h"
#include "pico/util/datetime.h"

/// \tag::hello_rtc_main[]
int main() {
    stdio_init_all();
    printf("Hello RTC!\n");

    char datetime_buf[256];
    char *datetime_str = &datetime_buf[0];

    // Start on Friday 5th of June 2020 15:45:00
    datetime_t t = {
            .year  = 2020,
            .month = 06,
            .day   = 05,
            .dotw  = 5, // 0 is Sunday, so 5 is Friday
            .hour  = 15,
            .min   = 45,
            .sec   = 00
    };

    // Start the RTC
    rtc_init();
    rtc_set_datetime(&t);

    // clk_sys is >2000x faster than clk_rtc, so datetime is not updated immediately when rtc_get_datetime() is called.
    // tbe delay is up to 3 RTC clock cycles (which is 64us with the default clock settings)
    sleep_us(64);

    // Print the time
    while (true) {
        rtc_get_datetime(&t);
        datetime_to_str(datetime_str, sizeof(datetime_buf), &t);
        printf("\r%s      ", datetime_str);
        sleep_ms(100);
    }
}
  • 📗RTC报警中断使用例程:

每分钟的固定秒数,产生一次报警中断,一次配置重复触发。


/*
  CMSIS-DAP烧录命令:openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c  "adapter speed 5000"-c "program debugprobe.elf verify reset exit"

 jlink命令: openocd -f interface/jlink.cfg -f target/rp2040.cfg  -c  "adapter speed 2000" -c  "program RP2040_RTC.elf verify reset exit"
 */
#include <stdio.h>
#include "pico/stdlib.h"
// #include "hardware/uart.h"
#include "hardware/gpio.h"
#include "hardware/divider.h"
#include "hardware/clocks.h"
#include "hardware/rtc.h"
#include "pico/util/datetime.h"

// GPIO defines
// Example uses GPIO 2
#define GPIO 25

#define BUILTIN_LED PICO_DEFAULT_LED_PIN

#define ALARM_AT_SECONDS 5
#define ALARM_REPEAT_FOREVER true

volatile bool alarmTriggered = false;
bool setAlarmDone = false;
datetime_t t = {
    .year = 2024,
    .month = 9,
    .day = 04,
    .dotw = 3, // 0 is Sunday, so 5 is Friday
    .hour = 23,
    .min = 30,
    .sec = 00};

datetime_t alarmT;

static volatile bool fired = false;

//

// This is ISR. Be careful. No Serial.print here.
void rtcCallback(void)
{
  alarmTriggered = true;
}

void set_RTC_Alarm(datetime_t *alarmTime)
{
  rtc_set_alarm(alarmTime, rtcCallback);
}

void setAlarmOnce(uint8_t alarmSeconds)
{
  rtc_get_datetime(&alarmT);

  if (alarmSeconds > alarmT.sec)
    alarmT.sec = alarmSeconds;
  else
  {
    // Alarm in next minute
    alarmT.sec = alarmSeconds;
    alarmT.min += 1;
  }

  set_RTC_Alarm(&alarmT);

  printf("Set One-time Alarm @ alarmSeconds = %d\n", alarmSeconds);
}

void setAlarmRepeat(uint8_t alarmSeconds)
{

  alarmT.min = alarmT.hour = alarmT.day = alarmT.dotw = alarmT.month = alarmT.year = -1;
  alarmT.sec = (t.sec + ALARM_AT_SECONDS)%60;
  set_RTC_Alarm(&alarmT);
 // irq_set_enabled(RTC_IRQ, true);
   printf("Set Repeatitive Alarm @ alarmSeconds = %d\n", alarmT.sec);
}

void setAlarm()
{
#if ALARM_REPEAT_FOREVER
  setAlarmRepeat(ALARM_AT_SECONDS);
#else
  setAlarmOnce(ALARM_AT_SECONDS);
#endif

  setAlarmDone = true;
}
static void alarm_callback(void)
{
  alarmTriggered = true;
  // datetime_t t = {0};
  rtc_get_datetime(&t);
  char datetime_buf[256];
  char *datetime_str = &datetime_buf[0];
  datetime_to_str(datetime_str, sizeof(datetime_buf), &t);
  printf("Alarm Fired At %s\n", datetime_str);
  stdio_flush();
  alarmT.min = alarmT.hour = alarmT.day = alarmT.dotw = alarmT.month = alarmT.year = -1;
  alarmT.sec = (t.sec + ALARM_AT_SECONDS)%60;


}
int main()
{
  char datetime_buf[256];
  char *datetime_str = &datetime_buf[0];
  stdio_init_all();
  set_sys_clock_khz(133000, true); // 324us
  uint f_clk_rtc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_RTC);
  uint f_clk_sys = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_SYS);
  printf("clk_rtc  = %dkHz\n", f_clk_rtc);
  printf("clk_sys  = %dkHz\n", f_clk_sys);
  // Set up our UART
  //  uart_init(UART_ID, BAUD_RATE);
  // Set the TX and RX pins by using the function select on the GPIO
  // Set datasheet for more information on function select
  //  gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
  //  gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART);
  printf("Hello RTC!\n");

  // Start the RTC
  rtc_init();
  rtc_set_datetime(&t);
  bool rtc_status = rtc_running(); //
  printf("RTC is running = %d\n", rtc_status);

  // rtc_set_alarm (&alarm, &alarm_callback); // Set an alarm for 5 second from now
  // irq_set_enabled(RTC_IRQ, true);
  // irq_set_priority (RTC_IRQ, 1); //设置中断优先级
  sleep_us(64);

  // GPIO initialisation.
  // We will make this GPIO an input, and pull it up by default
  gpio_init(BUILTIN_LED);
  gpio_set_dir(BUILTIN_LED, 1);
  gpio_pull_up(BUILTIN_LED);
  alarmT.min = alarmT.hour = alarmT.day = alarmT.dotw = alarmT.month = alarmT.year = -1;
     // if (!setAlarmDone)
    // {
    //   setAlarm();
    //   printf("Set Repeatitive Alarm @ alarmSeconds = %d\n",alarmT.sec );

    // }
  alarmT.sec = 6;//每1分钟的第6秒报警一次,相对于1分报警一次。
set_RTC_Alarm(&alarmT);
  while (true)
  {
    rtc_get_datetime(&t);
    datetime_to_str(datetime_str, sizeof(datetime_buf), &t);
    printf("\r%s \n", datetime_str);
    stdio_flush();
    sleep_ms(1000);
    gpio_xor_mask(1ul << BUILTIN_LED); // Toggle the LED
    if (alarmTriggered)
    {
      alarmTriggered = false;
      printf("clk_sys = %dkHz,clk_rtc = %dkHz,rtc_status:%d\n", f_clk_sys, rtc_running());//57/30
     printf("Set Repeatitive Alarm @ alarmSeconds = %d\n", alarmT.sec);
    }
  }

  return 0;
}

  • 📗RTC报警中断间隔秒数重复例程:

运行到固定的秒数,产生一次报警中断,如下重复固定秒数,还需要在报警中断后,再次配置一次,下一个间隔时间触发一次。中断后如果不进行配置,则变成每分钟固定秒数触发。


/*
  CMSIS-DAP烧录命令:openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c  "adapter speed 5000"-c "program debugprobe.elf verify reset exit"

 jlink命令: openocd -f interface/jlink.cfg -f target/rp2040.cfg  -c  "adapter speed 2000" -c  "program RP2040_RTC.elf verify reset exit"
 */
#include <stdio.h>
#include "pico/stdlib.h"
// #include "hardware/uart.h"
#include "hardware/gpio.h"
#include "hardware/divider.h"
#include "hardware/clocks.h"
#include "hardware/rtc.h"
#include "pico/util/datetime.h"

// GPIO defines
// Example uses GPIO 2
#define GPIO 25

#define BUILTIN_LED PICO_DEFAULT_LED_PIN

#define ALARM_AT_SECONDS 5
#define ALARM_REPEAT_FOREVER true

volatile bool alarmTriggered = false;
bool setAlarmDone = false;
datetime_t t = {
    .year = 2024,
    .month = 9,
    .day = 04,
    .dotw = 3, // 0 is Sunday, so 5 is Friday
    .hour = 23,
    .min = 30,
    .sec = 00};

datetime_t alarmT;

static volatile bool fired = false;

//

// This is ISR. Be careful. No Serial.print here.
void rtcCallback(void)
{
  alarmTriggered = true;
}

void set_RTC_Alarm(datetime_t *alarmTime)
{
  rtc_set_alarm(alarmTime, rtcCallback);
}

void setAlarmOnce(uint8_t alarmSeconds)
{
  rtc_get_datetime(&alarmT);

  if (alarmSeconds > alarmT.sec)
    alarmT.sec = alarmSeconds;
  else
  {
    // Alarm in next minute
    alarmT.sec = alarmSeconds;
    alarmT.min += 1;
  }

  set_RTC_Alarm(&alarmT);

  printf("Set One-time Alarm @ alarmSeconds = %d\n", alarmSeconds);
}

void setAlarmRepeat(uint8_t alarmSeconds)
{

  alarmT.min = alarmT.hour = alarmT.day = alarmT.dotw = alarmT.month = alarmT.year = -1;
  alarmT.sec = (t.sec + ALARM_AT_SECONDS)%60;
  set_RTC_Alarm(&alarmT);
 // irq_set_enabled(RTC_IRQ, true);
   printf("Set Repeatitive Alarm @ alarmSeconds = %d\n", alarmT.sec);
}

void setAlarm()
{
#if ALARM_REPEAT_FOREVER
  setAlarmRepeat(ALARM_AT_SECONDS);
#else
  setAlarmOnce(ALARM_AT_SECONDS);
#endif

  setAlarmDone = true;
}
static void alarm_callback(void)
{
  alarmTriggered = true;
  // datetime_t t = {0};
  rtc_get_datetime(&t);
  char datetime_buf[256];
  char *datetime_str = &datetime_buf[0];
  datetime_to_str(datetime_str, sizeof(datetime_buf), &t);
  printf("Alarm Fired At %s\n", datetime_str);
  stdio_flush();
  alarmT.min = alarmT.hour = alarmT.day = alarmT.dotw = alarmT.month = alarmT.year = -1;
  alarmT.sec = (t.sec + ALARM_AT_SECONDS)%60;


}
int main()
{
  char datetime_buf[256];
  char *datetime_str = &datetime_buf[0];
  stdio_init_all();
  set_sys_clock_khz(133000, true); // 324us
  uint f_clk_rtc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_RTC);
  uint f_clk_sys = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_SYS);
  printf("clk_rtc  = %dkHz\n", f_clk_rtc);
  printf("clk_sys  = %dkHz\n", f_clk_sys);
  // Set up our UART
  //  uart_init(UART_ID, BAUD_RATE);
  // Set the TX and RX pins by using the function select on the GPIO
  // Set datasheet for more information on function select
  //  gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
  //  gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART);
  printf("Hello RTC!\n");

  // char datetime_buf[256];
  // char *datetime_str = &datetime_buf[0];

  // Start on Friday 5th of June 2020 15:45:00

  // Start the RTC
  rtc_init();
  rtc_set_datetime(&t);
  bool rtc_status = rtc_running(); //
  printf("RTC is running = %d\n", rtc_status);

  // rtc_set_alarm (&alarm, &alarm_callback); // Set an alarm for 5 second from now
  // irq_set_enabled(RTC_IRQ, true);
  // irq_set_priority (RTC_IRQ, 1); //设置中断优先级
  //  clk_sys is >2000x faster than clk_rtc, so datetime is not updated immediately when rtc_get_datetime() is called.
  //  tbe delay is up to 3 RTC clock cycles (which is 64us with the default clock settings)
  sleep_us(64);

  // GPIO initialisation.
  // We will make this GPIO an input, and pull it up by default
  gpio_init(BUILTIN_LED);
  gpio_set_dir(BUILTIN_LED, 1);
  gpio_pull_up(BUILTIN_LED);
  alarmT.min = alarmT.hour = alarmT.day = alarmT.dotw = alarmT.month = alarmT.year = -1;
  alarmT.sec = (t.sec + ALARM_AT_SECONDS)%60;//每间隔5秒钟报警一次
  //alarmT.sec = 6;//每1分钟第6秒报警一次
set_RTC_Alarm(&alarmT);
//setAlarm();
  //rtc_set_alarm(&alarmT, &alarm_callback);
  while (true)
  {
    rtc_get_datetime(&t);
    datetime_to_str(datetime_str, sizeof(datetime_buf), &t);
    printf("\r%s \n", datetime_str);
    stdio_flush();
    sleep_ms(1000);
    gpio_xor_mask(1ul << BUILTIN_LED); // Toggle the LED

    // if (!setAlarmDone)
    // {
    //   setAlarm();
    //   printf("Set Repeatitive Alarm @ alarmSeconds = %d\n",alarmT.sec );

    // }

    if (alarmTriggered)
    {
      alarmTriggered = false;
      printf("clk_sys = %dkHz,clk_rtc = %dkHz,rtc_status:%d\n", f_clk_sys, rtc_running());
      // rtc_set_alarm(&alarmT, &alarm_callback);
      setAlarm();//配置下一次报警时间
    // printf("Set Repeatitive Alarm @ alarmSeconds = %d\n", alarmT.sec);
    }
  }

  return 0;
}

在这里插入图片描述

🔰两者代码配置区别:
  • 🌿每分钟重复触发:
rtc_get_datetime(&alarmT);
  
  alarmT.min = alarmT.hour = alarmT.day = alarmT.dotw = alarmT.month = alarmT.year = -1;
  alarmT.sec =  alarmSeconds;
  set_RTC_Alarm(&alarmT);
  • 🌿间隔秒数重复触发:
 alarmT.min = alarmT.hour = alarmT.day = alarmT.dotw = alarmT.month = alarmT.year = -1;
  alarmT.sec = (t.sec + ALARM_AT_SECONDS)%60;//每间隔5秒钟报警一次

  set_RTC_Alarm(&alarmT);
  
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值