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.

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

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top