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

Arm Atmel SAM L21 Explained Pro上通过UART发送请求和接收响应的代码存在问题,arm,embedded,atmel,cortex-m,atmelstudio,Arm,Embedded,Atmel,Cortex M,Atmelstudio,我目前正在开发一个系统,该系统包括向通过UART连接到Atmel SAML21 Explained 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连接到Atmel SAML21 Explained 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\u 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;
        }
    }
}
#包括“atmel_start.h”
#包括“atmel\u start\u引脚.h”
#包括
静态uint8\u t示例\u hello\u world[14]=“hello world!\n”;
静态uint8\u t示例\u错误\u消息[13]=“UART错误!\n”;
静态uint8\u t请求消息[24]=“发送传感器请求\n”;
静态uint8_t rotronic_ascii[8]=“{99RDD}”;
易失性静态uint32数据到达=0;
接收到的易失性静态uint32读数=0;
静态无效发送\u cb\u EDBG\u COM(常量结构usart\u异步\u描述符*常量io\u描述)
{
/*转移完成*/
gpio_切换_引脚_电平(LED0);
}
静态无效接收cb EDBG COM(常量结构usart异步描述符*常量io描述)
{
/*接收完成*/
数据_=1;
}
静态无效错误\u cb\u EDBG\u COM(常量结构usart\u异步\u描述符*常量io\u描述)
{
/*错误句柄*/
io_write(&EDBG_COM.io,示例_error_msg,13);
}
静态无效tx\U cb\U COM1(常量结构usart\U异步描述符*常量io\U描述)
{
/*转移完成*/
gpio_切换_引脚_电平(LED0);
}
静态无效rx\u cb\u COM1(常量结构usart\u异步描述符*常量io\u描述)
{
/*接收完成*/
接收到的读数=1;
}
静态无效错误cb COM1(常量结构usart异步描述符*常量io描述)
{
/*错误句柄*/
io写入(&COM1.io,示例错误消息,13);
}
内部主(空)
{
挥发性uint8_t recv_char[99];
atmel_start_init();
//设置EDBG串行端口
usart_异步_寄存器_回调(&EDBG_COM、usart_异步_TXC_CB、tx_CB_EDBG_COM);
usart_异步_寄存器_回调(&EDBG_COM、usart_异步_RXC_CB、rx_CB_EDBG_COM);
usart\U异步\U寄存器\U回调(&EDBG\U COM、usart\U异步\U错误\U CB、错误\U CB\U EDBG\U COM);
usart\u异步\u启用(&EDBG\u COM);
//发送测试字符串以确保EDBG串行通信正常工作
io_write(&EDBG_COM.io,示例_hello_world,14);
//设置Rotronic[Arduino]串行端口
usart_异步_寄存器_回调(&COM1,usart_异步_TXC_CB,tx_CB_COM1);
usart\U异步\U寄存器\U回调(&COM1,usart\U异步\U RXC\U CB,rx\U CB\U COM1);
usart\U异步\U寄存器\U回调(&COM1,usart\U异步\U错误\U CB,错误\U CB\U COM1);
usart\u异步\u启用(&COM1);
而(1){
如果(接收到的读数==0)
{
//耽搁一下
延迟(5000);
//通知EDBG COM端口
io_write(&EDBG_COM.io,request_msg,24);
//发送Rotronic ASCII
io_写入(&COM1.io,rotronic_ascii,8);
}
//检查是否已收到读数
如果(接收的读数=1)
{
while(io_read(&COM1.io,&recv_char,99)==99)
{
//从接收器写入缓冲区中的内容
io_write(&EDBG_COM.io,recv_char,99);
}
//重置标志
接收到的读数=0;
}
}
}

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

这意味着,
io_read
很可能永远不会返回99(因为它只是部分读取了您的邮件),您也很可能永远不会返回任何内容

注意下面的语句(向下滚动至“不同的读取函数行为…”):

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

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


您需要反复调用
io\u read
并将接收到的字节数相加,直到得到99。只有这样才能继续。ASF文档中有一个例子。确保从那里复制符合您的版本的代码。

delay_ms(5000)不应等待半秒钟。您是否有该文档的链接?我想我一直在看旧的文档。另外,感谢您的回复!明天将进行测试,并将此答案标记为正确:)链接到上面插入的引用。