Timer-定时
RP2040 由 Raspberry Pi 设计,具有双核 Arm Cortex-M0+ 处理器和 264KB 内部 RAM,并支持高达 16MB 的片外闪存。 广泛的灵活 I/O 选项包括 I2C、SPI 和独特的可编程 I/O (PIO)。
本实例将演示如何使用Timer的定时中断功能。
1、Timer介绍
系统计时器旨在为软件提供全局时基。 RP2040 具有许多其他可编程计数器资源,可以提供定期中断或触发 DMA 传输。
- PWM包含8个16 位可编程计数器,以最高系统速度运行,可以生成中断,并且可以通过 DMA 连续重新编程,或触发 DMA 传输到其他外设。
- 8个PIO 状态机可以以系统速度对32位值进行计数,并产生中断。
- DMA有四个内部起搏定时器,它们以固定的时间间隔触发传输。
- 每个Cortex-M0+内核都有一个标准的24位SysTick计时器,用于计算微秒滴答或系统时钟。
Raspberry Pi Pico SDK提供对计时器硬件的中级访问。它使用硬件计时器提供更高级别的功能。RP2040 上的定时器外设支持以下功能:
- 单 64位计数器,每微秒递增一次
- 锁存计数器的两级读取,用于通过 32 位总线进行无竞争读取
- 四个闹钟(Alarm):计数器低32位匹配,匹配时 IRQ。
默认情况下,定时器使用从clk_ref 派生的看门狗中生成的一微秒参考。
定时器有4个闹钟,可以为每个闹钟输出一个单独的中断。 闹钟与64位计数器的低 32 位匹配,这意味着它们最多可以在未来 2^32 微秒内触发。 这相当于:
- 2^32 ÷ 10^6: ~4295 seconds
- 4295 ÷ 60: ~72 minutes
该计时器预计用于短时间睡眠,如果您想要更长的警报,请参阅hardware_rtc
函数。
1.1 闹钟(Alarms)
启用闹钟(Alarms)步骤如下:
- 通过写入 INTE 中的相应警报位启用定时器中断:即 (1 << 0) 用于 ALARM0
- 在处理器上启用适当的定时器中断
- 将中断触发的时间写入 ALARM0(即 TIMERAWL 中的当前值加上想要的以微秒为单位的报警时间)。 将时间写入 ALARM 寄存器会将 ARMED 位设置为副作用。
警报触发后,ARMED 位将设置为 0。要清除锁定的中断,请将 1 写入 INTR 中的相应位。
2、硬件准备
- Raspberry Pi Pico开发板一块
- 数据线一条
- USB转串口数据线一条
3、软件准备
Raspberry Pi Pico SDK开发环境安装,请参考:Raspberry Pi Pico开发环境搭建
4、代码实现
/*************************************定时器***************************************/
queue_t sample_fifo;
// using struct as an example, but primitive types can be used too
typedef struct element {
uint value;
} element_t;
const int FIFO_LENGTH = 32;
int Timer_IRQ_Config(void)
{
int hz = 1; //中断时间频率
queue_init(&sample_fifo, sizeof(element_t), FIFO_LENGTH);
static repeating_timer_t timer;
// negative timeout means exact delay (rather than delay between callbacks)
if (!add_repeating_timer_us(-1000000 / hz, timer_callback, NULL, &timer))
{
printf("Failed to add timer\n");
return 1;
}
}
bool timer_callback(repeating_timer_t *rt) {
printf("11111111111111\r\n");
return 1; // keep repeating
}