Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Uart communication between two different microcontrollers

Status
Not open for further replies.

brao

Newbie level 5
Joined
Dec 5, 2012
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,395
Hi...i want to communicate usart communication between 2 different microcontrollers...what are the hardware conections we have to give for communicating between 2 different microcontrollers...and how to take care in the software part like baudrate must be same for both controllers...? please suggest as i am new to microcontroller programming..

Thanks in Advance
 

Hi...
It doesnt matter whether u are using the same or different controllers.make sure u use the same USART settings on both sides(eg. baudrate, no of stop bits, parity ,and no of data bits).
As far as the hardware connections are concerned, connect the Rx of controller1 to Tx of controller2 and Rx of controller2 to Tx of controller1.
Hope that helps...

Cheers...
Vijay
 

Thnx for your reply...one more thing i want to clarify one mcu is operating at 1.8v and other mcu at 3.3v..as their is difference in voltage do we need any special ic in our hardware circuit
 

there is no need of the other circuit............

if both microcontroller are operating with the different power supply then connect grounds.......
 

I think the voltage difference matters. The voltage at pins including Rx and Tx of mcu operating at 1.8v will be 0v or 1.8v and the voltage levels at the pins of mcu operating at 3.3v will be 0v or 3.3v
 

from high voltage mcu tx to low voltage mcu rx, use a simple resistive voltage divider.
low voltage mcu tx connects directly to high voltage mcu rx. my logic is, there is low threshold voltage level for high voltage mcu that might be lower than 1.8v.
 

from high voltage mcu tx to low voltage mcu rx, use a simple resistive voltage divider.
low voltage mcu tx connects directly to high voltage mcu rx. my logic is, there is low threshold voltage level for high voltage mcu that might be lower than 1.8v.

THNX FOR YOUR SUGGESTIONS....we have to use resistive voltage divider for both the microcontrollers?
 

Hi,
I have the same type of problem but slight different.
I have connected ATmega32a to AT90USB1287 using UART and AT90USB1287 to PC using USB.

Intially,
AT90USB1287 is talking to the PC via USB.
ATmega32A is talking to the PC via USART(RS232).

Now i have connected ATmega32A board to AT90USB1287 using UART communication(RS232 cable by disabling connection to PC) Because both boards has to work together with one PC. Easiest way is UART connection between those two.

If i want to send data from ATmega32A to PC means, I have to get data from ATmega32A to ATusb901287 and send it to PC via USB.

I am confusing how to get data from ATmega32A to AT90USB1287.
Please help me.
 

It you want to get data into AT90USB1287 then you have to read data from ATmega32A. You said that you are using UART communication between your MCU's. Then what is the problem? You have to transmit data from ATmega32A and receive it in AT90USB1287. You connect the RxD pin of ATMega32A to TxD pin of AT90USB1287 and you connect TxD pin of ATMega32A to RxD pin of AT90USB1287. You have to use serial interrupt to receive data but you dont need interrupts to transmit data.
 

It you want to get data into AT90USB1287 then you have to read data from ATmega32A. You said that you are using UART communication between your MCU's. Then what is the problem? You have to transmit data from ATmega32A and receive it in AT90USB1287. You connect the RxD pin of ATMega32A to TxD pin of AT90USB1287 and you connect TxD pin of ATMega32A to RxD pin of AT90USB1287. You have to use serial interrupt to receive data but you dont need interrupts to transmit data.
I have written only interrupt to receive data as shown below.
Code:
/***************************************************
C O M U N I C A T I O N  RS-232
****************************************************/
unsigned char SerIn[SIBUFSIZE];     // Input buffer (raw data)
unsigned char RxCnt;                // Location of next byte to be written
unsigned char RdCnt;                // Location of next byte to be read
unsigned char BufCnt;               // Size of unread contents in ring buffer
unsigned char CompIndex;            // Index in Copmare array
unsigned char Compare[COMPBUFSIZE]; // Command string tokenizer
unsigned char Command;              // Current Command is executed
unsigned int  Param;                // Parameter used in command
       float  Param2;               // Optional (second) parameter used in command
unsigned long Param3;               // Optional (third) parameter in command

extern unsigned char Plot;
unsigned char Step;

// USART1 Receiver interrupt service routine
interrupt [USART1_RXC] void usart1_rx_isr(void){   
    
    if(UCSR1A & 0x1C){       
        SerIn[RxCnt] = UDR1; //Read the corrupted byte          
        return;              // Error
    }

    if(++BufCnt >= SIBUFSIZE){                 // Increment & check for buffer overflow
        BufCnt = SIBUFSIZE-1;                  // Set to max value
        return;                                // Skip char
    }else{                                     // Else: if buffer ok
        if(++RxCnt >= SIBUFSIZE) RxCnt = 0;    // Increment read counter, if 10 -> 0 (max 9)
        SerIn[RxCnt] = UDR1;                   // Write to SBUF (load the transmit register)
    }
}

// USB Receive
void catchString(void){
    
    while(UEBCLX){
    
        if(++BufCnt >= SIBUFSIZE){               // Increment & check for buffer overflow  
            BufCnt = SIBUFSIZE-1;                // Set to max value 
//            printf("!Overflow\r\n");
//            UENUM = 2;   
            return;                              // Skip char
        }else{                                   // Else: if buffer ok
            if(++RxCnt >= SIBUFSIZE) RxCnt = 0;  // Increment read counter, if 10 -> 0 (max 9)
            SerIn[RxCnt] = UEDATX;               // Write to SBUF (load the transmit register)
        }
     }  
}


// Read from ringbuffer
char getcharb(void){

    if(BufCnt){                                 // If anything
        BufCnt--;                               // Decrement buffer counter
        if(++RdCnt >= SIBUFSIZE) RdCnt = 0;     // Increment read counter, if 10 -> 0 (max 9)
        return SerIn[RdCnt];                    // Read from SBUF (access receive register)
    }
    return 0;
}
That is the code I have written in AT90USB1287 firmware to get data from ATmega32A. It is not working.

I have written UART for atmega32a as shown below.
Code:
/*************************************************** 
C O M U N I C A T I O N  RS-232 
****************************************************/ 
unsigned char CompIndex;            // Index in Copmare array 
unsigned char Compare[COMPBUFSIZE]; // Command string tokenizer 
extern unsigned char Command;              // Current Command is executed 
extern unsigned int  Param;                // Parameter used in command 
//       float  Param2;               // Optional (second) parameter used in command 
//unsigned long Param3;               // Optional (third) parameter in command 

unsigned char Step; 

extern unsigned char state; 
extern unsigned int status; 
extern unsigned char debug; 

#define RXB8 1 
#define TXB8 0 
#define UPE 2 
#define OVR 3 
#define FE 4 
#define UDRE 5 
#define RXC 7 

#define FRAMING_ERROR (1<<FE) 
#define PARITY_ERROR (1<<UPE) 
#define DATA_OVERRUN (1<<OVR) 
#define DATA_REGISTER_EMPTY (1<<UDRE) 
#define RX_COMPLETE (1<<RXC) 

// USART Receiver buffer 
#define RX_BUFFER_SIZE0 32 
char rx_buffer0[RX_BUFFER_SIZE0]; 

#if RX_BUFFER_SIZE0<256 
unsigned char rx_wr_index0,rx_rd_index0,rx_counter0; 
#else 
unsigned int rx_wr_index0,rx_rd_index0,rx_counter0; 
#endif 

// This flag is set on USART Receiver buffer overflow 
bit rx_buffer_overflow0; 

// USART Receiver interrupt service routine 
interrupt [USART_RXC] void usart_rx_isr(void){ 
    char status,data; 
    status=UCSRA; 
    data=UDR; 
    if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) 
       { 
       rx_buffer0[rx_wr_index0]=data; 
       if (++rx_wr_index0 == RX_BUFFER_SIZE0) rx_wr_index0=0; 
       if (++rx_counter0 == RX_BUFFER_SIZE0) 
          { 
          rx_counter0=0; 
          rx_buffer_overflow0=1; 
          }; 
       }; 
} 

#ifndef _DEBUG_TERMINAL_IO_ 
// Get a character from the USART Receiver buffer 
#define _ALTERNATE_GETCHAR_ 
#pragma used+                                
char getchar(void){ 
    char data; 
    while (rx_counter0==0); 
    data=rx_buffer0[rx_rd_index0]; 
    if (++rx_rd_index0 == RX_BUFFER_SIZE0) rx_rd_index0=0; 
    #asm("cli") 
    --rx_counter0; 
    #asm("sei") 
    return data; 
} 
#pragma used- 
#endif 

// USART Transmitter buffer 
#define TX_BUFFER_SIZE0 32 
char tx_buffer0[TX_BUFFER_SIZE0]; 

#if TX_BUFFER_SIZE0<256 
unsigned char tx_wr_index0,tx_rd_index0,tx_counter0; 
#else 
unsigned int tx_wr_index0,tx_rd_index0,tx_counter0; 
#endif 

// USART Transmitter interrupt service routine 
interrupt [USART_TXC] void usart_tx_isr(void){ 
    if (tx_counter0){ 
        --tx_counter0; 
        UDR=tx_buffer0[tx_rd_index0]; 
        if (++tx_rd_index0 == TX_BUFFER_SIZE0) tx_rd_index0=0; 
        //#asm("WDR"); // For long words and slow baud-rates 
    } 
} 

#ifndef _DEBUG_TERMINAL_IO_ 
// Write a character to the USART Transmitter buffer 
#define _ALTERNATE_PUTCHAR_ 
#pragma used+ 
void putchar(char c){ 
    while (tx_counter0 == TX_BUFFER_SIZE0); 
    #asm("cli") 
    if (tx_counter0 || ((UCSRA & DATA_REGISTER_EMPTY)==0)){
        tx_buffer0[tx_wr_index0]=c; 
        if (++tx_wr_index0 == TX_BUFFER_SIZE0) tx_wr_index0=0; 
        ++tx_counter0; 
    } 
    else 
    UDR=c; 
    #asm("sei") 
} 
#pragma used- 
#endif
Please help me what is the problem. but i am not able to display ATmega32a data to the PC using At90USB1287.

If you need more information please ask me.
 
Last edited:

See the links I have given. See where you are going wrong.

UART of ATMega32A received 1 byte at a time using serial interrupt. The moment it receives data (byte) just transmit it.

If you want I can write a new code for USART receive and transmit for ATMega32A.
 

See the links I have given. See where you are going wrong.

UART of ATMega32A received 1 byte at a time using serial interrupt. The moment it receives data (byte) just transmit it.

If you want I can write a new code for USART receive and transmit for ATMega32A.

Sorry, If i din't understand properly.

The code I have posted above is working properly when I connect ATmega32A to PC using UART. I am able to send commands from PC and able to receive data from it. This is my first project with micro controller. I am using CodeVisionAVr compiler.
 
Last edited:

Have you written code for ATMega32A to transmit data? Have you also written code for AT90USB1287 to receive data? If yes, then if it is not working then the problem is in your baudrate settings or AT90USB1287 receive code.
 

Have you written code for ATMega32A to transmit data? Have you also written code for AT90USB1287 to receive data? If yes, then if it is not working then the problem is in your baudrate settings or AT90USB1287 receive code.
I have initialized both UART ports like
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART0 Mode: Asynchronous
// USART Baud Rate: 38400
I have posted the all the code above. That is only i have. I think I don't have the code to send it from ATmega32a and code receive it at at90USB1287. Can you help me.
 

The same ATMega32A code which transmits data to PC if you connect your ATMega32A to PC will do the job. If you are able to receive data from ATMega32A in PC then it means ATMega32A code has UART transmit code. If not, then code for ATMega32A to transmit data through UART has to be written. If your AT90USB1287 is able to receive data using UART then there is no need to modify code for AT90USB1287.

The code for UART receive and transmit is like this.

Code:
#include <avr/io.h> 

#define USART_BAUDRATE 9600 
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1) 

int main (void) 
{ 
   char ReceivedByte; 

   UCSRB |= (1 << RXEN) | (1 << TXEN);   // Turn on the transmission and reception circuitry 
   UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); // Use 8-bit character sizes 

   UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register 
   UBRRL = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register 

   for (;;) // Loop forever 
   { 
      while ((UCSRA & (1 << RXC)) == 0) {}; // Do nothing until data have been received and is ready to be read from UDR 
      ReceivedByte = UDR; // Fetch the received byte value into the variable "ByteReceived" 

      while ((UCSRA & (1 << UDRE)) == 0) {}; // Do nothing until UDR is ready for more data to be written to it 
      UDR = ReceivedByte; // Echo back the received byte back to the computer 
   }    
}
 

The same ATMega32A code which transmits data to PC if you connect your ATMega32A to PC will do the job. If you are able to receive data from ATMega32A in PC then it means ATMega32A code has UART transmit code. If not, then code for ATMega32A to transmit data through UART has to be written. If your AT90USB1287 is able to receive data using UART then there is no need to modify code for AT90USB1287.

Yes, the code I have posted above for ATmega32A is working well with PC. I am able to send commands and receive data perfectly it means i have code that transmit data. The problem is i am confusing with the code i have with AT90USb1287 is able to receive it or not. What functions i need to write? only UART receiving code is enough? Then how to send it through USB to PC?
 

If you don't want AT90USb1287 to send any data to ATMega32A and only want it to receive data then only data receive code is necessary. If you want to send the data from AT90USb1287 to PC through USB then you have to write the code to transmit data received by AT90USb1287 serially using USB.
 

If you don't want AT90USb1287 to send any data to ATMega32A and only want it to receive data then only data receive code is necessary. If you want to send the data from AT90USb1287 to PC through USB then you have to write the code to transmit data received by AT90USb1287 serially using USB.
I have understand the concept now. I need UART receive and transmit code for AT90USB1287 to receive and send data to atmega32A, I have already code for ATmega32a for receive and send so i need code for only at90. Once i have the receive and send code of AT90USB1287 then i have to send the received data using USB buffer to PC. Am i right.
If you don't mine can you have any examples for implementing uart communication for AT90USB1287. Is it same like what i have written for atmega32a?
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top