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

时间:2020-09-12 02:28:18

标签: c uart tinkercad

我已经解决这个问题已有相当长的时间了,并且已经获得了部分评分。我想知道我的代码有什么问题,就是在某些情况下阻止我成功

我需要一个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;
}  

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

0 个答案:

没有答案
相关问题