Tuesday, November 26, 2013

Communicating two microcontrollers

Components Required




  • ATmega32 microcontroller x 2
  • AVR Programmer Board
  • Crystal
  • Capacitors
  • LEDs
  • +5V supply
  • Breadboard
  • Connecting Wires

Circuit Diagram

Description



The first microcontroller(at the top) takes the analog value of the voltage of the battery provided in the figure and shows its digital value on the given LEDs connected to the PORT B of the first microcontroller. For more information on the ANALOG TO DIGITAL conversion go through the blog analog-to-digital-conversion. Now the digital data is send to the second microcontroller and the LEDs corresponding to the digital value of the data in PORT B glows. If the data transfer is proper then the bulbs glowing through both the microcontrollers will be the same.

Connections

  • LEDs are connected to the Pins 0 to 7 of PORT B for both the microcontrollers.
  • The analog input is given to PIN A0 (ADC 0) of first microcontroller.
  • The Txd of the first microcontroller is connected to the Rxd of the second microcontroller.
  • A crystal is connected to the XTAL1 and XTAL2 pins to provide the clock pulse for both the microcontrollers.
  • Reset is connected to +5V.
NOTE:
  •  The crystal oscillator connection is not shown in the figure due to limited space. Kindly go through the previous blogs to check out the connection.
  • The ground of both the microcontrollers must be at the same potential.


Source Code 1/2

/*The first microcontroller converts the analog data to digital data, glows the corresponding LEDs and sends the same to the second microcontroller*/
#ifndef F_CPU
#define F_CPU 1000000UL               //frequency of the external crystal
#endif

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define USART_BAUDRATE 9600     
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
void send(uint8_t data);                          //function to send the data
int main()
 { 
DDRB = 0xFF;                             //All pins of PORT B as output
PORTB = 0xFF;                           //Initially all pins of PORTB as output low
UCSRB = (1 << RXEN ) | (1 << TXEN );            //Enabling the RXD and TXD 
UCSRC = (1 << URSEL ) | (1 << UCSZ0 ) | (1 << UCSZ1 );
UBRRH = ( BAUD_PRESCALE >> 8);
  UBRRL = BAUD_PRESCALE ; 
ADCSRA |= 1<<ADPS2;
ADMUX |=1<<REFS0 | 1<<REFS1;
ADMUX |=1<<ADLAR; 
ADCSRA |=1<<ADIE;
ADCSRA |=1<<ADEN;
sei();
ADCSRA |=1<<ADSC;
   while (1)                                                                      //Infinite while loop
   ;
   return 0;
 }
 ISR(ADC_vect)                                                            //Interrupt service routine 
 {
         //theLow stores the converted digital value
uint8_t theLow = ADCH;                                    
          //PORT B is configured according to theLow
PORTB = theLow;       
         //send theLow to the send function                                       
send(theLow);                                                       
 ADCSRA |=1<<ADSC;                                      
  } 
  void send(uint8_t data)
  {
 while (( UCSRA & (1 << UDRE )) == 0);
 _delay_ms(1);
 UDR = data;
  }

Source Code 2/2


/*The second microcontroller receives the data and configures the output of the PORT B according to the input received from the first microcontroller*/

#ifndef F_CPU
#define F_CPU 1000000UL               //frequency of the external crystal
#endif

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define USART_BAUDRATE 9600 
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
uint8_t receive(void);
uint8_t msg;
int main()
 { 
DDRB = 0xFF;
PORTB = 0xFF;
UCSRB = (1 << RXEN ) | (1 << TXEN );
UCSRC = (1 << URSEL ) | (1 << UCSZ0 ) | (1 << UCSZ1 );
UBRRH = ( BAUD_PRESCALE >> 8);
  UBRRL = BAUD_PRESCALE ; 
sei();                                                      //to enable the interrupt
   while (1)                                                      //Infinite while loop
   {
  msg = receive();                                   //to receive the data from function
           //configure the PORT B according to the received data
  PORTB = msg;                                   
   }
   return 0;
 }

uint8_t receive(void)
  {
 uint8_t data;
 while (!( UCSRA & (1 << RXC )));
      return UDR;                                          //return the received data to the calling function 
  }  


Thank you for reading.

For more tutorial and information, like the Facebook Page.