如何在两个 Arduino Unos 之间通过 UART 发送和接收数据

我已经解决这个问题很长一段时间了,并成功地获得了部分分数。我想知道我拥有的代码有什么问题,这阻止我在某些条件下成功

我需要一个 arduino 通过发送一串字符与另一个 arduino 进行通信。到目前为止,我已经成功地发送和接收了一些数据,但我认为我在 uart_receive_string() 函数中设置的缓冲区可能存在问题。我将提供测试所需的所有必要信息和代码,如果需要更多信息,请告诉我,我很乐意提供。

这是 tinkercad 驱动程序的链接: https://www.tinkercad.com/things/eUZqkaIHp6J

只需单击“复制和修补”并点击顶部的代码按钮即可将以下代码粘贴到其中。您需要通过下拉框选择将代码粘贴到两个 ardunios 中。

Test Driver criteria

这是我正在研究的问题的标准:

criteria

这是我应该在提供的测试驱动程序中收到的输出:

output

这是我已经实现的当前代码:

这是两个arduino都需要复制到tinkercad中的东西

#include <stdint.h>
#include <stdio.h>
#include <avr/io.h> 
#include <avr/interrupt.h>
#include <util/delay.h>

void uart_putbyte(unsigned char data);
int uart_getbyte(unsigned char *buffer);

/*
**  Define a function named uart_send_string which transmits the contents of 
**  a standard C string (i.e. a null-terminated char array) over UART. The 
**  function should iterate over the characters in the array, using a cast to 
**  convert each to an unsigned char, and transmitting the resulting byte via 
**  uart_putbyte. The end of the string should be signalled by sending a single
**  null byte. That is, the number 0, not the character '0'. 
**  
**  Param: str - string to be transmitted.
**
**  Returns: Nothing.
*/

// vvvvvvv I need help with this vvvvvvv

void uart_send_string(char str[])
{

    int i = 0;

    char ch;

    do{
        ch = str[i];
        uart_putbyte(ch);
        i++;
    }while(ch != '0');

}

/*
**  Define a function named uart_receive_string which uses uart_getbyte to fetch 
**  the contents of a standard C string (i.e. a null-terminated char array) 
**  from UART. The function should wait for characters, and must not return 
**  until a complete string has been retrieved.
**  
**  Note that uart_getbyte will return 1 if a byte is available, and zero 
**  otherwise. Therefore, to fetch a byte and store it in a variable named x, 
**  you will need to use a construct of the form:
**      unsigned char x;
**      while (! uart_getbyte(&x)) {
**          // Do nothing.
**      }
**  
**  Param: buffer - a char array which has capacity to store a string 
**      containing at most (buff_len-1) characters. If more than (buff_len-1) 
**      characters are received, the first (buff_len-1) of them should be 
**      stored consecutively in the buffer, and any others discarded. The 
**      string must be terminated correctly with a null terminator in all 
**      circumstances.
**  
**  Param: buff_len - an int which specifies the capacity of the buffer.
**  
**  Returns: Nothing. However, up to buff_len elements of buffer may have been 
**      overwritten by incoming data. 
*/

//vvvvvvv I need help with this vvvvvvv

void uart_receive_string(char buffer[], int buff_len)
{
    int i = 0;
    unsigned char ch;

    while(!uart_getbyte(&ch))
    {

        if(ch == 0)
        {
          break;    
        }
        if(i < buff_len-1)
        {
            ch = buffer[i];
            uart_putbyte(ch);
            i++;   
        }
     }

  buffer[i]=0;

}

/*
***************************************************************************
**  Initialise UART.
***************************************************************************
*/
void uart_init(void) {
    UBRR0 = F_CPU / 16 / 9600 - 1;
    UCSR0A = 0;
    UCSR0B = (1 << RXEN0) | (1 << TXEN0);
    UCSR0C = (3 << UCSZ00);
}

/*
**************************************************************************
**  Send one byte, protecting against overrun in the transmit buffer.
**
**  Param: data - a byte to be transmitted.
**
**  Returns: Nothing.
***************************************************************************
*/
#ifndef __AMS__
void uart_putbyte(unsigned char data) {
    // Wait for empty transmit buffer
    while (!(UCSR0A & (1 << UDRE0)));

    // Send data by assigning into UDR0
    UDR0 = data;
}
#endif

/*
***************************************************************************
**  Attempt to receive one byte, returning immediately to sender.
**
**  Param: buffer - the address of a byte in which a result may be stored.
**
**  Returns: If a byte is available returns 1 and stores the incoming byte in 
**      location referenced by buffer. Otherwise returns 0 and makes no other
**      change to the state.
***************************************************************************
*/
#ifndef __AMS__
int uart_getbyte(unsigned char *buffer) {
    // If receive buffer contains data...
    if (UCSR0A & (1 << RXC0)) {
        // Copy received byte from UDR0 into memory location (*buffer)
        *buffer = UDR0;
        // 
        return 1;
    }
    else {
        return 0;
    }
}
#endif

/*
***************************************************************************
**  Implement main event loop.
***************************************************************************
*/
void process() {
    // Use two devices, as indicated in the supplied TinkerCad model. One 
    //  device acts as the sender (is_sender = 1), the other as receiver
    // (is_sender = 0). Change this to set the role accordingly.
    const int is_sender = 1;

    if (is_sender) {
        static char * messages_to_send[] = {
            "", // Empty string
            "A", // String with one symbol.
            "Hello from CAB202!", // Multiple symbols
            "1234567890abcdefghijklmnopqrstuvwxyz", // Longer than buffer size.
            NULL, // End of list 
        };

        static int next_message = 0;
        uart_send_string(messages_to_send[next_message]);
        next_message ++;
        if (messages_to_send[next_message] == NULL) next_message = 0;
        _delay_ms(300);
    }
    else {
        #define BUFF_SIZE 20
        char buffer[BUFF_SIZE];
        uart_receive_string(buffer, BUFF_SIZE);
        uart_send_string(buffer);
        uart_putbyte('r');
        uart_putbyte('n');
    }
}

int main(void) {
    uart_init();

    while (1) {
        process();
    }

    return 0;
}  

我需要处理的代码区域如下:

这是发送数据所必需的:

void uart_send_string(char str[])
{

    int i = 0;

    char ch;

    do{
        ch = str[i];
        uart_putbyte(ch);
        i++;
    }while(ch != '0');
}

这是接收数据所必需的:

void uart_receive_string(char buffer[], int buff_len)
{
    int i = 0;
    unsigned char ch;

    while(!uart_getbyte(&ch))
    {

        if(ch == 0)
        {
          break;    
        }
        if(i < buff_len-1)
        {
            ch = buffer[i];
            uart_putbyte(ch);
            i++;   
        }
     }

  buffer[i]=0;

}

如果这很难理解,我真的很抱歉。我会尽力澄清所需的任何其他信息。我只需要弄清楚我做错了什么。

stack overflow How to send and receive data through UART between two Arduino Unos
原文答案