RP2040 C SDK开发串口的使用
- 📍环境搭建部署篇《RP2040 VSCode C/C++开发环境快速部署》
- 🔖RP2040 有硬件串口资源有2个。
- 🌿参考RP2040 C SDK Hardware APIS:
https://www.raspberrypi.com/documentation/pico-sdk/hardware.html#group_hardware_uart
- 🌿串口0默认引脚定义:
// --- UART ---
#ifndef PICO_DEFAULT_UART
#define PICO_DEFAULT_UART 0
#endif
#ifndef PICO_DEFAULT_UART_TX_PIN
#define PICO_DEFAULT_UART_TX_PIN 0
#endif
#ifndef PICO_DEFAULT_UART_RX_PIN
#define PICO_DEFAULT_UART_RX_PIN 1
#endif
- 🌿串口0初始化:
int main() {
// Set the GPIO pin mux to the UART - pin 0 is TX, 1 is RX; note use of UART_FUNCSEL_NUM for the general
// case where the func sel used for UART depends on the pin number
// Do this before calling uart_init to avoid losing data
gpio_set_function(0, UART_FUNCSEL_NUM(uart0, 0));
gpio_set_function(1, UART_FUNCSEL_NUM(uart0, 1));
// Initialise UART 0
uart_init(uart0, 115200);
uart_puts(uart0, "Hello world!");
}
- 🌿如果调用了
stdio_init_all();
则默认使用串口0(0,1),波特率默认115200;作为标准输出函数。
bool stdio_init_all(void) {
// todo add explicit custom, or registered although you can call stdio_enable_driver explicitly anyway
// These are well known ones
bool rc = false;
#if LIB_PICO_STDIO_UART
stdio_uart_init();
rc = true;
#endif
#if LIB_PICO_STDIO_SEMIHOSTING
stdio_semihosting_init();
rc = true;
#endif
#if LIB_PICO_STDIO_USB
rc |= stdio_usb_init();
#endif
return rc;
}
//最终调用的串口初始化函数
void stdio_uart_init_full(struct uart_inst *uart, uint baud_rate, int tx_pin, int rx_pin) {
uart_instance = uart;
if (tx_pin >= 0) gpio_set_function((uint)tx_pin, GPIO_FUNC_UART);
if (rx_pin >= 0) gpio_set_function((uint)rx_pin, GPIO_FUNC_UART);
uart_init(uart_instance, baud_rate);
stdio_set_driver_enabled(&stdio_uart, true);
}
📗串口0和串口1测试例程
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/uart.h"
#include "hardware/gpio.h"
#include "hardware/gpio.h"
#include "hardware/divider.h"
// UART defines
// By default the stdout UART is `uart0`, so we will use the second one
#define UART_ID uart1
#define BAUD_RATE 115200 //
// Use pins 4 and 5 for UART1
// Pins can be changed, see the GPIO function select table in the datasheet for information on GPIO assignments
#define UART_TX_PIN 4
#define UART_RX_PIN 5
// GPIO defines
// Example uses GPIO 2
#define GPIO 2
static const uint pin = 25;
int main()
{
stdio_init_all();//串口0,115200,支持printf打印
// Set up our UART
uart_init(UART_ID, BAUD_RATE);//串口1,115200
uart_set_hw_flow(UART_ID, false, false);//关闭硬件流控
// 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);
// GPIO initialisation.
// We will make this GPIO an input, and pull it up by default
gpio_init(GPIO);
gpio_set_dir(GPIO, GPIO_OUT);
gpio_pull_up(GPIO);
gpio_init(pin);
gpio_set_dir(pin, GPIO_OUT);
while (true) {
// Example of using the HW divider. The pico_divider library provides a more user friendly set of APIs
// over the divider (and support for 64 bit divides), and of course by default regular C language integer
// divisions are redirected thru that library, meaning you can just use C level `/` and `%` operators and
// gain the benefits of the fast hardware divider.
int32_t dividend = 123456;
int32_t divisor = -321;
// This is the recommended signed fast divider for general use.
divmod_result_t result = hw_divider_divmod_s32(dividend, divisor);
printf("%d/%d = %d remainder %d\n", dividend, divisor, to_quotient_s32(result), to_remainder_s32(result));
// This is the recommended unsigned fast divider for general use.
int32_t udividend = 123456;
int32_t udivisor = 321;
divmod_result_t uresult = hw_divider_divmod_u32(udividend, udivisor);
printf("%d/%d = %d remainder %d\n", udividend, udivisor, to_quotient_u32(uresult), to_remainder_u32(uresult));
puts("Hello, world!1234 from uart0");
sleep_ms(1000);
gpio_set_mask(1ul<<GPIO);
gpio_put(pin, true);
sleep_ms(250);
gpio_clr_mask(1ul<<GPIO);
gpio_put(pin, false);
sleep_ms(250);
uart_puts(uart1,"Hello, from UART1!");
//uart_puts(uart0, "Hello world!");
}
// return 0;
}
📘串口中断测试例程
- 🌿中断号:
enum irq_num_rp2040 { TIMER_IRQ_0 = 0, TIMER_IRQ_1 = 1, TIMER_IRQ_2 = 2, TIMER_IRQ_3 = 3, PWM_IRQ_WRAP = 4, USBCTRL_IRQ = 5, XIP_IRQ = 6, PIO0_IRQ_0 = 7, PIO0_IRQ_1 = 8, PIO1_IRQ_0 = 9, PIO1_IRQ_1 = 10, DMA_IRQ_0 = 11, DMA_IRQ_1 = 12, IO_IRQ_BANK0 = 13, IO_IRQ_QSPI = 14, SIO_IRQ_PROC0 = 15, SIO_IRQ_PROC1 = 16, CLOCKS_IRQ = 17, SPI0_IRQ = 18, SPI1_IRQ = 19, UART0_IRQ = 20, UART1_IRQ = 21, ADC_IRQ_FIFO = 22, I2C0_IRQ = 23, I2C1_IRQ = 24, RTC_IRQ = 25, IRQ_COUNT } RP2040
Interrupt numbers on RP2040 (used as typedef irq_num_t)
📑通过开启串口1接收中断,将串口1(0,1)接收到的数据,通过串口0(4,5)转发.
- 📝测试代码:
/*
烧录命令:openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "program USART_Test.elf verify reset exit"
jlink openocd -f interface/jlink.cfg -f target/rp2040.cfg -c "program USART_Test.elf verify reset exit"
* @FilePath: \USART_Test\USART_Test.c
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/uart.h"
#include "hardware/gpio.h"
#include "hardware/divider.h"
// #include "hardware/clocks.h"
// 检查是否定义了 LIB_PICO_STDIO_UART 宏
#if defined(LIB_PICO_STDIO_UART)
// 如果定义了,取消这个宏
#undef LIB_PICO_STDIO_UART
#define LIB_PICO_STDIO_USB 1
#endif
// UART defines
// By default the stdout UART is `uart0`, so we will use the second one
#define UART_ID uart1
#define BAUD_RATE 115200 //串口波特率
// Use pins 4 and 5 for UART1
// Pins can be changed, see the GPIO function select table in the datasheet for information on GPIO assignments
#define UART_TX_PIN 4
#define UART_RX_PIN 5
// GPIO defines
// Example uses GPIO 2
#define GPIO 2
static const uint pin = 25;
void uart1ISR(void)
{
while(uart_is_readable(UART_ID))
{
uint8_t ch = uart_getc(UART_ID);
if(uart_is_writable(UART_ID))
{
uart_putc(uart0, ch);//转发数据
}
}
}
int main()
{
stdio_init_all();//串口0,115200
// 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);
// Set up our UART
uart_init(UART_ID, BAUD_RATE);//串口1,115200
uart_set_hw_flow(UART_ID, false, false);//关闭硬件流控
irq_set_exclusive_handler(UART1_IRQ, uart1ISR);//配置中断回调
irq_set_enabled(UART1_IRQ, true);//开启串口中断
uart_set_irq_enables(uart1, true, false); //开启中断,接收中断,关闭发送中断
irq_set_priority (21, 1); //设置中断优先级
uart_set_fifo_enabled(uart1, true);//开启缓存
hw_write_masked(&uart_get_hw(uart1)->ifls, 0b100 << UART_UARTIFLS_RXIFLSEL_LSB,
UART_UARTIFLS_RXIFLSEL_BITS); //开启接收中断
uart_is_enabled(UART_ID);
while (true) {
}
- 测试结果