Strange Uart problem!

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have this program, it seems that I cant receive any data in my receiver module from the transmitter module which is connected with an Atmega32u4 module.

Need help, here's my program.

#define F_CPU 1000000UL
#define BAUDRATE 9600
#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 8UL))) - 1)


#include 
#include 
#include 

//Declaration of functions
void USART_init(void);
void USART_send(unsigned char data);
void USART_putstring(char* StringPtr);

/*message arrays*/

char msg1[] = {"The water is in level 1."};
char msg2[] = {"The water is in level 2."};
char msg3[] = {"The water is in level 3."};
char msg4[] = {"The water is in level 4."};

int main(void)
{
	DDRB = 0x00; /*set PortB as input*/
	USART_init();
	
    while(1) //Infinite loop
    {
		if (PINB & 0x01)   {
		USART_putstring(msg1);			
		_delay_ms(5000); }
		
		else if (PINB & 0x03) {
		USART_putstring(msg2);
		_delay_ms(5000);  }
		
		else if (PINB & 0x07) {
		USART_putstring(msg3);		
		_delay_ms(5000); }
		
		else if (PINB & 0x0F) {
		USART_putstring(msg4);	
		_delay_ms(5000);  }
				
		
    }
	
	return 0;
}

void USART_send(unsigned char data){
	
	while(!(UCSR1A & (1<<UDRE1)));
	UDR1 = data;
}

void USART_putstring(char* StringPtr){
	
	while(*StringPtr != 0x00){
		USART_send(*StringPtr);
	StringPtr++;}
	
}

void USART_init(void){
	UBRR1H = (uint8_t)(BAUD_PRESCALLER>>8);
	UBRR1L = (uint8_t)(BAUD_PRESCALLER);
	UCSR1A = (1 << U2X1);
	UCSR1B = (1 << TXEN1);
	UCSR1C = (1 << UCSZ11) | (1 << UCSZ10);
}

any suggestions?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

what happens if you send a string right after you initialized the uart?

does the PC (when connected to that instead of another cpu) do receive data?
TXD and RXD swapped?
portB pins have external pull-downs?
you check on high level so in rest the pins should be low. you make them high.perhaps better to check for low level. Then you can enable internal pull-ups and have a defined level for sure. all you then need to do is pull the pins low.

edit:

you set the double speed bit, but I think the baudrate formula is for the normal speed. So it might be that you need to clear that. See datasheet on how and when the bit is to be used.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

the normal speed baudrate formula is (((F_CPU / (BAUDRATE * 16UL))) - 1)..so I am sure that the double speed baudrate formula is (((F_CPU / (BAUDRATE * 8UL))) - 1).

Actually, I am doing this for water level monitoring, but it only has 4 points. So Pin B0 to Pin B3 are connected with float switch, when it is floating or submerged I expect it to give logic one to PINBx register.

I have read about the internal pull-ups, in the datasheet, but I am confused.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I suggest taking a step backwards.....

You have tested the Mega32u4 module and when you connect TXD and RXD there with the set baud rate it works right?

if that does then forget about the floats for a while and go back to the basics. You have no communication. make a program that repeatedly just send out a character. If this is received by the 32u4 thenyour communications are OK (yes... you have a debug interface for the next steps)
now first check if writing the sentences as you made them work and give the expected reception. Note that you now put the strings in RAM and not in FLASH meaning on start they are loaded from flash in ram. You could take another step here first to put the strings in FLASH. reed the PROGMEM tutorial in the tutorials forum on how to do that.

last step is to see why the pins dont give the right value....

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your code says...

#define F_CPU 1000000UL 
#define BAUDRATE 9600 
#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 8UL))) - 1) 

Can you check replacing 8UL with F_CPU

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I use the following function to set the baud rate:

//*****************************************************************************
//*
//*	Function name : USART_set_baud_rate
//*
//*	Returns :		None
//*
//*	Parameters :	a_Baudrate : byte that is transmitted
//*
//*	Purpose :		function that calculates and sets the baudrate given
//*					
//*****************************************************************************
static void USART0_set_baud_rate(double a_BaudRate) 
{ 
   // calculate division factor for requested baud rate, and set it 
   int l_BaudDiv = (((F_CPU / (a_BaudRate * 16UL))) - 1) ;
   
   UBRR0L= l_BaudDiv; 
   UBRR0H= (l_BaudDiv>>8); 
} // USART0_set_baud_rate

Note that I do not use the X2 bit. you could change the code to not do that also.
what I do see is that you write first to the high register and then to the low register.
perhaps try these changes and let us know the result

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for helping guys..I will get back to this one. I have loaded the hex file to my Atmega32u4 module. I will try to use a terminal program to communicate with the module. If it is working, maybe my transceiver modules are the problem.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Can you check replacing 8UL with F_CPU
Huh???

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Koshchi wrote:
Quote:
Can you check replacing 8UL with F_CPU
Huh???

Yeh - that was an error in jiffy...pls ignore

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jeffreyarmingol wrote:
Thanks for helping guys..I will get back to this one. I have loaded the hex file to my Atmega32u4 module. I will try to use a terminal program to communicate with the module. If it is working, maybe my transceiver modules are the problem.

wait a sec....
the code you posted is that for the slave device or teh mega32u4?
because in the code you posted you have not enabled the receiver, nor have you posted code that will handle reception of bytes, so it is not bidirectional

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dude? why would I replace 8UL with F_CPU?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am not trying to receive data from pc, I am just trying to check if the terminal program can receive the data from Atmega32u4 or just trying to see if my atmega module is transmitting.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have you verified with a oscilloscope or even a LED if the UART transmits something or not? If it transmits, is it at the correct speed?

Are you sure your AVR is running at 10MHz? Have you set the fuses to use an external crystal instead of internal oscillator? Have you set the fuses not to divide the clock by 8 which is usually on by default?

Do you have a RS232 tranceiver chip between PC RS232 connection and AVR, or do you use some kind of TTL level direct connection to an USB-UART adapter?