我目前正在开发一个系统,其中包括发送一个请求字符串到一个传感器设备通过UART连接到一个Atmel SAML21 Xplained板。我正在用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;
}
}
}发布于 2017-01-13 18:12:52
您似乎正在为ASFv3编写代码-- v4将触发对任何传入字节的接收回调,而不仅仅是在缓冲区已满时(并且每收到99个字符)。
这意味着io_read很可能永远不会返回99 (因为它只是部分读到您的消息),而且您很可能永远也不会发回任何东西。
注意文档 say (滚动到“不同的读取函数行为.”):
在ASFv4中,对每个接收到的数据触发具有环形缓冲区的驱动程序中的数据接收类型回调。
很明显,UART是一个带有环形缓冲器的司机。
您需要反复调用io_read并总结接收到的字节数,直到得到99个字节为止。只有这样才能继续。ASF文档有一个例子。确保您从那里复制符合您的版本的代码。
https://stackoverflow.com/questions/41634974
复制相似问题