PIC18F uart baud rate problem

Discussion about projects that used PIC Microcontroller, Hardware Interface, Programming Algorithm and etc......

PIC18F uart baud rate problem

Postby jeffrey5337 » Thu Mar 03, 2011 9:13 pm

Hi, I was testing a simple uart program, modify from cytron's example of "uart" from "SK40C 18F4520 Sample Program".


The only difference is I try to keep sending the string "OK" out without receiving any characters and I use PIC18F4550.
CODE: SELECT_ALL_CODE
//=============================================================================
// Filename: Example_uart.c
//-----------------------------------------------------------------------------
// Compiled using MPLAB-C18 v3.34 student edition
//=============================================================================
// Company   : Cytron Technologies, Malaysia
// Revision   : 1.00
// Date      : 28 Dec 2009
//=============================================================================
#include <p18f4550.h>
#include "delays.h"

//=============================================================================
//   Configuration Bits
//=============================================================================
/** CONFIGURATION **************************************************/
#pragma config PLLDIV   = 5         // (20 MHz crystal on PICDEM FS USB board)
#pragma config CPUDIV   = OSC1_PLL2   
#pragma config USBDIV   = 2         // Clock source from 96MHz PLL/2
#pragma config FOSC     = HSPLL_HS
#pragma config FCMEN    = OFF
#pragma config IESO     = OFF
#pragma config PWRT     = OFF
#pragma config BOR      = ON
#pragma config BORV     = 3
#pragma config VREGEN   = ON      //USB Voltage Regulator
#pragma config WDT      = OFF
#pragma config WDTPS    = 32768
#pragma config MCLRE    = ON
#pragma config LPT1OSC  = OFF
#pragma config PBADEN   = OFF
// #pragma config CCP2MX   = ON
#pragma config STVREN   = ON
#pragma config LVP      = OFF
// #pragma config ICPRT    = OFF       // Dedicated In-Circuit Debug/Programming
#pragma config XINST    = OFF       // Extended Instruction Set
#pragma config CP0      = OFF
#pragma config CP1      = OFF
// #pragma config CP2      = OFF
// #pragma config CP3      = OFF
#pragma config CPB      = OFF
// #pragma config CPD      = OFF
#pragma config WRT0     = OFF
#pragma config WRT1     = OFF
// #pragma config WRT2     = OFF
// #pragma config WRT3     = OFF
#pragma config WRTB     = OFF       // Boot Block Write Protection
#pragma config WRTC     = OFF
// #pragma config WRTD     = OFF
#pragma config EBTR0    = OFF
#pragma config EBTR1    = OFF
// #pragma config EBTR2    = OFF
// #pragma config EBTR3    = OFF
#pragma config EBTRB    = OFF

//=============================================================================
//   Define Pins
//=============================================================================
#define PIC_CLK 20000000
#define BAUD 9600
//#define DIVIDER ((PIC_CLK/(16UL * BAUD) -1))
#define DIVIDER ((PIC_CLK/BAUD)/16) -1
#define HIGH_SPEED 1
#define LOW_SPEED 0

#define sw1         PORTBbits.RB0      //Active Low
#define sw2         PORTBbits.RB1


//=============================================================================
//   Function Prototypes
//=============================================================================
void Delay_1msX (unsigned int miliseconds);
void Delay_100msX (unsigned int msec);

int uart_init(){
   // SPBRGH = 0;   
   SPBRG = DIVIDER;                  //set baud rate to 9600 for 20Mhz
   TXSTAbits.BRGH = HIGH_SPEED;      //baud rate high speed option
   
   TXSTAbits.SYNC = 0;     //Asynchronous mode
   RCSTAbits.SPEN = 1;     //Serial port enable
   RCSTAbits.CREN = 1;     //enable reception.
   TXSTAbits.TX9=0;        //8-bit transmission
   RCSTAbits.RX9=0;        //8-bit reception
   
   TXSTAbits.TXEN=0;                  //reset transmitter
   TXSTAbits.TXEN=1;                  //enable the transmitter
   TRISC = 0b10000000;   // RC7 = RX = input, RC6 = TX = output
   return 1;
}

void clear_usart_error(void)
{
   if (RCSTAbits.OERR)
   {                                                   
      TXSTAbits.TXEN=0;                                       
      TXSTAbits.TXEN=1;                                       
      RCSTAbits.CREN=0;                                       
      RCSTAbits.CREN=1;                                       
   }

   if (RCSTAbits.FERR)
   {                                                                               
      TXSTAbits.TXEN=0;                                       
      TXSTAbits.TXEN=1;
   }
}

void uart_send(char data)
{
   while(!PIR1bits.TXIF);
   TXREG = data;
}

char uart_rec(void)
{
   while(!PIR1bits.RCIF)
   {
      clear_usart_error();
   }
   return RCREG;
}

void uart_string(unsigned char *str_ptr)
{
   while(!PIR1bits.TXIF);
   while (*str_ptr)
   {
      uart_send(*str_ptr);
      str_ptr++;
   }
   return;
}


//=============================================================================
//   Global Variables
//=============================================================================
unsigned int i, t;
unsigned char data_tx, data_rx;


//=============================================================================
//   Main Program
//=============================================================================
void main ()
{
   //set I/O input output
   TRISB = 0b00000011;               //Configure PORTB I/O direction
   TRISC = 0b10000000;               //Configure PORTC I/O direction
   TRISD = 0b00000000;               //Configure PORTD I/O direction
   PORTB = 0;
   PORTC = 0;
   PORTD = 0;

   //-------------------------------------------------------------------------
   // Configure UART
     //-------------------------------------------------------------------------
   /*
   OpenUSART (USART_TX_INT_OFF &             //Transmit interrupt off
      USART_RX_INT_OFF &                //Receive interrupt off
      USART_ASYNCH_MODE &                //Asynchronous mode - UART
      USART_EIGHT_BIT &                //8-bit transmit/receive
      USART_CONT_RX &                //Continuous reception
      USART_BRGH_HIGH,               //High baudrate
      129);                     //9600 baudrate at 20MHz frequency
   */
   uart_init();
   
   while(1)
   {
      //-------------------------------------------------------------------------
      // UART Transmit
      //-------------------------------------------------------------------------
      data_tx='O';                     //Assign data
      uart_send(data_tx);                  //Send data through UART

      data_tx='K';                     //Assign data
      uart_send(data_tx);                  //Send data through UART

   }   
}//End of main



//=============================================================================
//   Subroutines
//=============================================================================

/********************************************************************
*       Function Name:  Delay_1msX                                  *
*       Return Value:   void                                        *
*       Parameters:     miliseconds: amount of delay            *
*       Description:    This routine generates various delays       *
*                  needed by xlcd functions.               *
*                  For delay of 1ms (18F4550 running at 48MHz)   *
*                  Cycles = (TimeDelay * Fosc) / 4            *
*                  Cycles = (1ms * 48MHz) / 4               *
*                  Cycles = 12,000                        *
*                  Since call of function also takes some       *
*                  instruction cycles, the exact value to get   *
*                  1ms delay is less than 12,000.            *
********************************************************************/
void Delay_1msX (unsigned int miliseconds)
{
   t=0;
   while(t<miliseconds)
   {
      Delay1KTCYx(11);
      Delay10TCYx(96);
      Nop();
      Nop();
      Nop();
      Nop();
      Nop();
      t++;
   }
}//End of Delay_1msX


/********************************************************************
*       Function Name:  Delay_100msX                                  *
*       Return Value:   void                                        *
*       Parameters:     miliseconds: amount of delay            *
*       Description:    This routine generates various delays       *
*                  needed by xlcd functions.               *
*                  For delay of 100ms                     *
*                  (18F4550 running at 48MHz)               *
*                  Cycles = (TimeDelay * Fosc) / 4            *
*                  Cycles = (100ms * 48MHz) / 4            *
*                  Cycles = 1,200,000                     *
*                  Since call of function also takes some       *
*                  instruction cycles, the exact value to get   *
*                  1ms delay is less than 1,200,000.         *
********************************************************************/
void Delay_100msX (unsigned int msec)
{
   t=0;
   while(t<msec)
   {
      Delay10KTCYx(119);
      Delay1KTCYx(9);
      Delay10TCYx(96);
      t++;
   }
}//End of Delay_100msX

Then I try to receive the characters from the PC side using a RS232 converter and eventually I receive garbage characters, can anyone help?

In this program, it receive 0xAD for both "O" and "K"...


solved: it should be #pragma config FOSC = HS instead of #pragma config FOSC = HSPLL_HS.
can anyone tell me the reasons?
jeffrey5337
Greenhorn
 
Posts: 3
Joined: Wed Oct 27, 2010 2:02 am

Re: PIC18F uart baud rate problem

Postby yonghui » Fri Mar 04, 2011 12:01 am

most probably incorrect baud rate.

the baud rate generator register value is incorrect
thanks&regards,
yh
yonghui
Professional
 
Posts: 732
Joined: Mon Sep 28, 2009 3:27 pm

Re: PIC18F uart baud rate problem

Postby zhenning » Sat Apr 09, 2011 2:57 pm

jeffrey5337 WROTE:Hi, I was testing a simple uart program, modify from cytron's example of "uart" from "SK40C 18F4520 Sample Program".


The only difference is I try to keep sending the string "OK" out without receiving any characters and I use PIC18F4550.
CODE: SELECT_ALL_CODE
//=============================================================================
// Filename: Example_uart.c
//-----------------------------------------------------------------------------
// Compiled using MPLAB-C18 v3.34 student edition
//=============================================================================
// Company   : Cytron Technologies, Malaysia
// Revision   : 1.00
// Date      : 28 Dec 2009
//=============================================================================
#include <p18f4550.h>
#include "delays.h"

//=============================================================================
//   Configuration Bits
//=============================================================================
/** CONFIGURATION **************************************************/
#pragma config PLLDIV   = 5         // (20 MHz crystal on PICDEM FS USB board)
#pragma config CPUDIV   = OSC1_PLL2   
#pragma config USBDIV   = 2         // Clock source from 96MHz PLL/2
#pragma config FOSC     = HSPLL_HS
#pragma config FCMEN    = OFF
#pragma config IESO     = OFF
#pragma config PWRT     = OFF
#pragma config BOR      = ON
#pragma config BORV     = 3
#pragma config VREGEN   = ON      //USB Voltage Regulator
#pragma config WDT      = OFF
#pragma config WDTPS    = 32768
#pragma config MCLRE    = ON
#pragma config LPT1OSC  = OFF
#pragma config PBADEN   = OFF
// #pragma config CCP2MX   = ON
#pragma config STVREN   = ON
#pragma config LVP      = OFF
// #pragma config ICPRT    = OFF       // Dedicated In-Circuit Debug/Programming
#pragma config XINST    = OFF       // Extended Instruction Set
#pragma config CP0      = OFF
#pragma config CP1      = OFF
// #pragma config CP2      = OFF
// #pragma config CP3      = OFF
#pragma config CPB      = OFF
// #pragma config CPD      = OFF
#pragma config WRT0     = OFF
#pragma config WRT1     = OFF
// #pragma config WRT2     = OFF
// #pragma config WRT3     = OFF
#pragma config WRTB     = OFF       // Boot Block Write Protection
#pragma config WRTC     = OFF
// #pragma config WRTD     = OFF
#pragma config EBTR0    = OFF
#pragma config EBTR1    = OFF
// #pragma config EBTR2    = OFF
// #pragma config EBTR3    = OFF
#pragma config EBTRB    = OFF

//=============================================================================
//   Define Pins
//=============================================================================
#define PIC_CLK 20000000
#define BAUD 9600
//#define DIVIDER ((PIC_CLK/(16UL * BAUD) -1))
#define DIVIDER ((PIC_CLK/BAUD)/16) -1
#define HIGH_SPEED 1
#define LOW_SPEED 0

#define sw1         PORTBbits.RB0      //Active Low
#define sw2         PORTBbits.RB1


//=============================================================================
//   Function Prototypes
//=============================================================================
void Delay_1msX (unsigned int miliseconds);
void Delay_100msX (unsigned int msec);

int uart_init(){
   // SPBRGH = 0;   
   SPBRG = DIVIDER;                  //set baud rate to 9600 for 20Mhz
   TXSTAbits.BRGH = HIGH_SPEED;      //baud rate high speed option
   
   TXSTAbits.SYNC = 0;     //Asynchronous mode
   RCSTAbits.SPEN = 1;     //Serial port enable
   RCSTAbits.CREN = 1;     //enable reception.
   TXSTAbits.TX9=0;        //8-bit transmission
   RCSTAbits.RX9=0;        //8-bit reception
   
   TXSTAbits.TXEN=0;                  //reset transmitter
   TXSTAbits.TXEN=1;                  //enable the transmitter
   TRISC = 0b10000000;   // RC7 = RX = input, RC6 = TX = output
   return 1;
}

void clear_usart_error(void)
{
   if (RCSTAbits.OERR)
   {                                                   
      TXSTAbits.TXEN=0;                                       
      TXSTAbits.TXEN=1;                                       
      RCSTAbits.CREN=0;                                       
      RCSTAbits.CREN=1;                                       
   }

   if (RCSTAbits.FERR)
   {                                                                               
      TXSTAbits.TXEN=0;                                       
      TXSTAbits.TXEN=1;
   }
}

void uart_send(char data)
{
   while(!PIR1bits.TXIF);
   TXREG = data;
}

char uart_rec(void)
{
   while(!PIR1bits.RCIF)
   {
      clear_usart_error();
   }
   return RCREG;
}

void uart_string(unsigned char *str_ptr)
{
   while(!PIR1bits.TXIF);
   while (*str_ptr)
   {
      uart_send(*str_ptr);
      str_ptr++;
   }
   return;
}


//=============================================================================
//   Global Variables
//=============================================================================
unsigned int i, t;
unsigned char data_tx, data_rx;


//=============================================================================
//   Main Program
//=============================================================================
void main ()
{
   //set I/O input output
   TRISB = 0b00000011;               //Configure PORTB I/O direction
   TRISC = 0b10000000;               //Configure PORTC I/O direction
   TRISD = 0b00000000;               //Configure PORTD I/O direction
   PORTB = 0;
   PORTC = 0;
   PORTD = 0;

   //-------------------------------------------------------------------------
   // Configure UART
     //-------------------------------------------------------------------------
   /*
   OpenUSART (USART_TX_INT_OFF &             //Transmit interrupt off
      USART_RX_INT_OFF &                //Receive interrupt off
      USART_ASYNCH_MODE &                //Asynchronous mode - UART
      USART_EIGHT_BIT &                //8-bit transmit/receive
      USART_CONT_RX &                //Continuous reception
      USART_BRGH_HIGH,               //High baudrate
      129);                     //9600 baudrate at 20MHz frequency
   */
   uart_init();
   
   while(1)
   {
      //-------------------------------------------------------------------------
      // UART Transmit
      //-------------------------------------------------------------------------
      data_tx='O';                     //Assign data
      uart_send(data_tx);                  //Send data through UART

      data_tx='K';                     //Assign data
      uart_send(data_tx);                  //Send data through UART

   }   
}//End of main



//=============================================================================
//   Subroutines
//=============================================================================

/********************************************************************
*       Function Name:  Delay_1msX                                  *
*       Return Value:   void                                        *
*       Parameters:     miliseconds: amount of delay            *
*       Description:    This routine generates various delays       *
*                  needed by xlcd functions.               *
*                  For delay of 1ms (18F4550 running at 48MHz)   *
*                  Cycles = (TimeDelay * Fosc) / 4            *
*                  Cycles = (1ms * 48MHz) / 4               *
*                  Cycles = 12,000                        *
*                  Since call of function also takes some       *
*                  instruction cycles, the exact value to get   *
*                  1ms delay is less than 12,000.            *
********************************************************************/
void Delay_1msX (unsigned int miliseconds)
{
   t=0;
   while(t<miliseconds)
   {
      Delay1KTCYx(11);
      Delay10TCYx(96);
      Nop();
      Nop();
      Nop();
      Nop();
      Nop();
      t++;
   }
}//End of Delay_1msX


/********************************************************************
*       Function Name:  Delay_100msX                                  *
*       Return Value:   void                                        *
*       Parameters:     miliseconds: amount of delay            *
*       Description:    This routine generates various delays       *
*                  needed by xlcd functions.               *
*                  For delay of 100ms                     *
*                  (18F4550 running at 48MHz)               *
*                  Cycles = (TimeDelay * Fosc) / 4            *
*                  Cycles = (100ms * 48MHz) / 4            *
*                  Cycles = 1,200,000                     *
*                  Since call of function also takes some       *
*                  instruction cycles, the exact value to get   *
*                  1ms delay is less than 1,200,000.         *
********************************************************************/
void Delay_100msX (unsigned int msec)
{
   t=0;
   while(t<msec)
   {
      Delay10KTCYx(119);
      Delay1KTCYx(9);
      Delay10TCYx(96);
      t++;
   }
}//End of Delay_100msX

Then I try to receive the characters from the PC side using a RS232 converter and eventually I receive garbage characters, can anyone help?

In this program, it receive 0xAD for both "O" and "K"...


solved: it should be #pragma config FOSC = HS instead of #pragma config FOSC = HSPLL_HS.
can anyone tell me the reasons?



Look at the datasheet. HS and HSPLL_HS, both are going through a different route. HSPLL_HS, goes through the PLL module, while HS goes directly to CPUDIV to scale the frequency.
zhenning
Enthusiast
 
Posts: 351
Joined: Thu Dec 30, 2010 12:32 am


Return to PIC Microcontroller

Who is online

Users browsing this forum: No registered users and 4 guests