PIC16F877A UART character display

Status
Not open for further replies.

sana_akhtar

Member level 2
Joined
Apr 21, 2012
Messages
47
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,606
Hey

Please help me in figuring out the problem in this code. I am interfacing UART of PIC16F877A with PC, baud rate 9600, 4MHz fosc. In main.c, I am just sending a char array through a command function Uart_Write_text. Testing circuit on proteus 8.1, the virtual termainal do show something but they are random characters, not what I am sending. Is there some problem with my code? What I am missing?

Code:
#ifndef _XTAL_FREQ
 #define _XTAL_FREQ 4000000
#endif


char UART_Init(const long int baudrate)
{
	unsigned int x;
	x = (_XTAL_FREQ - baudrate*64)/(baudrate*64);
	if(x>255)
	{
		x = (_XTAL_FREQ - baudrate*16)/(baudrate*16);
		BRGH = 1;
		SPBRG = x;
	 	SYNC = 0;
	    SPEN = 1;
        TRISC7 = 1;
        TRISC6 = 1;
        CREN = 1;
        TXEN = 1;
	    return 1;
	}
	if(x<256)
	{
	  BRGH=0;
	  SPBRG = x;
	  SYNC = 0;
	  SPEN = 1;
      TRISC7 = 1;
      TRISC6 = 1;
      CREN = 1;
      TXEN = 1;
	  return 1;
	}
	return 0;
}

char UART_TX_Empty()
{
  return TRMT;
}

char UART_Data_Ready()
{
   return RCIF;
}
char UART_Read()
{
 
  while(!RCIF);
  return RCREG;
}

void UART_Read_Text(char *Output, unsigned int length)
{
	int i;
	for(int i=0;i<length;i++)
		Output[i] = UART_Read();
}

void UART_Write(char data)
{
  while(!TRMT);
  TXREG = data;
}

void UART_Write_Text(char *text)
{
  int i;
  for(i=0;text[i]!='\0';i++)
	  TXREG=text[i];
}
 


Hi sana_akhtar;
Note that the MAX232 inverts each signal. However, the Virtual Terminal can also be set to inverting all (in its properties).
 

Glad it works but there are a few 'tidy up' things you can do in the UART_init function:

1. it returns '1' if x is less than or greater than 256 and '0' if it is 256. I can't see much point in that. Also if x is exactly 256 it will fail to initialize the port at all.

2. this code:
Code:
      SYNC = 0;
      SPEN = 1;
      TRISC7 = 1;
      TRISC6 = 1;
      CREN = 1;
      TXEN = 1;
is repeated regardless of x being > or < than 256 so you can restructure the code so the same lines are used only once.

Also check the formula for calculating x, I don't have data sheets with me at the moment but it looks suspicious to me.

Brian.
 
I did these changes. Still struggling with MAX232
 

If its not coming on Proteus,then something is wrong with your code
Try this
Code:
__CONFIG(FOSC_XT & WDTE_OFF & PWRTE_OFF & BOREN_ON & LVP_ON & CPD_OFF & WRT_OFF & CP_OFF);

void init()
{
     PORTC=0x00;
     TRISC7 = 1;
     TRISC6 = 0;
      SYNC = 0;
      SPEN=1;
      TXSTAbits.TX9=0;
      TXSTAbits.TXEN=1;
      BRGH=1;
      SPBRG = 25;
}

void main (void)
{
    init();
    while(1)
    {
        TXREG=0x41;
        while(!TRMT);
        
    }
}
 
Last edited by a moderator:

Thanks poojarai, its coming on the proteus now.
I am sending these commands to PC for a software. That software (designed specifically for this app) is displaying random numbers with great delays. For example, I want to send no. of outputs and output/hour. It isnt displaying anything accurately. This is the function I am using. It is working right on Proteus, but not on PC. Why??

Code:
void SendStringSerially(const unsigned char* st)
{
	int i;
	while(!TXIF);
	for (i=0; st[i]!='\0';i++)
	{
		SendByteSerially(st[i]);
	}
}
 

test TX register empty or not for each invoice of char


Code:
void SendStringSerially(const unsigned char* st)
{
    int i;
    for (i=0; st[i]!='\0';i++)
    {        while(!TXIF);
        SendByteSerially(st[i]);
    }
}

or

Code:
void SendStringSerially(const unsigned char* st){
	int i;
	for (i=0; st[i]!='\0';i++)
	{        while(!TRMT);
		  TXREG = st[i]);
	}
}
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…