将 UART 与 RPi Pico C sdk 一起使用时出现问题
Trouble using the UART with RPi Pico C sdk
我正在制作一台遥控机器,使用 pi pico 驱动电机并读取一些传感器,以及 raspberry pi 4 通过串行向 pi pico 发送命令并托管网络界面。
我正在努力从树莓派发送和接收命令,现在我被这段代码困住了:
#include <string.h>
#include "pico/stdlib.h"
#include "hardware/uart.h"
#include "hardware/irq.h"
#define UART_ID uart0
#define BAUD_RATE 19200
#define DATA_BITS 8
#define STOP_BITS 1
#define PARITY UART_PARITY_NONE
#define UART_TX_PIN 0
#define UART_RX_PIN 1
static int chars_rxed = 0;
char uCommand[32] = {0, 0};
void on_uart_rx() {
char tmp_string[] = {0, 0};
while (uart_is_readable(UART_ID)) {
uint8_t ch = uart_getc(UART_ID);
tmp_string[0] = ch;
strcat(uCommand, tmp_string);
if(uart_is_writable(UART_ID)){
uart_putc(UART_ID, '-');
uart_puts(UART_ID, uCommand);
uart_putc(UART_ID, '-');
}
chars_rxed++;
}
}
int main(){
uart_init(UART_ID, BAUD_RATE);
gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART);
uart_set_hw_flow(UART_ID, false, false);
uart_set_format(UART_ID, DATA_BITS, STOP_BITS, PARITY);
uart_set_fifo_enabled(UART_ID, false);
int UART_IRQ = UART_ID == uart0 ? UART0_IRQ : UART1_IRQ;
irq_set_exclusive_handler(UART_IRQ, on_uart_rx);
irq_set_enabled(UART_IRQ, true);
uart_set_irq_enables(UART_ID, true, false);
uart_puts(UART_ID, "\nOK\n");
while (1){
tight_loop_contents();
if(uCommand[0] != 0){
uart_putc(UART_ID, '/');
uart_puts(UART_ID, uCommand);
uart_putc(UART_ID, '/');
}
}
}
我的想法是把中断期间通过串行发送的命令放在一个字符集中,然后解析它并在外部执行它。
尝试了一下,我注意到它从来没有在 while 中输入 if 并且它没有 'fill' 完全 'uCommand' 字符集,但与发送的字符相比只有几个字符。
希望我的问题没有跑题。
您应该声明 uCommand
(以及任何其他共享对象)volatile
。
while 循环正在等待 uCommand[0] != 0
变为真,但主线程不会修改 uCommand[0]
因此编译器可以自由地“优化”掉整个代码块,如果它“知道”永远不可能是真的。
同样,chars_rxed
可能会被优化掉,因为您只写但从不阅读。
将其声明为 volatile 也可以防止这种情况发生。
显然冗余访问的优化通常只发生在 -O1
或更高的优化级别设置时。尽管无论如何您都应该在这种情况下使用 volatile
。
我正在制作一台遥控机器,使用 pi pico 驱动电机并读取一些传感器,以及 raspberry pi 4 通过串行向 pi pico 发送命令并托管网络界面。
我正在努力从树莓派发送和接收命令,现在我被这段代码困住了:
#include <string.h>
#include "pico/stdlib.h"
#include "hardware/uart.h"
#include "hardware/irq.h"
#define UART_ID uart0
#define BAUD_RATE 19200
#define DATA_BITS 8
#define STOP_BITS 1
#define PARITY UART_PARITY_NONE
#define UART_TX_PIN 0
#define UART_RX_PIN 1
static int chars_rxed = 0;
char uCommand[32] = {0, 0};
void on_uart_rx() {
char tmp_string[] = {0, 0};
while (uart_is_readable(UART_ID)) {
uint8_t ch = uart_getc(UART_ID);
tmp_string[0] = ch;
strcat(uCommand, tmp_string);
if(uart_is_writable(UART_ID)){
uart_putc(UART_ID, '-');
uart_puts(UART_ID, uCommand);
uart_putc(UART_ID, '-');
}
chars_rxed++;
}
}
int main(){
uart_init(UART_ID, BAUD_RATE);
gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART);
uart_set_hw_flow(UART_ID, false, false);
uart_set_format(UART_ID, DATA_BITS, STOP_BITS, PARITY);
uart_set_fifo_enabled(UART_ID, false);
int UART_IRQ = UART_ID == uart0 ? UART0_IRQ : UART1_IRQ;
irq_set_exclusive_handler(UART_IRQ, on_uart_rx);
irq_set_enabled(UART_IRQ, true);
uart_set_irq_enables(UART_ID, true, false);
uart_puts(UART_ID, "\nOK\n");
while (1){
tight_loop_contents();
if(uCommand[0] != 0){
uart_putc(UART_ID, '/');
uart_puts(UART_ID, uCommand);
uart_putc(UART_ID, '/');
}
}
}
我的想法是把中断期间通过串行发送的命令放在一个字符集中,然后解析它并在外部执行它。
尝试了一下,我注意到它从来没有在 while 中输入 if 并且它没有 'fill' 完全 'uCommand' 字符集,但与发送的字符相比只有几个字符。
希望我的问题没有跑题。
您应该声明 uCommand
(以及任何其他共享对象)volatile
。
while 循环正在等待 uCommand[0] != 0
变为真,但主线程不会修改 uCommand[0]
因此编译器可以自由地“优化”掉整个代码块,如果它“知道”永远不可能是真的。
同样,chars_rxed
可能会被优化掉,因为您只写但从不阅读。
将其声明为 volatile 也可以防止这种情况发生。
显然冗余访问的优化通常只发生在 -O1
或更高的优化级别设置时。尽管无论如何您都应该在这种情况下使用 volatile
。