see this code and help me out in USART comm.

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

i am using USART to communicate with my Nokia 3220 using AT commands. I have also connected a LCD at Port B in my project. For testing purpose i am connecting microcontroller to the computer serial port and using hyprterminal to see the response of the code. My code is working fine and the USART is initialized properly and i am also reciving ATD xxxxxxxxx;at the hyperterminal but the characters send by me are not getting echo and also they are not getting displayed on the LCD can someone tell me where is the problem. Here is my program code

#define USART_BAUDRATE 115200
#define F_CPU 3686400
#include 
#include 
#include 
#include 
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
#define CLR_RS (PORTA &= 0xFD)
#define SET_RS (PORTA |= 0x02)
#define CLR_EN (PORTA &= 0xFE)
#define SET_EN (PORTA |= 0x01)

//LCD data bus is PORTB
//LCD EN is PortA.0
//LCD RS is PortA.1
//Device 1 with LED is at PortA.5 
//Device 2 with LED is at PortA.5
//Device 3 with LED is at PortA.6
//Device 4 with LED is at PortA.7

void lcd_cmd(char cmd)
{
CLR_RS;
CLR_EN;
PORTB=cmd;
_delay_us(70);
SET_EN;
CLR_EN;
}

void lcd_wl(char TxtLine[16], short int SecondLine)
{
int i=0;
lcd_cmd(0x80);
if(SecondLine)
	lcd_cmd(0xC0);
SET_RS;
SET_EN;
CLR_EN;
	while(TxtLine[i])
	{
	PORTB=TxtLine[i];
	SET_EN;
	CLR_EN;
	_delay_us(60);
	i++;
	}
	for(;i<16;i++)
	{
	CLR_EN;
	PORTB=0x20;
	SET_EN;
	CLR_EN;
	_delay_us(60);
	} 
}

void USART_TX(char *TxStr)
{
int i;
for (i=0;TxStr[i];i++)
	{
	while ((UCSRA & (1<<UDRE)) == 0);
	UDR=TxStr[i];
	}
}


void INIT()
{
//USART INITIALIZATION
// Turn on the transmission and reception circuitry 
	UCSRB |= (1 << RXEN) | (1 << TXEN);   					
// Use 8-bit character sizes 	
   	UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); 	
// Load lower 8-bits of the baud rate value into the low byte of the UBRR register 
   	UBRRL = BAUD_PRESCALE; 			
// Load upper 8-bits of the baud rate value into the high byte of the UBRR register 
   	UBRRH = (BAUD_PRESCALE >> 8); 	
_delay_ms(5);
DDRA=0xFF;
PORTA=0;
DDRB=0xFF;
PORTB=0;
//LCD INITIALIZATION
//set function 
lcd_cmd(0x38);
//Display on
lcd_cmd(0x0E);
//Display clear
lcd_cmd(0x01);
//entry mode
lcd_cmd(0x06);
}

int main()
{
int i=0;
char tmp[2];
INIT();
lcd_wl(" Initialized",0);
lcd_wl(" Calling...",1);
USART_TX("ATD xxxxxxxxx;\r");
lcd_wl(" ATD command sent",0);
char c;
PORTA=0xFF;
while(1)
	{	
      while ((UCSRA&(1<<RXC))==0);
	  c=UDR;
	  tmp[0] = c; 
	  tmp[1]='\0';
	  USART_TX(tmp);
	  lcd_wl(tmp,0);
	  PORTA = ~PORTA;
   }    
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

while(1)
{
while ((UCSRA&(1<<RXC))==0);
c=UDR;
tmp[0] = c;
tmp[1]='\0';
USART_TX(tmp);
lcd_wl(tmp,0);
PORTA = ~PORTA;
}

At a guess, id say this is where your problem is. What is going to happen to the incomming characters when you're waiting to send them out and write them to the lcd? Investigate using interrupts for the serial comms and a circular buffer for the rx data. This will remove the timing requirement for the received characters.

For example: each character at 115200 baud takes around 86uS. Writing one character alone to your LCD takes a minimum of 60uS and you wait to send the character out the serial port - 86uS per character -oops! we've lost some received characters!

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

@Kartman thnx for your reply. can u tell me wht exactly is circular buffer and how to declare and use circular buffer??

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

Wait a minute.... you asked what was wrong, he told you what was wrong and how to fix it, search for 'circular buffer'... or send him a plane ticket to come type it in for you. What word is tripping you up? Surely you must grok the concept of 'circular'. How about 'buffer'? You can program c and cant visualize 'buffer'? Just declare an array and put chars in at the 'inputindex' and pull them out at the 'outputindex'. After writing a char in the last position in the array, reset the inputindex to 0. Hopefully, you will have done something with the char at 0 before it gets overwritten.

Imagecraft compiler user

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

How about a ring buffer instead of circular buffer? Only difference is the name :)

- Jani

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

I've posted an interrupt driven USART tutorial in the Tutorials section of this site. Seems like your code is based on the code I wrote for the first one - check out the new tutorial which expands on the previous one.

As for a ring (circular) buffer, I've posted two of my variants on my site here.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!