[SOLVED] PIC18F4520 UART interfacing using C18

Status
Not open for further replies.

ahsoopk

Member level 5
Joined
Mar 12, 2010
Messages
81
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Visit site
Activity points
2,103
Hi,

Can some please check my code and let me know what is that i am doing wrong. When I send character to the PIC using docklight scripting (an RS232 GUI like hyperterminal) PIC echos the first time but then after that it doesn't echo anything.

It seems like my program is getting stuck somewhere but where I can't figure it out, I don't have in circuit debugger.

code is given below, thanks in advance.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#include "p18f4520.h"
#include "usart.h"
 
/*------------------------------------------------------------
            SETTING MICROCONTROLLER CONFIGURATION BITS
------------------------------------------------------------*/
#pragma config OSC = HS
#pragma config WDT = OFF
#pragma config LVP =OFF
 
/*------------------------------------------------------------
                    DEFINE Rx and Tx PORTS
-------------------------------------------------------------*/
#define Tx_port                     TRISCbits.TRISC6
#define Rx_port                     TRISCbits.TRISC7
 
/*------------------------------------------------------------
         DEFINE USART STATUS AND CONTROL REGISTER BITS
-------------------------------------------------------------*/
#define Serial_port_enable                  RCSTAbits.SPEN //serial port enable or disable bit in RCSTA register
#define Transmission_mode                   TXSTAbits.SYNC //transmission mode selection bit (synchronous or Asynchronous) in TXSTA register
#define Tx_enable                           TXSTAbits.TXEN //Tx enable or disable bit in TXSTA register
#define Continious_Rx_enable                RCSTAbits.CREN //continous recieption enable or disable bit in RCSTA register
#define Baud_rate_generator_speed           TXSTAbits.BRGH //baud rate generator speed (high or low) selection bit in TXSTA register
#define Baud_rate_generator_bits            BAUDCONbits.BRG16 //buad rate generator no. or bits selection bit (8 or 16 bits)in BAUDCON register
#define Baud_rate_generator_factor_lowByte  SPBRG //register to hold the serial port baud rate generator calculated baud factor LOW BYTE
#define Baud_rate_generator_factor_highByte SPBRGH //register to hold the serial port baud rate generator calculated baud factor HIGH BYTE 
 
/*---------------------------------------------------------------
            DEFINE USART RELATED INTERRUPT REGISTER BITS
----------------------------------------------------------------*/
#define Global_interrupt_enable     INTCONbits.GIEH //to enable or disable all interrupts (onchip and external)
#define Peripheral_interrupt_enable INTCONbits.GIEL //to enable or disable onchip peripheral interrupts
#define Tx_interrupt                PIE1bits.TXIE //to anable or disable transmitter interrupts
#define Rx_interrupt                PIE1bits.RCIE //to enable or disable reciever interrupts
#define Interrupt_priority_enable   RCONbits.IPEN //to enable or disable the priority level function on all interrupts
#define Tx_interrupt_priority       IPR1bits.TXIP //to change the priority level of the Tx interrupt (1=high,0=low)
#define Rx_interrupt_priority       IPR1bits.RCIP //to change the priority level of the Rx interrupt (1=high,0=low)
 
/*-----------------------------------------------------------------
                    USART RELATED FUNCTION DECLERATIONS
------------------------------------------------------------------*/
void Initialize_USART(void);
void Tx_char(unsigned char);
void InterruptHandlerLow();
 
/*-----------------------------------------------------------------
                        GLOBAL VARIABLE DECLERATIONS
------------------------------------------------------------------*/
unsigned char cUART_char;
unsigned char cUART_data_flg;
 
/*-------------------------------------------------------------------
                INTERRUPT HANDER CALL
-------------------------------------------------------------------*/
 
#pragma code InterruptVectorLow = 0x18
void InterruptVectorLow()
{
    _asm
    goto InterruptHandlerLow //jump to interrupt routine
    _endasm
 
}
#pragma code //End of pragma code
 
/*-------------------------------------------------------------------
                        INTERRUPT HANDLER ROUTINE
-------------------------------------------------------------------*/
 
void InterruptHandlerLow()
{
 
    if (PIR1bits.RCIF==1)//is interrupt occured by EUSART receive?, 
    //then RCREG is full we have new data (cleared when RCREG is read)
    { 
        if(RCSTA&0x06) //more efficient way than following commented method to check for reception error 
        //if(RCSTAbits.FERR==1 || RCSTAbits.OERR==1 )
        {
        RCSTAbits.CREN=0; //Overrun error (can be cleared by clearing bit CREN)
        cUART_char=getcUSART(); //clear Framing error 
        while(BusyUSART());
        RCSTAbits.CREN=1;
        cUART_data_flg = 1;
        PIR1bits.RCIF==0;
        }
        else
        {
        cUART_char = getcUSART(); // read new data into variable
        while(BusyUSART());
        cUART_data_flg = 1; // new data received. so enable flg
        PIR1bits.RCIF==0;
        }
    }
 
}
/*-------------------------------------------------------------------
                            MAIN FUNCTION
--------------------------------------------------------------------*/
 
void main(void)
{//start if main()
 
    //ADCON = 0; //all pins digital I/O
    Initialize_USART(); // init UART module
 
    while (1) // infinite loop which handles ncoming data as they arrive
    {
        if (cUART_data_flg==1)// if new data available, send it back through USART tx line (echo it)
        {
            Tx_char(cUART_char); 
            cUART_data_flg=0; // clear new data flag so one charactor will echoed once
        }
    }
 
}//end of main()
 
/*---------------------END OF MAIN FUNCTION-------------------------*/
/*--------------------------------------------------------------------
                    USART INITIALIZATION FUNCTION
---------------------------------------------------------------------*/
 
void Initialize_USART()
{
cUART_data_flg=0;
Tx_port = 0; //make C6 pin of port C as output pin for Tx
Rx_port =1; //make C7 pin of port C as input pin for Rx
 
    /*---------------------------------------------------------
            STATUS & CONTROL REGISTER BITS CONFIGURATION
    ----------------------------------------------------------*/
    Serial_port_enable =1; // Enable serial port
    Transmission_mode = 0; // Asynchronous transmission
    Tx_enable = 1; //Enable transmitter
    Continious_Rx_enable = 1; //Enable continous recieption on reciever
    Baud_rate_generator_speed = 1; //High speed
    Baud_rate_generator_bits = 0; //8bits
    Baud_rate_generator_factor_lowByte = 25; //Buad rate = 9600 for FOSC = 4MHz (See page 207 of PIC18F4520 datasheet)
    Baud_rate_generator_factor_highByte = 0;
 
    /*---------------------------------------------------------
            INTERRUPT REGISTER BITS CONFIGURATION
    ----------------------------------------------------------*/
 
    Global_interrupt_enable = 1; //enable all interrupts (onchip and external)
    Peripheral_interrupt_enable = 1; //enable onchip peripheral interrupts
    Tx_interrupt = 0; //disable Tx interrupt for start
    Rx_interrupt = 1; //enable Rx interrupt
    Interrupt_priority_enable = 1; //enable interrupt priorities
    Tx_interrupt_priority = 0; //low interrupt periority
    Rx_interrupt_priority = 0; //low interrupt periority
    
    /*----------------------------------------------------------*/
    
} //END OF INITIALIZATION FUNCTION
 
/*--------------------------END OF INITIALIZATION FUNCTION --------------*/
 
/*-----------------------------------------------------------------------
                            Tx CHARACTER FUNCTION
------------------------------------------------------------------------*/
void Tx_char(unsigned char c)
{
 
//putcUSART(c);
//TXSTAbits.TXEN=0;// disable transmission
//TXREG=c; // load txreg with data
putcUSART(c);
//TXSTAbits.TXEN=1; // enable transmission
//while(TXSTAbits.TRMT==1) // wait here till transmit complete
//{
//Nop();
//}
}

 
Last edited by a moderator:

Use this configuration :-

Code:
[syntax=c][/syntax]
#pragma config FOSC=[B]INTIO2[/B],PLLCFG=OFF,IESO=OFF //pin 6 and 7 as internal oscillaotr
#pragma config WDTEN=OFF,PWRTEN=ON,BOREN=OFF,PBADEN=OFF
#pragma config DEBUG=OFF,STVREN=ON,PRICLKEN=ON,FCMEN=OFF
#pragma config LVP=OFF,MCLRE = EXTMCLR,HFOFST =OFF,XINST=OFF

and in main () add these initializations also :- Or see on 32 page of datasheet(OSCCON register)

Code:
[syntax=c][/syntax]
 OSCCONbits.IRCF0 = 1;
 OSCCONbits.IRCF1 = 1;
 OSCCONbits.IRCF2 = 1;

        OSCCONbits.SCS1 = 1;
        OSCCONbits.SCS0 = 1;
        OSCCONbits.IDLEN = 1;  // IDLE mode on SLEEP instruction
 
Last edited:

hello,

Why are you using while (BusyUSART()); into the interrupt treatment, because concerne Transmit caracatere ?
and why do you also set cUART_data_flg = 1; when you get Frame error or Overload ? it could be reset cUART_data_flg = 0;

did you also try with High level interrupt level 0x08 ?


even at 4MHz for Fosc, this must be OK at 9600 bauds.
Maybe you can add 2 other leds to test if you get errors = hardware debugger

if (RCSTAbits.FERR==1 ) set led1;
if (RCSTAbits.OERR==1 ) set led2

reset led1 and led2 at initilalisation.




 
Last edited:

Thanks guys,

I missed something very important and so did you gentlemen, interrupt handler routine should be defined within #pragma clause and its not.

I defined it properly with in interrupt #pragma and the whole thing works fine.

However Paul can you explain bit more clearly why shouldn't I use while (BusyUSART()); I am bit struggling to understanding from your previous reply.

Best Regards,
Malik
 

hello,

.. why shouldn't I use while (BusyUSART());..

this function is used to check if Transmiter register is free, so ready to SEND a character
so not necessary inside the RECEIVE Interrupt...
except if you want an echo off each received char..like in the following example, i use the input RB1 to valide the echo or not



Code:
//-------- interrupts---------------

void Serial_ISR(void);


 //gestionnaire d'interruption
//------------------------------
// High priority interrupt vector
#pragma code InterruptVectorHigh = 0x08
void InterruptVectorHigh (void)
{
  _asm
    goto Serial_ISR //jump to interrupt routine
  _endasm
}

#pragma code

#pragma interrupt Serial_ISR
void Serial_ISR()
 {
  if(PIR1bits.RC1IF==1) // si une interruption arrive
  {
   if(RCSTA1bits.FERR==1 )
   {
     RCSTA1bits.SPEN = 0 ;
     Flags.Drapeaux.FrameErr=1;
     CptFE++;
     RCSTA1bits.SPEN= 1 ;
     }
     else
     Flags.Drapeaux.FrameErr=0;

   if (RCSTA1bits.OERR==1)    // voir parag 16.1.26 p273
   {
       RCSTA1bits.CREN = 0 ;
       Flags.Drapeaux.Over=1;
       RCSTA1bits.CREN = 1 ;
       CptFO++;
       }
      else
      Flags.Drapeaux.Over=0;

   c1 =Read1USART(); // le lire => RAZ  RCIF
  [B] while( Busy1USART()) ; // par sécurite
   if (PORTBbits.RB1==0) Write1USART(c1); // echo[/B]
   if(c1 != CR )
     {
      buffer[i1] = c1;
      i1++;
      DataReady = 0;
     }
     else
      {
      buffer[i1] = 0;         //  0 a la fin du string
      DataReady = 1;      // drapeau Data recue
      i1=0;
    }
 } //if PIR1
  //PIR1bits.RC1IF=0;  // not accessible by software
}
 

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…