Electronic Projects, forums and more.

Go Back   Electronic Circuits Projects Diagrams Free > Electronics Categories > Micro Controllers


Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc.

Reply
 
Tools
Old 3rd December 2008, 07:36 PM   #1
Default UART Transmitting Problem

Hello everybody,

I was trying to write a UART program to send out few bytes of data by using PIC16F877A, CCS C compiler, MPLAB IDE, MPLAB SIM. The problem of my program is the code fail to transmit out the data to pin RC6 of Port C. So far i am just use MPLAB SIM to simulate my program and using Watch window to monitor all the register and symbol. To simulate the program i was pressing the "step into" button, and the first 2 bytes of data was load to TXREG and TSR but after that not able to load the third bytes of data beacuse TXIF flag is not set, this showing that TXREG was still full and the data look like "jam" already. from the Watch window the Port C does not show any value(0x00), i also try to press "animate" and let the program run for few minutes but still no data was show on Port C. Anybody can help to solve the problem or give some suggestion?

Below is my program,

#include <16F877A.h>

//***** Function prototype ******//
void init(void);
void transmit (void);
void transmit_empty (void);

//*****variable declaration******//
unsigned char TXSTA,RCSTA,SPBRG,INTCON,PIR1,PIE1,TXREG,PORTC,TRI SC;
int count;

//****** define sfr address *****//
#byte TXSTA = 0x98
#byte RCSTA = 0x18
#byte SPBRG = 0x99
#byte PIE1 = 0x8c
#byte INTCON = 0x8b
#byte TXREG = 0x19
#byte RCREG = 0x1A
#byte PIR1 = 0x0c
#byte PORTC = 0x07
#byte TRISC = 0x87



char ucIPOD_packet_origin[2][7]={
{0xff,0x55,0x03,0x02,0x00,0x01,0xfa}, /* " play/pause " */
{0xff,0x55,0x03,0x02,0x00,0x08,0xf3} /* " fwd " */
};


/************************************************** ******************
FUNCTION : main()
DESCRIPTION : main loop
INPUT : Null
OUTPUT : Null
CREATE :
DATE : 07/10/08
************************************************** ******************/
void main()
{
init ();
transmit ();
while (1)
{
}
}


/************************************************** ******************
FUNCTION : init()
DESCRIPTION : sfr initialization
INPUT : Null
OUTPUT : Null
CREATE :
DATE : 07/10/08
************************************************** ******************/
void init ()
{
PORTC = 0x00; //0b 0000 0000 //Clear Port C

TRISC = 0xFF; //0b 1111 1111 //Enable USART Transmitter

TXSTA = 0x24; //0b 0010 0100 //Transmit Enable //SYNC = 0, Asynchronous Mode

RCSTA = 0x90; //0b 1001 0000 //Receive Enable //Serial Port Enable

SPBRG = 0x40; //0b 0100 0000 //SPBRG = 64, Baudrate = 19.231KBAUD, High Baud Rate

INTCON = 0x00; //0b 0000 0000 //Disable Global and Peripheral Interrupt

PIR1 = 0x10; //0b 0001 0000 //USART transmit/Receive Interrupt Flag bit

PIE1 = 0x00; //0b 0000 0000; //Individual enable bits for the peripheral interrupts.

count = 0;
}


/************************************************** ******************
FUNCTION : transmit()
DESCRIPTION : uart transmission
INPUT : Null
OUTPUT : Null
CREATE :
DATE : 07/10/08
************************************************** ******************/
void transmit ()
{
while (1) //Keep on looping
{
if (PIR1 == 0x10) //Check TXIF flag
{ //If TXREG is empty

TXREG = ucIPOD_packet_origin[0][count]; //Load data

count++; //Counter increment
}
}
}

[/code]

I am really no idea why such condition happen, everything look like set properly but it is not run.
Is it my simualtion methods is wrong or my code was having problem?

Any suggestion is appreciate.

Thanks
winson is offline  
Old 3rd December 2008, 10:52 PM   #2
Default

The TXIF goes high when the USART transmit buffer is full. I think that you are testing it the wrong way round. You should wait for it to go low not high before sending another byte.

When you test bit 4 of the PIR, you shouldn't test the whole register. PIR consists of

PSPIF ADIF RCIF TXIF SSPIF CCP1IF TMR2IF TMR1IF

so that will only be 0x10 if all the other bits are 0.

I don't write in C so I can't tell you how to just test bit 4. In assembly I would write:-

Code:
      btfsc      PIR, TXIF
      goto       [transmit next byte]
      [whatever needs to be done instead of transmitting byte]
I don't know if the simulator works with the USART. I use the simulator to make sure that the correct bytes are transmitted, but I don't really see how it can simulate the actual transmission.
Diver300 is offline  
Old 4th December 2008, 05:58 AM   #3
Default

Diver,
The TXIF goes high when the transmit buffer is empty. This generates an interrupt and allows you to load the next byte. It cannot be cleared in software and the only way to clear it is to write to TXREG.

winson,
I suspect Diver found your problem, namely how you test PIR1. The way to do this in C is compiler specific but you can try one of these,
Code:
	if(PIR1&1<<TXIF){
	if(PIR1.TXIF){
	if(PIR1Bits.TXIF){
The first one should work on any compiler.

Mike.
Pommie is online now  
Old 4th December 2008, 06:49 PM   #4
Default

My program is ok. I already successfully simulate my UART program by using Uart1 IO tab in MPLAB SIM. It is under Debugger > Settings > Uart1 IO. In Uart1 IO tab just click "Enable Uart IO" and select "Window" as output then press ok. After back to MPLAB main screen a "SIM Uart1" tab will exist in the output window. Press "run" to simulate the UART program and the transmitted data will show in output window as ASCII character, just have to refer ASCII table and verify the transmitted data.

Thanks everybody!
winson is offline  
Old 31st December 2008, 05:32 PM   #5
Default

Hi everybody.

I already try my UART transmiting program on the real hardware with a breadboard but the result is not successful. I was using an oscilloscope to trace the signal that send out from the USART Tx pin of 16F877A but the scope does not show any pulses and just maintain at 0V. This program is run well in MPLAB Simulation.

The peripheral circuitry of the 877A is simple, i was put the 20MHz crystal's leg to OSC1 and OSC2 with a 22pF capacitor from each crystal leg to ground. I connect 5V(3A) supply to the two VDD pin of 877A and 0V to the two VSS pin finally i also connect 5V supply to the MCLR pin for the reset purpose and i also try to put a 20k resistor to the VDD to limit the current but the result is still the same. This is all the thing that i do, but the scope does not show any digital pulses. Anybody can give me some suggestion or alert me some of the error that i done?
My latest version of code is show below, Thanks...

Code:
#include <16F877A.h>

//***** Function prototype ******//
void init(void);
void transmit (void);
void transmit_empty (void);

//*****variable declaration******//
unsigned char TXSTA,RCSTA,SPBRG,INTCON,PIR1,PIE1,TXREG,PORTC,TRISC;
int count, next;

//****** define sfr address *****//
#byte TXSTA		=  	0x98
#byte RCSTA		=	0x18
#byte SPBRG		=	0x99
#byte PIE1		=	0x8c
#byte INTCON		=	0x8b
#byte TXREG		=	0x19
#byte RCREG		=	0x1A
#byte PIR1		=	0x0c
#byte PORTC		=	0x07
#byte TRISC		= 	0x87
#bit  TXIF		=	PIR1.4
#bit  TRMT		=	TXSTA.1




char remote_command_basic[3][10]=
{
	{0xff,0x55,0x06,0x02,0x00,0x01,0x00,0x00,0x00,0xf7},	//0 Play/Pause
	{0xff,0x55,0x06,0x02,0x00,0x01,0x00,0x00,0x00,0xf7},	//1 Play/Pause
	{0xff,0x55,0x06,0x02,0x00,0x00,0x00,0x00,0x00,0xf8}	//2 Release
};

	
/********************************************************************
FUNCTION   	: main()
DESCRIPTION : main loop
********************************************************************/
void main()
{
	init ();
	transmit ();
	while (1)
	{
	}
}


/********************************************************************
FUNCTION   	: init()
DESCRIPTION : sfr initialization
********************************************************************/
void init ()
{
   
	PORTC = 0x00;	//0b 0000 0000		//Clear Port C
	
	TRISC = 0xFF;	//0b 1111 1111		//Enable USART Transmitter and Receiver
	
	TXSTA = 0x24;	//0b 0010 0100		//Transmit Enable	//SYNC = 0, Asynchronous Mode
	RCSTA = 0x90;	//0b 1001 0000		//Receive Enable	//Serial Port Enable
	
	SPBRG = 0x40;	//0b 0100 0000		//SPBRG = 64, Baudrate = 19.231KBAUD, High Baud Rate
	                                                                                
	INTCON = 0x00;	//0b 0000 0000		//Global and Peripheral Interrupt Disable

	PIR1 = 0x10;	//0b 0001 0000		//USART transmit/Receive Interrupt Flag bit

	PIE1 = 0x00;	//0b 0000 0000;		//Individual enable bits for the peripheral interrupts.
					
	count = 0;
	next = 0;
}


/********************************************************************
FUNCTION   	: transmit()
DESCRIPTION : uart transmission
********************************************************************/
void transmit ()
{
	while (1)					//Keep on looping
	{
		if (TXIF == 1)				//Check TXIF flag			
		{						//If TXREG is empty 
			
			TXREG = remote_command_basic[next][count];//Load data
			delay_cycles( 1 );		//NOP
			delay_cycles( 1 );		
			delay_cycles( 1 );
			
			if (count > 8)			//After 10th byte
			{
				next++;				//Next packet
				if (next > 2)		//After 3rd packet
				{
					return;			//Return to main()
				}
			}
			count++;				//Counter increment
			if (count > 9)			//After 10th byte
			{
				count = 0;			//Reset counter
			}
		}		//End first if loop
	}		//End while loop
}

Last edited by winson; 31st December 2008 at 05:36 PM.
winson is offline  
Old 17th January 2009, 01:54 AM   #6
Default

The program is working after i added some code to set the configuration words.
winson is offline  
Old 17th January 2009, 03:30 AM   #7
Default

its good to hear it works! also make sure you tie MCLR to VCC with at least a 10K resistor. Not straight to VCC.

Last edited by AtomSoft; 17th January 2009 at 03:35 AM. Reason: Typo
AtomSoft is offline  
Old 17th January 2009, 09:31 AM   #8
Default

Thanks Jason!

Now i aware that a program will not work in a PIC chip if we do not set the configuration words in the program code. I have added the following line of code to my program:

Code:
#fuses hs, nowdt, nolvp, noprotect
Just one line of code, and the thing will work nicely. The program is work well in MPLAB SIM simulation because by default MPLAB already set the configuration words properly in Configuration > Configuration Bits > Set Configuration Bits in Code.

Normal 20MHz oscilloscope will not able to see the data waveform clearly, i have use a 100MHz digital oscilloscope to trace the data waveform.

Regards,
Winson

Last edited by winson; 17th January 2009 at 09:39 AM. Reason: Add information
winson is offline  
Old 17th January 2009, 01:27 PM   #9
Default

Winson may i ask what kind of remote is this? Is it custom to control another project or is it some irDA type system? Just curious.
AtomSoft is offline  
Old 20th January 2009, 03:01 AM   #10
Default

It is not an irDA system but just is a custum remote control for my project.
winson is offline  
Reply

Tags
problem, transmitting, uart

Thread Tools
Display Modes


Similar
Title Starter Forum Replies Latest
UART problem-Where is first byte? Elvedin General Electronics Chat 2 22nd July 2008 03:19 PM
8051 Serial UART Problem ahmedragia21 8051/8951 6 16th December 2007 12:27 AM
Problem in applying configuration data to UART tkvenki Micro Controllers 0 22nd March 2007 11:59 AM
PIC 16F628A UART Coding Problem Gayan Soyza Micro Controllers 11 1st February 2007 12:59 PM
Maximum transmitting distance mstechca Electronic Projects Design/Ideas/Reviews 7 4th September 2005 02:30 PM



All times are GMT. The time now is 06:11 AM.


Electronic Circuits  |  Learning Electronics
eXTReMe Tracker