-1

Suppose we have two microcontrollers , UART module was initialized to work as a Transmitter and Receiver ( full doublex communication ) for both of them.

Before the super loope one of them send a certain byte , and in the super loop some times the first micro and the second one received and some times the second one sends and the first one received and so on .

So, how can to code something like that ? The void uart_sendByte(uint8 data) and uint8 uart_receiveByte() are working using pollong technique .

How can I control the communication so receive right data at the right time and send the right data at the right time ?

Mickaël Leger
  • 3,426
  • 2
  • 17
  • 36
mrMatrix
  • 37
  • 5
  • Can you please share what you have tried so far ? – Fourat Oct 21 '19 at 07:38
  • 1
    If I've understood you, and given the driver functions, you can write a Finite State Machine (FSM) to handle your UART-based communication on both sides. – danrodlor Oct 21 '19 at 14:28
  • you may want to consider a packet type structure, a byte that marks the beginning of the packet, a length a checksum (or crc) either in the header or at the end, and the payload. this way if one side is out of sync or the mcus start up at different times you can recover and find you way through the data. you can make it more complicated with sequence numbers and such to be able to detect if there was a missed packet... – old_timer Oct 21 '19 at 14:42
  • but in general yes you simply send a byte out the uart or receive one. you want to poll for the receive buffer not empty or whatever your uart's status bits indicate you dont want to wait for a character as both sides will be stuck and never send. just do a check per loop if the loop is fast enough on its longest path to cover the time to receive and process a character. – old_timer Oct 21 '19 at 14:43
  • i can't understand you well unfortunetly :\ . can you give me a simple code please ? i handled this situation by bolling the data register for both so , no one of the two micros send byte until the content of it's receive data register is equal number Mx_READY for example . ex : Micro One : while(UART_receiveByte() != M2_READY) ; sendByte( data ) ; Micro Two : uart_sendByte( M2_READY ) ; variable = Uart_receiveByte() ; – mrMatrix Oct 21 '19 at 21:16

1 Answers1

-1

Header File For UART Driver for AVR Atmega16 Microcontroller

#ifndef UART_H_
#define UART_H_

#include "std_types.h"
#include "common_macros.h"
#include "micro_config.h"

/**************************************************************************************************/
/*                                     Preprocessor Macros                                        */
/**************************************************************************************************/
#define UART_BAUDRATE 9600

/**************************************************************************************************/
/*                                Public Functions Prototypes                                     */
/**************************************************************************************************/
void UART_init(void);
void UART_sendByte(uint8 data) ;
uint8 UART_receiveByte(void) ;
void UART_sendString(const uint8 *str ) ;
void UART_receiveString( uint8 *str ) ;

#endif 

UART Driver Code

#include "uart.h"
#define BAUDRATE_PRESCALE (((F_CPU/(8UL*UART_BAUDRATE))) - 1)

/**************************************************************************************************
   [ Function Name ] : UART_init
   [ Description   ] : This function is responsible for initializing UART module .
   [ Args          ] : void
   [ Returns       ] : void
**************************************************************************************************/
void UART_init(void)
{
    /* Double Transmission Speed                                                     */
    UCSRA = (1<<U2X) ;
    /* Enable Receiver and Transmitter                                               */
    UCSRB = (1<<RXEN) | (1<<TXEN) ;
    /* URSEL   : Must be one when writing UCSRC                                      */
    /* UCSZ0:1 : Set 8-Bits Data Mode                                                */
    UCSRC = (1<<URSEL)|(1<<UCSZ0)|(UCSZ1) ;
    /* First 8 bits from the BAUDRATE_PRESCALE inside UBRRL and last 4 bits in UBRRH */
    UBRRH = BAUDRATE_PRESCALE >> 8 ;
    UBRRL = BAUDRATE_PRESCALE ;
}

/**************************************************************************************************
   [ Function Name ] : UART_sendByte
   [ Description   ] : This function is responsible for Transmitting a 1-Byte of data
   [ Args          ] : uint8 : byte of data to be send
   [ Returns       ] : void
**************************************************************************************************/
void UART_sendByte(uint8 data)
{
    UDR = data ;                      /* Put Data in Data Register           */
    while(BIT_IS_CLEAR(UCSRA , TXC)); /* wait until transmission is complete */
    SET_BIT(UCSRA , TXC) ;          /* clear flag again                    */
}
/**************************************************************************************************
   [ Function Name ] : UART_receiveByte
   [ Description   ] : This function is responsible for Receiving 1-Byte of data
   [ Args          ] : uint8 data
   [ Returns       ] : uint8 : content of UART Data Register
**************************************************************************************************/
uint8 UART_receiveByte(void)
{
    while(BIT_IS_CLEAR(UCSRA , RXC)); /* wait until receiving is complete */
    return UDR ;                      /* return contents of data register */
}
/**************************************************************************************************
   [ Function Name ] : UART_sendString
   [ Description   ] : This function is responsible for Transmiting a String
   [ Args          ] : const uint8* : a pointer to constant character arry - string - to be send
   [ Returns       ] : void
**************************************************************************************************/
void UART_sendString(const uint8 *str )
{
    uint8 i = 0 ;
    while(str[i] !='\0')
    {
        UART_sendByte(str[i]) ;
        i++ ;
    }
}
/**************************************************************************************************
   [ Function Name ] : UART_receiveString
   [ Description   ] : This function is responsible for Receiving a String
   [ Args          ] : uint8* : a pointer to  character arry - string - to hold received string
   [ Returns       ] : void
**************************************************************************************************/
void UART_receiveString(uint8 *str )
{
    uint8 i = 0 ;
    str[i] = UART_receiveByte() ;
    while(str[i] !='#')
    {
        i++ ;
        str[i] = UART_receiveByte() ;
    }
    str[i] = '\0' ;
}
mrMatrix
  • 37
  • 5
  • The question is not about a "UART API" but about implementing the actual communication sequence. – Rev Oct 23 '19 at 11:34