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.

[AVR] Problem on Data transmission through RS485 over Atmega32

Status
Not open for further replies.

Prayuktibid

Newbie level 6
Joined
Mar 30, 2017
Messages
12
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
148
I am trying to communicate between two Atmega32 through RS485 Driver .. I am using MAX487 IC and Atmega32 MCU, whenever I am simulating on Proteus its not giving any output.. I have done many way but I unable to solve this. Please help me.

Here my schematics
neee schematics.jpg

This is my code
HTML:
#include <inttypes.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define MAXTTEpin 2
#define SET_MAXTE(a,b) ( (a) |=  (1 << (b) ) )
#define CLR_MAXTE(a,b) ( (a) &= ~(1 << (b) ) )
#define Led 1
#define Button 1 
/*Initilize RS485 data Transmission*/ 
void RS485init(void)
	{
	DDRD|= (1<<MAXTTEpin); 						//make max transmitter enabled pin OUTPUT
	CLR_MAXTE(PORTD,MAXTTEpin);			 		//Clear Transmitter enabled pin
	UCSRB|=(1<<TXEN)|(1<<RXEN)|(1<<RXCIE);	                        //Enabled transmitter and Receiver and Interrupt on RXC
	UCSRC|=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);                        //SET 8 Character, one stop bit, No parity
	UBRRL=0x33;						        //Set baud 9600
	sei();								//Set Interrupt
	} 
/*IRS485 data Transmitter*/
void RS485Transmitt(char x)
	{
	  SET_MAXTE(PORTD,MAXTTEpin);
      _delay_ms(1); 				        //Set Transmitter enabled pin
	 while(!(UCSRA&(1<<UDRE)));					//Check whether Transmitter data buffer is empty or not
			
			UDR=x;                                          //Receive data on UDR register
			
	while(!(UCSRA&(1<<TXC)));					//Check whether Transmission complete or not
			
			UCSRA|=(1<<TXC);                                //Make TXC HIGH
			
	CLR_MAXTE(PORTD,MAXTTEpin);
	_delay_ms(1);                                      //Clear Transmitter enabled pin
	}

/*IRS485 data Receive Inturrept Vector*/
ISR(USART_RXC_vect)
	{
    cli();
	PORTA = UDR;
	_delay_ms(1);  
    sei();                                                 //send data to port A from UDR
	}
/*Main Function*/
int main()
	{ 
    char data=0;
	DDRA|=(1<<Led);
    DDRB&=~(1<<Button);   							//make pin0 OUTPUT and other pins are INPUT of PORTA
	RS485init();                                                    //Initialize Trans receiver 
	while(1)
		{
		data=PINB;                                              //Take data from Pin A
		RS485Transmitt(data);
		_delay_ms(1);                                    //Transmit Data
		}
	}

and Oscilloscope Output
Proteus DSO Printing0004.jpg
 

Attachments

  • new Schematics.jpg
    new Schematics.jpg
    48.7 KB · Views: 124

Hi,

according your scope picture it is working like expected.

For further debug:
Show the state of both RE signals.

****
I wonder why you used RS485 driver.
* for short distance there is no need for RS485, just connect the Tx with the Rx, with CMOS levels.
* for long distance you need a proper 120 Ohms twisted pair cable and the termination resistors.

Klaus
 

Thanks for reply
For further debug: Show the state of both RE signals.
Both RE signals are same as above.. I have observed in Scope.

according your scope picture it is working like expected.
as per you its working fine then why I am not getting output? as per circuit diagram and code Leds should glow at the initial(when simulation will start) there after Leds will respond according to Buttons respectively. but nothing is happening.

I wonder why you used RS485 driver.
I am exploring the RS485 cause I am newbie in this field.
 

Hi,

Both RE signals are same as above.. I have observed in Scope.
I can´t find them in the scope picture.
Both RE signals with the same value?... doesn´t make sense. One should be the driver, the other the receiver.

Indeed I recommend to leave both receivers active all the time and only swith the trasmitters active/inactive (DE signals).

When using RS422/485 ... use the termination resistors.

It seems, that the hardware is working, so I assume there is a problem with your code.

Klaus
 

I can´t find them in the scope picture.
Both RE signals with the same value?... doesn´t make sense. One should be the driver, the other the receiver.
See the Scope output
Untitled.jpg
Indeed I recommend to leave both receivers active all the time and only swith the trasmitters active/inactive (DE signals).
I am newbie in this field please guide me how I will proceed?
 

Hi,

I still can´t see if RE1 and RE2 is HIGH or LOW. I just see a straight line.

I am newbie in this field please guide me how I will proceed?

/RE = low active. Set them active = connect them continously to GND.
Set DE signals according data direction.

Klaus
 

I'm a little bit confused about schematics. Do I understand right that you try to measure both TXD and RXD at the U3 side?
At the source code I can see driving DE/RE# in the right way. But again, the scope picture above shows a transmitting, and both RE# are the same. I can suggest that DE/RE# are HIGH at this point, so both microcontrollers are trying to drive the line. Thus no receiving. The pitfall might be if your controllers start at the same time and both drive DE/RE# to HIGH (for transmitting) simultaneously. In the real world there may be some time discrepancies and you'll see the receiving at one side and prevent collision, but in the simulator your program flow will be absolutely the same.
Try one MCU to be the master and the second to be the slave. Multi-master communication using half-duplex transmission line is not such a simple task.
 

Zip and post your complete project files and also Proteus file.
 

Thank you very much to all for your kind help. Now My project is working flawlessly.
 

Hi,

Since this is a forum, where other members should gain from the discussion...you should post where/what the problem was and how you solved it.

Klaus
 

This the circuit diagram
neee schematics.jpg

Code for MCU 1
HTML:
#include <inttypes.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define MAXTTEpin 2
#define SET_MAXTE(a,b) ( (a) |=  (1 << (b) ) )
#define CLR_MAXTE(a,b) ( (a) &= ~(1 << (b) ) )
#define Led 1
#define Button 1 
/*Initilize RS485 data Transmission*/ 
extern volatile char flag =0;
void RS485init(void)
	{
	DDRD|= (1<<MAXTTEpin); 											//make max transmitter enabled pin OUTPUT
	CLR_MAXTE(PORTD,MAXTTEpin);			 							//Clear Transmitter enabled pin
	UCSRB|=(1<<TXEN)|(1<<RXEN)|(1<<RXCIE);	                        //Enabled transmitter and Receiver and Interrupt on RXC
	UCSRC|=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);                        //SET 8 Character, one stop bit, No parity
	UBRRL=0x33;						        						//Set baud 9600
	sei();															//Set Interrupt
	} 
/*IRS485 data Transmitter*/
void RS485Transmitt(char x)
	{
	  SET_MAXTE(PORTD,MAXTTEpin);									//Set Transmitter enabled pin
      _delay_ms(1); 				        						
	 while(!(UCSRA&(1<<UDRE)));										//Check whether Transmitter data buffer is empty or not
	 UDR=x;                                          				//Receive data on UDR register
	 while(!(UCSRA&(1<<TXC)));										//Check whether Transmission complete or not
	 UCSRA|=(1<<TXC);                                				//Make TXC HIGH
	 CLR_MAXTE(PORTD,MAXTTEpin);									//Clear Transmitter enabled pin
	 _delay_ms(1);                                      
	}

/*IRS485 data Receive Inturrept Vector*/
ISR(USART_RXC_vect)
	{
     cli();															 //Clear Interruppt 
	 PORTA = UDR; 													 //send data to port A from UDR
     flag = 1;                                                       //Set Flag
     sei();                                                          //Set Interrupt 
    //_delay_ms(1);                                                 
	}
/*Main Function*/
int main()
	{ 
    char data=0;
	DDRA|=(1<<Led);                                                  //Make Led as Output
    DDRB&=~(1<<Button);   							                 //Make Button as Input
	RS485init();                                                     //Initialize Trans receiver 
	while(1)
		{
        if(flag)
		  {
		   data=PINB;                                              	//Take data from Pin B
		   RS485Transmitt(data);									//Transmitt Data
		   _delay_ms(1);                       
        }                                        
	 }
  }

Code for MCU 2
HTML:
#include <inttypes.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define MAXTTEpin 2
#define SET_MAXTE(a,b) ( (a) |=  (1 << (b) ) )
#define CLR_MAXTE(a,b) ( (a) &= ~(1 << (b) ) )
#define Led 1
#define Button 1
//extern volatile char flag =0x00;
void RS485init(void)
	{
	DDRD|= (1<<MAXTTEpin); 						  					//make max transmitter enabled pin OUTPUT
	CLR_MAXTE(PORTD,MAXTTEpin);			 							//Clear Transmitter enabled pin
	UCSRB|=(1<<TXEN)|(1<<RXEN)|(1<<RXCIE);	                        //Enabled transmitter and Receiver and Interrupt on RXC
	UCSRC|=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);                        //SET 8 Character, one stop bit, No parity
	UBRRL=0x33;						        						//Set baud 9600
	sei();															//Set Interrupt
	}
/*IRS485 data Transmitter*/
void RS485Transmitt(char x)
	{
	  SET_MAXTE(PORTD,MAXTTEpin);									//Set Transmitter enabled pin
      _delay_ms(1); 				        
	  while(!(UCSRA&(1<<UDRE)));									//Check whether Transmitter data buffer is empty or not
      UDR=x;                                         				//Receive data on UDR register
      while(!(UCSRA&(1<<TXC)));										//Check whether Transmission complete or not
      UCSRA|=(1<<TXC);                                				//Make TXC HIGH
      CLR_MAXTE(PORTD,MAXTTEpin);									//Clear Transmitter enabled pin		
	 _delay_ms(1);                                      
	}

/*IRS485 data Receive Inturrept Vector*/
ISR(USART_RXC_vect)
	{
    PORTA = UDR;
    //_delay_ms(1);                                                     //send data to port A from UDR
	}
/*Main Function*/
int main()
	{
     char data=0;
     DDRA|=(1<<Led);                                                 //Make Led as Output
     DDRB&=~(1<<Button);   							                 //Make Button as Input
	 RS485init();                                                    //Initialize Trans receiver
	 while(1)
	       {
			data=PINB;												 //Take data from Pin B
			RS485Transmitt(data);									 //Transmitt Data
			_delay_ms(1);
		 }
    }
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top