在Atmel SAM L21 Xplained Pro上通过UART发送请求和接收响应的代码问题

时间:2017-01-13 12:45:39

标签: arm embedded atmel cortex-m atmelstudio

我目前正在开发一个系统,该系统涉及将请求字符串发送到通过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;
        }
    }
}

1 个答案:

答案 0 :(得分:1)

您似乎正在为ASFv3编码 - v4将触发任何传入字节的接收回调,而不仅仅是当您的缓冲区已满(并且您已收到每99个字符)时。

这意味着io_read很可能永远不会返回99(因为它只是部分读取你的消息),你很可能永远不会发回任何东西。

注意docs说(向下滚动到&#34;不同的读取功能行为......&#34;):

  

在ASFv4中,每个接收到的数据都会触发带有环形缓冲区的驱动程序中的数据接收类型回调。

UART显然是带有环形缓冲区的驱动程序。

你需要反复调用io_read并总结收到的字节数,直到你得到99.然后继续。 ASF文档就是一个例子。确保从那里复制适合您版本的代码。