在 Atmel SAM L21 Xplained Pro 上通过 UART 发送请求和接收响应的代码问题
Posted
技术标签:
【中文标题】在 Atmel SAM L21 Xplained Pro 上通过 UART 发送请求和接收响应的代码问题【英文标题】:Problems with code to send request and receive response over UART on Atmel SAM L21 Xplained Pro 【发布时间】:2017-01-13 12:45:38 【问题描述】:我目前正在开发一个系统,该系统涉及向通过 UART 连接到 Atmel SAML21 Xplained Pro 板的传感器设备发送请求字符串。我正在使用 Arduino 板作为“传感器设备”进行测试,但最终将用于 Rotronic HC-2 传感器。
这个过程是这样的:
MCU sends string 99RDD over UART to sensor
-> delay of up to 500ms
-> Response string of 99 bytes sent back via UART
-> Response transmitted to virtual com port on embedded debugger
我的问题是,由于某种原因,我要么没有收到任何发回的东西,要么发回了变量 request_msg
我知道传感器的响应应该是 99 字节的 ASCII,并且我已经通过串行连接器测试了实际传感器和 Arduino 测试板,以确保读数正确返回。
该软件使用的是 Atmel ASF v4.0,它在运行时非常好,但文档相当不稳定,所以我希望有更多经验的人能指出我在代码中哪里出错了。
我的主应用程序有以下代码:
#include "atmel_start.h"
#include "atmel_start_pins.h"
#include <string.h>
static uint8_t example_hello_world[14] = "Hello World!\n";
static uint8_t example_error_msg[13] = "UART Error!\n";
static uint8_t request_msg[24] = "Sending Sensor Request\n";
static uint8_t rotronic_ascii[8] = " 99RDD";
volatile static uint32_t data_arrived = 0;
volatile static uint32_t reading_received = 0;
static void tx_cb_EDBG_COM(const struct usart_async_descriptor *const io_descr)
/* Transfer completed */
gpio_toggle_pin_level(LED0);
static void rx_cb_EDBG_COM(const struct usart_async_descriptor *const io_descr)
/* Receive completed */
data_arrived = 1;
static void err_cb_EDBG_COM(const struct usart_async_descriptor *const io_descr)
/* error handle */
io_write(&EDBG_COM.io, example_error_msg, 13);
static void tx_cb_COM1(const struct usart_async_descriptor *const io_descr)
/* Transfer completed */
gpio_toggle_pin_level(LED0);
static void rx_cb_COM1(const struct usart_async_descriptor *const io_descr)
/* Receive completed */
reading_received = 1;
static void err_cb_COM1(const struct usart_async_descriptor *const io_descr)
/* error handle */
io_write(&COM1.io, example_error_msg, 13);
int main(void)
volatile uint8_t recv_char[99];
atmel_start_init();
// Setup the EDBG Serial Port
usart_async_register_callback(&EDBG_COM, USART_ASYNC_TXC_CB, tx_cb_EDBG_COM);
usart_async_register_callback(&EDBG_COM, USART_ASYNC_RXC_CB, rx_cb_EDBG_COM);
usart_async_register_callback(&EDBG_COM, USART_ASYNC_ERROR_CB, err_cb_EDBG_COM);
usart_async_enable(&EDBG_COM);
// Send a test string to ensure EDBG Serial is working
io_write(&EDBG_COM.io, example_hello_world, 14);
// Setup the Rotronic [Arduino] Serial Port
usart_async_register_callback(&COM1, USART_ASYNC_TXC_CB, tx_cb_COM1);
usart_async_register_callback(&COM1, USART_ASYNC_RXC_CB, rx_cb_COM1);
usart_async_register_callback(&COM1, USART_ASYNC_ERROR_CB, err_cb_COM1);
usart_async_enable(&COM1);
while (1)
if (reading_received == 0)
// Delay for a Bit
delay_ms(5000);
// Notify the EDBG COM Port
io_write(&EDBG_COM.io, request_msg, 24);
// Send the Rotronic ASCII
io_write(&COM1.io, rotronic_ascii, 8);
// Check if Reading has been Received
if (reading_received == 1)
while (io_read(&COM1.io, &recv_char, 99) == 99)
// Write what's on the buffer from the receiver
io_write(&EDBG_COM.io, recv_char, 99);
// Reset the flag
reading_received = 0;
【问题讨论】:
delay_ms(5000) 不应该等待半秒 【参考方案1】:您似乎正在为 ASFv3 编码 - v4 将触发您对 任何 传入字节的接收回调,而不仅仅是在您的缓冲区已满时触发一次(并且您每 99 个字符接收一次)。
这意味着io_read
很可能永远不会返回 99(因为它只是对您的消息的部分阅读)并且您很可能永远不会发回任何东西。
注意docs 说(向下滚动到“不同的读取功能行为...”):
在 ASFv4 中,每个接收到的数据都会触发带有环形缓冲区的驱动程序中的数据接收类型回调。
UART 显然是一个带有环形缓冲区的驱动程序。
您需要反复调用io_read
并将接收到的字节数相加,直到得到99。然后才能继续。 ASF 文档有一个例子。确保从那里复制适合您的版本的代码。
【讨论】:
你有那个文档的链接吗?我想我一直在查看旧文档。另外,感谢您的回复!明天将测试并将此答案标记为正确:) 上面插入的引用链接。以上是关于在 Atmel SAM L21 Xplained Pro 上通过 UART 发送请求和接收响应的代码问题的主要内容,如果未能解决你的问题,请参考以下文章
Xplained pro SAM4SD32C - 定时器 1 - 无法写入 RA 寄存器
SAM 上的 Atmel ASF - pio_configure_pin 描述错误?