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.

Strange Problem with PIC18F4550 Serial Communication i am facing

Status
Not open for further replies.

xpress_embedo

Advanced Member level 4
Joined
Jul 5, 2011
Messages
1,154
Helped
161
Reputation
396
Reaction score
189
Trophy points
1,353
Location
India
Activity points
10,591
I had purchased a development board having PIC18F4550 Development Board

And i am trying to Check the Serial Communication of my Board.

The company of my Development Board had given a sample code for Transmission of Serial 'S'.

Here is the Code

Code:
	   		INCLUDE"P18F4550.INC"	;include PIC18F4580 definitions
		    ORG 0000H				;reset vector location
		    CLRF PCLATH				;clearing program counter higher bits
		    GOTO START				;jump to start up location defined at 30H
			ORG 0030H
			 
	START						;start of program		
	
			BCF TRISC,6			; configure RC6(TXD pin) as o/p [B]According to me this line is wrong as it is mentioned in data sheet that Rx and Tx pins TRIS value must be Set[/B]	
			BCF TXSTA,BRGH		; select baud-rate(9600)
			BCF BAUDCON,BRG16	; 8-bit Baud Rate Generator, SPBRG only 
							
								; value loaded corresponding to baud-rate,9600
			MOVLW 0x4D
			MOVWF SPBRG		
			BCF TXSTA,SYNC		; asynchronous mode select
			BSF TXSTA,TXEN		; 8-bit transmission enable
			BSF RCSTA,SPEN		; serial port enable

		    MOVLW 'S'			
		    MOVWF TXREG			;transmit buffer loaded with data to be transmitted   
	CHECK   
			BTFSS TXSTA,TRMT	;wait for complete transmission and skip if done
		    GOTO CHECK
		    
		    GOTO $				;infinite wait
		    
		    END					;end of program

this code this working fine in my Development Board
Here is the Output on USART Terminal
Proper_Receive.PNG

Means output is working Proper.
But in this code they have put SPBRG = 0x4D; means 77(decimal)
This doesn't correspond to 9600 Baud Rate according to Datasheet

Now i write my own code in Hi-Tech C Language for Serial Communication
Based on the above code
Code:
#include<htc.h>

/***************************
*   Device configuration   *
***************************/
#pragma config FOSC = HS	// Using 20 MHz crystal with PLL
//#pragma config PLLDIV = 5     	// Divide by 5 to provide the 96 MHz PLL with 4 MHz input
//#pragma config CPUDIV = OSC1_PLL2 // Divide 96 MHz PLL output by 2 to get 48 MHz system clock
#pragma config FCMEN = OFF	 // Disable Fail-Safe Clock Monitor
#pragma config IESO = OFF  	// Disable Oscillator Switchover mode
#pragma config PWRT = OFF 	 // Disable Power-up timer
#pragma config BOR = OFF   	// Disable Brown-out reset
#pragma config WDT = OFF  	 // Disable Watchdog timer
#pragma config MCLRE = ON  // Enable MCLR Enable
#pragma config LVP = OFF   // Disable low voltage ICSP
#pragma config ICPRT = OFF // Disable dedicated programming port (only on 44-pin devices)
#pragma config CP0 = OFF   // Disable code protection


#define TX TRISCbits.RC6
#define RX TRISCbits.RC7

void delay_ms(unsigned int time);
void delay_us(unsigned int time);
//void SerTX(unsigned char value);

void main()	@ 0x0000A0
{
	TRISB = 0x00;
	PORTB = 0x00;
	delay_ms(1000);
	PORTB = 0xFF;
	delay_ms(1000);
	TRISCbits.RC6 = 0;	
	TRISCbits.RC7 = 1;	//Make Input Pin
	TXSTAbits.BRGH = 0;	//Select Low Speed Baud Rate
	BAUDCONbits.BRG16 = 0;	//Select 8-bit Baud Rate Generator Only
	SPBRGH = 0x4D;                  //[B][I]Even when i change this value to 129 and BRGH to 1 i am getting the same result[/I][/B]
	TXSTAbits.SYNC = 0;	//Asynchronous Mode Selected
	TXSTAbits.TXEN = 1;	//8-bit Transmit mode enable
	RCSTAbits.SPEN = 1;	//Enable Serial Port Transmission
	
	while(1)
	{
		TXREG = 'S';
		while(TXSTAbits.TRMT == 0);
		
		PORTB = 0x00;
		delay_ms(1000);
		PORTB = 0xFF;
	}	
}


/*void SerTX(unsigned char value)
{
	TXREG = value;
	while(TXSTAbits.TRMT == 0);	
}*/

void delay_us(unsigned int time)
{
	unsigned int k;
	for(k=0;k<time;k++)
	{
		_delay(5);
	}
}

void delay_ms(unsigned int time)
{	
	unsigned int k;
	for(k=0;k<time;k++)
	{
		delay_us(1000);
	}
}

And i am getting this Output

Received Data.PNG

Which is not correct
 

The SPBRG = 0x4D value corresponds to a BAUD rate of 9600 with system clock of 48MHz.

It appears you have not properly configured your PLL to generate this system clock frequency.

The use of the High Speed Oscillator in addition to enabling the PLL must be specified in the device's Configuration Registers.

You need to specify the HS_PLL or similar bit mask, depending on your compiler version, check your device specific header (pic18f4550.h).

Also uncomment the two lines in your Configuration Register settings.

What version of the Hi-Tech PICC18 are you currently using?

BigDog
 
I am using Hi-Tech PICC18 Compiler.

My Board has 20Mhz Crystal
In my C code i had configured the Configuration Bits as HS for 20 Mhz not for HS_PLL mode..

So i think it should work..
I don't know what mistake i am doing...

In my c code
i had replaced the SPBRG value by 129 even that did not works :-(
 

I am using Hi-Tech PICC18 Compiler.

I realize you are using the Hi-Tech PICC18 Compiler. What version is it, v9.66, v9.xx, etc?

My Board has 20Mhz Crystal
In my C code i had configured the Configuration Bits as HS for 20 Mhz not for HS_PLL mode..

So i think it should work..
I don't know what mistake i am doing...

In my c code
i had replaced the SPBRG value by 129 even that did not works :-(

I was attempting to configure your PIC for an system clock of 48MHz, which is required by the way for Fast USB implementations.

However, the SPBRG value of 129 should produce a BAUD rate of 2400 with an error rate of -0,1% with the BRGH setting of 0, or a 9600 BAUD rate with -0.2% error rate with a BRGH setting of 1.

Did you remember to properly set your BRGH?

BigDog
 
I am HI-TECH C Compiler for PIC18 MCUs (Lite Mode) V9.80

And yes i had i had enabled the BRGH = 1

And using this..

Here is my code which is Configured for HS_PLL

Code:
#include<htc.h>
#include "delay.h"

void main()	@ 0x0000A0
{
	TRISB = 0x00;
	PORTB = 0x00;
	DelayMs(1000);
	PORTB = 0xFF;
	DelayMs(1000);
	TRISCbits.RC6 = 1;	
	TRISCbits.RC7 = 1;	//Make Input Pin
	TXSTAbits.BRGH = 0;	//Select Low Speed Baud Rate
	BAUDCONbits.BRG16 = 0;	//Select 8-bit Baud Rate Generator Only
	SPBRGH = 0x4D;
	TXSTAbits.SYNC = 0;	//Asynchronous Mode Selected
	TXSTAbits.TXEN = 1;	//8-bit Transmit mode enable
	RCSTA = 0x80;
	
	while(1)
	{
		TXREG = 'S';
		while(PIR1bits.TXIF == 0);
		
		PORTB = 0x00;
		DelayMs(1000);
		PORTB = 0xFF;
		DelayMs(1000);
	}	
}

Capture.PNG

Capture2.png

My TXIF gets high automatically after RCSTA = 0x80; line..
Why this is happening

In Datasheet
bit 4 TXIF: EUSART Transmit Interrupt Flag bit
1 = The EUSART transmit buffer, TXREG, is empty (cleared when TXREG is written)
0 = The EUSART transmit buffer is full

Why this happen..
bigdogguru pls help me
 

I had programmed that code into my controller..

and i am getting same data as seen previously

Received Data.PNG

But my proteus simulation is showing any data..

My controller has a inbuilt boot loader..

Is this causing a problem..
 

BigDogguru pls Help me...
I changed my compiler to check whether my code is working fine or not

I write this code for MPLABC18 Compiler

Code:
#include "p18f4550.h"
#include "delays.h"
#include "usart.h"

/*********Setting Configuration Bits************/
#pragma config FOSC = HSPLL_HS
#pragma config FCMEN = OFF	// Disable Fail-Safe Clock Monitor
#pragma config IESO = OFF   // Disable Oscillator Switchover mode
#pragma config PWRT = OFF   // Disable Power-up timer
#pragma config BOR = OFF  	// Disable Brown-out reset
#pragma config WDT = OFF    // Disable Watchdog timer
#pragma config MCLRE = ON   // Enable MCLR Enable
#pragma config LVP = OFF    // Disable low voltage ICSP
#pragma config ICPRT = OFF  // Disable dedicated programming port (only on 44-pin devices)
#pragma config CP0 = OFF    // Disable code protection

/***********************************************/

void DelayMs(unsigned int itime);

unsigned int i;
void main()
{
	TRISB = 0x00;
	PORTB = 0xFF;
	DelayMs(1000);
	// configure USART
	OpenUSART( USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW,77 );
	DelayMs(10);
	while(BusyUSART());	//Wait Until USART gets Ready
	DelayMs(10);
	
	for(i=0;i<10;i++)
	{
		WriteUSART('A');
		DelayMs(1000);
	}
	CloseUSART();
	PORTB = 0x00;
	DelayMs(1000);
	PORTB = 0xFF;
	while(1);
}



void DelayMs(unsigned int itime)
{
	unsigned int k;
	for(k=0;k<itime/2;k++)
	{	
		Delay10KTCYx(1);
	}
}

Means using 20Mhz Crystal with PLL to get 48Mhz

I am getting the appropriate data..
Means 10 times A on the Serial Port

That's fine for me..
But when i change this code to

Code:
#include "p18f4550.h"
#include "delays.h"
#include "usart.h"

/*********Setting Configuration Bits************/
#pragma config FOSC = HS     [B][I]Only 20Mhz Oscillator[/I][/B]
#pragma config FCMEN = OFF	// Disable Fail-Safe Clock Monitor
#pragma config IESO = OFF   // Disable Oscillator Switchover mode
#pragma config PWRT = OFF   // Disable Power-up timer
#pragma config BOR = OFF  	// Disable Brown-out reset
#pragma config WDT = OFF    // Disable Watchdog timer
#pragma config MCLRE = ON   // Enable MCLR Enable
#pragma config LVP = OFF    // Disable low voltage ICSP
#pragma config ICPRT = OFF  // Disable dedicated programming port (only on 44-pin devices)
#pragma config CP0 = OFF    // Disable code protection

/***********************************************/

void DelayMs(unsigned int itime);

unsigned int i;
void main()
{
	TRISB = 0x00;
	PORTB = 0xFF;
	DelayMs(1000);
	// configure USART
	OpenUSART( USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH,129 );  [B][I]//To get 9600 Baud rate[/I][/B]
	DelayMs(10);
	while(BusyUSART());	//Wait Until USART gets Ready
	DelayMs(10);
	
	for(i=0;i<10;i++)
	{
		WriteUSART('A');
		DelayMs(1000);
	}
	CloseUSART();
	PORTB = 0x00;
	DelayMs(1000);
	PORTB = 0xFF;
	while(1);
}



void DelayMs(unsigned int itime)
{
	unsigned int k;
	for(k=0;k<itime/2;k++)
	{	
		Delay10KTCYx(1);
	}
}

I am getting the redundant data 10 times..
What i personally feel is that .. it is the problem related to Baud rate or TTL to Serial Port Logic Conversion
 

Hello!!!
This Code is Working Fine in Proteus..
It is written in HiTech C Compiler and is working fine in Proteus

Code:
#include<htc.h>
#include "delay.h"



///***************************
//*   Device configuration   *
//***************************/
#pragma config FOSC = HS	// Using 20 MHz crystal with PLL
//#pragma config PLLDIV = 5     	// Divide by 5 to provide the 96 MHz PLL with 4 MHz input
//#pragma config CPUDIV = OSC1_PLL2 // Divide 96 MHz PLL output by 2 to get 48 MHz system clock
#pragma config FCMEN = OFF	 // Disable Fail-Safe Clock Monitor
#pragma config IESO = OFF  	// Disable Oscillator Switchover mode
#pragma config PWRT = OFF 	 // Disable Power-up timer
#pragma config BOR = OFF   	// Disable Brown-out reset
#pragma config WDT = OFF  	 // Disable Watchdog timer
#pragma config MCLRE = ON  // Enable MCLR Enable
#pragma config LVP = OFF   // Disable low voltage ICSP
#pragma config ICPRT = OFF // Disable dedicated programming port (only on 44-pin devices)
#pragma config CP0 = OFF   // Disable code protection


#define TX TRISCbits.RC6
#define RX TRISCbits.RC7


//void SerTX(unsigned char value);

void main()	@ 0x0000A0
{
	TRISB = 0x00;
	PORTB = 0x00;
	DelayMs(1000);
	PORTB = 0xFF;
	DelayMs(1000);
	TRISCbits.RC6 = 0;	
	TRISCbits.RC7 = 1;	//Make Input Pin
	TXREG = 0x00;
	SPBRG = 129;
	TXSTAbits.TXEN = 1;
	RCSTAbits.SPEN = 1;
	TXSTAbits.BRGH = 1;
	BRG16 = 0;
	
	while(1)
	{
		while(PIR1bits.TXIF == 0);
		TXREG = 'A';
		DelayMs(1000);
	}
}

This Code is Working fine in Proteus

But in real Development Board it is giving redundant data

But when i program using this CODE

Code:
#include<htc.h>
#include "delay.h"



///***************************
//*   Device configuration   *
//***************************/
#pragma config FOSC = HS	// Using 20 MHz crystal with PLL
//#pragma config PLLDIV = 5     	// Divide by 5 to provide the 96 MHz PLL with 4 MHz input
//#pragma config CPUDIV = OSC1_PLL2 // Divide 96 MHz PLL output by 2 to get 48 MHz system clock
#pragma config FCMEN = OFF	 // Disable Fail-Safe Clock Monitor
#pragma config IESO = OFF  	// Disable Oscillator Switchover mode
#pragma config PWRT = OFF 	 // Disable Power-up timer
#pragma config BOR = OFF   	// Disable Brown-out reset
#pragma config WDT = OFF  	 // Disable Watchdog timer
#pragma config MCLRE = ON  // Enable MCLR Enable
#pragma config LVP = OFF   // Disable low voltage ICSP
#pragma config ICPRT = OFF // Disable dedicated programming port (only on 44-pin devices)
#pragma config CP0 = OFF   // Disable code protection


#define TX TRISCbits.RC6
#define RX TRISCbits.RC7


//void SerTX(unsigned char value);

void main()	@ 0x0000A0
{
	TRISB = 0x00;
	PORTB = 0x00;
	DelayMs(1000);
	PORTB = 0xFF;
	DelayMs(1000);
	TRISCbits.RC6 = 0;	
	TRISCbits.RC7 = 1;	//Make Input Pin
	TXREG = 0x00;
	SPBRG = 77;
	TXSTAbits.TXEN = 1;
	RCSTAbits.SPEN = 1;
	TXSTAbits.BRGH = 0;
	BRG16 = 0;
	
	while(1)
	{
		while(PIR1bits.TXIF == 0);
		TXREG = 'A';
		DelayMs(1000);
	}
}

This code is written to send data at the BaudRate of 9600bps but i forget to use HSPLL_HS config setting..

And it still works on my Development Board..
What does it means

I think my Bootloader is not able to program the configuration bits..
And has a default config setting for all cases..
Am i right..

Now a question i want to ask
Are bootloaders able to program the configuration bits..
 

I think my Bootloader is not able to program the configuration bits..
And has a default config setting for all cases..
Am i right..

Yes. It is possible the bootloader is not reconfiguring the Configuration Registers, that would explain why the code appears to run however the BAUD rate is not properly configured due to the incorrect system clock configuration.

Now a question i want to ask
Are bootloaders able to program the configuration bits..

Yes, however it depends both on the bootloader supporting the feature and the device being programmed.

Reference: PIC18F2455/2550/4455/4550 Datasheet, Section: 7.1 EECON1 and EECON2 Registers, Pg. 91
7.1 EECON1 and EECON2 Registers

Access to the data EEPROM is controlled by two
registers: EECON1 and EECON2. These are the same
registers which control access to the program memory
and are used in a similar manner for the data
EEPROM.

The EECON1 register (Register 7-1) is the control
register for data and program memory access. Control
bit, EEPGD, determines if the access will be to program
or data EEPROM memory. When clear, operations will
access the data EEPROM memory. When set, program
memory is accessed.

Control bit, CFGS, determines if the access will be to
the Configuration registers or to program memory/data
EEPROM memory.
When set, subsequent operations
access Configuration registers. When CFGS is clear,
the EEPGD bit selects either Flash program or data
EEPROM memory.

The WREN bit, when set, will allow a write operation.
On power-up, the WREN bit is clear. The WRERR bit is
set in hardware when the WREN bit is set and cleared
when the internal programming timer expires and the
write operation is complete.


Reference: PIC18F2455/2550/4455/4550 Datasheet, Section: 25.1 Configuration Bits, Pg. 292
25.1 Configuration Bits

The Configuration bits can be programmed (read as
‘0’) or left unprogrammed (read as ‘1’) to select various
device configurations. These bits are mapped starting
at program memory location 300000h.

The user will note that address 300000h is beyond the
user program memory space. In fact, it belongs to the
configuration memory space (300000h-3FFFFFh),
which can only be accessed using table reads and
table writes.

Programming the Configuration registers is done in a
manner similar to programming the Flash memory. The
WR bit in the EECON1 register starts a self-timed write
to the Configuration register. In normal operation mode,
a TBLWT instruction, with the TBLPTR pointing to the
Configuration register, sets up the address and the
data for the Configuration register write. Setting the WR
bit starts a long write to the Configuration register. The
Configuration registers are written a byte at a time. To
write or erase a configuration cell, a TBLWT instruction
can write a ‘1’ or a ‘0’ into the cell. For additional details
on Flash programming, refer to Section 6.5 “Writing
to Flash Program Memory”.

Therefore in the case of the PIC18F4550, as well as most of the PIC18F, the Configuration Registers can be reprogrammed at runtime or from within code.

BigDog
 
Thank BigDogGuru...

I think configuring the configuration bits using the above technology..
But will it affect the bootloader code in my controller..

Anyways thanks BigDogGuru..
I will run my code with 48Mhz Crystal..
 

I think configuring the configuration bits using the above technology..
But will it affect the bootloader code in my controller..

I posted the info to demonstrate that a bootloader can indeed reconfigure the Configuration Register Bits within code or runtime.

Although, in theory you should be able modify the Configuration Registers within your code as long as the lock bit is not set.


I will run my code with 48Mhz Crystal..

Have you tried modifying your program/Configuration Registers to configure the PLL to generate a system clock of 48MHz?

If their assembly language example performs as expected at a system clock of 48MHz, you should as well.


BigDog
 

The following code is working for me...
Even i had set HS oscillator in configuration bits,
Changing that to HSPLL_HS also works,
What i mean whatever i do my board will run with 48Mhz Crystal..
My Bootloader is not changing the configuration bits..


Code:
#include<htc.h>
#include "delay.h"



///***************************
//*   Device configuration   *
//***************************/
#pragma config FOSC = HS	// Using 20 MHz 
//#pragma config PLLDIV = 5     	// Divide by 5 to provide the 96 MHz PLL with 4 MHz input
//#pragma config CPUDIV = OSC1_PLL2 // Divide 96 MHz PLL output by 2 to get 48 MHz system clock
#pragma config FCMEN = OFF	 // Disable Fail-Safe Clock Monitor
#pragma config IESO = OFF  	// Disable Oscillator Switchover mode
#pragma config PWRT = OFF 	 // Disable Power-up timer
#pragma config BOR = OFF   	// Disable Brown-out reset
#pragma config WDT = OFF  	 // Disable Watchdog timer
#pragma config MCLRE = ON  // Enable MCLR Enable
#pragma config LVP = OFF   // Disable low voltage ICSP
#pragma config ICPRT = OFF // Disable dedicated programming port (only on 44-pin devices)
#pragma config CP0 = OFF   // Disable code protection


#define TX TRISCbits.RC6
#define RX TRISCbits.RC7


//void SerTX(unsigned char value);

void main()	@ 0x0000A0
{
	TRISB = 0x00;
	PORTB = 0x00;
	DelayMs(1000);
	PORTB = 0xFF;
	DelayMs(1000);
	TRISCbits.RC6 = 0;	
	TRISCbits.RC7 = 1;	//Make Input Pin
	TXREG = 0x00;
	SPBRG = 77;
	TXSTAbits.TXEN = 1;
	RCSTAbits.SPEN = 1;
	TXSTAbits.BRGH = 0;
	BRG16 = 0;
	
	while(1)
	{
		while(PIR1bits.TXIF == 0);
		TXREG = 'A';
		DelayMs(1000);
	}
}
 

My Bootloader is not changing the configuration bits..

Maybe you should try changing the Configuration Registers in a small demo program?

You should also consider replacing the bootloader with one that is well documented and source code is available.

BigDog
 

Maybe you should try changing the Configuration Registers in a small demo program?

I have tried,
I write a simple code to toggle the LED state on PORTB.
I know there is a bit PBADEN bit in Configuration Register which must be configured to make PORTB as Digital I\O pin.

I haven't enabled that, it means only 4 led's must glow rest 4 should not..
But in my dev board all are glowing..
This shows the sign that i am not able to program the configuration bits..

And before this serial port transmission is also reflecting the cause that i am not able to change my configuration bit.

You should also consider replacing the bootloader with one that is well documented and source code is available.

Yes i will do so. if you help me in finding out a bootloader, i will be thankful to you.

And pls also tell me how to program my controller using that boot-loader.

My Development board company has provided me this software to program the hex code..
Capture.PNG
 

Maybe you should try changing the Configuration Registers in a small demo program?

I have tried,
I write a simple code to toggle the LED state on PORTB.
I know there is a bit PBADEN bit in Configuration Register which must be configured to make PORTB as Digital I\O pin.

I haven't enabled that, it means only 4 led's must glow rest 4 should not..
But in my dev board all are glowing..
This shows the sign that i am not able to program the configuration bits..

And before this serial port transmission is also reflecting the cause that i am not able to change my configuration bit.

You should also consider replacing the bootloader with one that is well documented and source code is available.

Yes i will do so. if you help me in finding out a bootloader, i will be thankful to you.

And pls also tell me how to program my controller using that boot-loader.

My Development board company has provided me this software to program the hex code..
View attachment 69756
 

I suspect the current settings of the boards Configuration Registers has several Code Protection and Configuration Registers Protection bits set.

In effect preventing you from modifying the bootloader storage areas or the Configuration Registers.

I'm still have trouble understanding why the manufacture of your dev board won't provide you with at least a HEX file of the bootloader.

Which would allow you to wipe the device and later reinstall the bootloader.

Maybe you should contact them and explain you have upgraded the PIC from a PIC18F4550 to a PIC18F4553 and you need the bootloader HEX file to install it in the new device.

After all their online product page states the dev board supports various PICs, implying you can change the devices.

And the PIC18F4553 is fully compatible with the PIC18F4550 except it has 12-bit ADC rather than 10-bit ADC, as a matter of fact they use the same datasheet as the PIC18F4550 with a short addendum covering only the minor differences.

BigDog
 

Hello!! BigDogGuru the Development Board Company has given me the bootloader..
I am attaching that,
Pls have a look on that, and tell me what i can i do.
Or how can i modify the bootloader


View attachment tinybld18F2550usb.zip

Configuration_Bit_Setting_in_Bootloader.png

Pls have a look on both attachements
 
Last edited:

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top