Help with RF module link with high & low priority in pic18F

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

Help with RF module link with high & low priority in pic18F

Postby Enyuin » Mon Jul 29, 2013 11:15 am

Hi,
I am a newbie in programming pic. Now, I am trying to do a project which can use RF module to control high and low interrupt, but it doesn't work on low prority which using RB interrupt. Here is my code
CODE: SELECT_ALL_CODE
/ Program for Seven segment multiplexing using PIC18F4550 Microcontroller

#include <p18f4550.h>

#define  _XTAL_FREQ   12000000

#pragma config PLLDIV = 5
#pragma config CPUDIV = OSC1_PLL2
#pragma config USBDIV = 2
#pragma config FOSC = HS
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config PWRT = OFF
#pragma config BOR = OFF
#pragma config BORV = 3
#pragma config VREGEN = OFF
#pragma config WDT = OFF
#pragma config WDTPS = 32768
#pragma config CCP2MX = ON
#pragma config PBADEN = OFF
#pragma config LPT1OSC = OFF
#pragma config MCLRE = ON
#pragma config STVREN = ON
#pragma config LVP = OFF
#pragma config ICPRT = OFF
#pragma config XINST = OFF
#pragma config DEBUG = OFF
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF
#pragma config CPB = OFF
#pragma config CPD = OFF
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF
#pragma config WRTC = OFF
#pragma config WRTB = OFF
#pragma config WRTD = OFF
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF
#pragma config EBTRB = OFF

//============================================================================
//   define
//============================================================================
//#define display         PORTD
#define HEADER         0xaa

unsigned char num,no,portB_val;
//=============================================================================
//   function prototype
//=============================================================================
void high_ISR(void);
void yourHighPriorityInterruptCode(void);
void low_ISR(void);
void yourLowPriorityInterruptCode(void);
void Interrupt_Init(void);
void PortBLoc (void);
unsigned char uart_rec(void);
unsigned char read_packet(void);
void Delay_ms ( int delay ); //delay function for 1 ms
void check();

/////////////////////////////////////////////////////////////////////////////////////////////////
/*Configure interrupt using asm*/
#pragma code HIGH_INTERRUPT_VECTOR = 0x000008
void high_ISR(void)
{
   _asm
   goto yourHighPriorityInterruptCode
   _endasm
}
#pragma code
///////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////
/*Configure interrupt using asm*/
#pragma code LOW_INTERRUPT_VECTOR = 0x000018
void low_ISR(void)
{
   _asm
   goto yourLowPriorityInterruptCode
   _endasm
}
#pragma code
///////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////
/**/
#pragma interrupt yourHighPriorityInterruptCode
void yourHighPriorityInterruptCode(void)
{
   if (PIR1bits.RCIF == 1)
   {
      
      RCSTAbits.CREN=1;            //enable continuos receive
      if(RCSTAbits.OERR==0)
      {
         no=read_packet();         //receive data if overrun error free
         
         PortBLoc();
      }
      else
      {
         RCSTAbits.CREN=0;               //if overrun error, disable continuos receive
         PORTAbits.RA1 = 1;
         LATAbits.LATA1 = 1;
      }
   }
}

#pragma code
////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma interrupt yourLowPriorityInterruptCode
void yourLowPriorityInterruptCode(void)
{
   if (INTCONbits.RBIF == 1)
   {
      portB_val = PORTB;      //Read PORTD from PORTB
      PORTD = portB_val;
      Delay_ms(5000);
      INTCONbits.RBIF = 0; //Clear the PORTB RBIF flag
   }

}
#pragma code
/////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////
/*function on initiate intterrupt*/
void Interrupt_Init(void)
{
   //Set up intterrupt
   RCON    = 0b10000000;
   INTCONbits.GIE = 1;               //Enable all high interrupt
   INTCONbits.PEIE = 1;            //enable all low interrupt
   INTCONbits.RBIE = 1;            //enable rb interrupt
   INTCON2bits.RBIP = 0;            //port b interrupt in low priority
   INTCON2bits.RBPU = 1;            //enable portb pulls up
   INTCONbits.RBIF = 0;             //Make sure that the PORTB interrupt is not already set
   IPR1bits.RCIP = 1;               //set EUSART Receive Interrupt Priority bit to high priority
   PIE1bits.RCIE = 1;               //enable EUSART Receive Interrupt Enable bit   
   

}
/////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////
/*PORT B Bits Changes LOCATION*/
void PortBLoc(void)
{
   if (no == 0)
   {
      PORTBbits.RB4 = 1;
      PORTBbits.RB5 = 0;
      PORTBbits.RB6 = 0;
      PORTBbits.RB7 = 0;
   }
   else if (no == 1)
   {
      PORTBbits.RB4 = 0;
      PORTBbits.RB5 = 1;
      PORTBbits.RB6 = 0;
      PORTBbits.RB7 = 0;
   }
   else if( no == 2)
   {
      PORTBbits.RB4 = 0;
      PORTBbits.RB5 = 0;
      PORTBbits.RB6 = 1;
      PORTBbits.RB7 = 0;
   }
   else if (no == 3)
   {
      PORTBbits.RB4 = 0;
      PORTBbits.RB5 = 0;
      PORTBbits.RB6 = 0;
      PORTBbits.RB7 = 1;
   }
   else if (no == 4)
   {
      PORTBbits.RB4 = 1;
      PORTBbits.RB5 = 0;
      PORTBbits.RB6 = 1;
      PORTBbits.RB7 = 0;
   }
   else if (no == 5)
   {
      PORTBbits.RB4 = 1;
      PORTBbits.RB5 = 0;
      PORTBbits.RB6 = 0;
      PORTBbits.RB7 = 1;
   }
   else if (no == 6)
   {
      PORTBbits.RB4 = 1;
      PORTBbits.RB5 = 1;
      PORTBbits.RB6 = 1;
      PORTBbits.RB7 = 0;
   }
   else if (no == 7)
   {
      PORTBbits.RB4 = 1;
      PORTBbits.RB5 = 1;
      PORTBbits.RB6 = 0;
      PORTBbits.RB7 = 1;
   }
   else if (no == 8)
   {
      PORTBbits.RB4 = 1;
      PORTBbits.RB5 = 0;
      PORTBbits.RB6 = 1;
      PORTBbits.RB7 = 1;   
   }
   else if (no == 9)
   {
      PORTBbits.RB4 = 1;
      PORTBbits.RB5 = 1;
      PORTBbits.RB6 = 1;
      PORTBbits.RB7 = 1;
   }
}

void Delay_ms ( int delay )
{
   int ms, i;
 
   for ( ms = 0; ms < delay; ms ++ )
   for ( i = 0; i < 235; i ++ );
}

//============================================================================
//   main function
//============================================================================
void main(void)
{
   //assign variable


   //set I/O input output
   TRISB = 0;         //configure PORTB <4:7> as input
   PORTB = 0;
   TRISA = 0;               //configure PORTA as output
   TRISD = 0;               //configure PORTD as output
   PORTD = 0;
      
   //setup USART
   SPBRG = 153;            //set boud rate to 1200bps for 12Mhz crystal
   TXSTAbits.BRGH = 0;               //baud rate low speed option
   RCSTAbits.SPEN = 1;               //enable serial port
   RCSTAbits.RX9 = 0;               //8-bit reception
   RCSTAbits.CREN = 1;               //enable continuous reception
   
   Interrupt_Init();

   while(1)               //infinity loop //main loop
   {
      PORTA = 1;   
      LATAbits.LATA1 = 1;
   }
}

//==================================================================================
//   functions
//===================================================================================
unsigned char uart_rec(void)   //receive uart value
{
   unsigned char rec_data;
   while(PIR1bits.RCIF==0);            //wait for data
   rec_data = RCREG;
   return rec_data;         //return the received data
}



unsigned char read_packet(void)
{
   // Buffer for received byte.
   unsigned char received_byte;
   
   // Counter to indicate the current position of the received data packet.
   static unsigned char counter = 0;
   
   // Buffers for the data and checksum.
   unsigned char data;
   unsigned char checksum;
   
   
   // We loop until the checksum is correct.
   do {
      // We will ignore the sync data and assume the header byte is the start of packet.
      // Keep reading until the header byte is received.
      while (uart_rec() != HEADER);
      
      // The following byte shoulde be the data byte.
      data =    uart_rec();
      
      // Then the last byte is the checksum.
      checksum =    uart_rec();
   } while (checksum != (unsigned char)(HEADER + data));
   // If the checksum is correct, return the data.
   return data;
}

I really dun know wad to do, the port D just won't be light up.
Could anyone help me to solve this problem?
Enyuin
Freshie
 
Posts: 7
Joined: Thu Jul 18, 2013 1:03 pm

Re: Help with RF module link with high & low priority in pic

Postby yonghui » Mon Jul 29, 2013 12:27 pm

hi, i think its better for u to remove the RF and test with normal push button signal 1st.
thanks&regards,
yh
yonghui
Moderator
 
Posts: 732
Joined: Mon Sep 28, 2009 3:27 pm

Re: Help with RF module link with high & low priority in pic

Postby Enyuin » Mon Jul 29, 2013 4:18 pm

Hi,
Youg Hui, I would like to say thank you for looking at my post.
Sorry for this late reply, cause i encountered another problem of my program. But, this time, i managed to solve it le.
Talk back to the intial problem, i have removed the rf and add a pull up circuit in my hardware. The RB interrupt does function but the problem is when i turn on the power supply, the interrupt functioned firstly without function my main loop, and for the second time i press the switch button, the interrupt doesn't function anymore. Why do this happen?
Enyuin
Freshie
 
Posts: 7
Joined: Thu Jul 18, 2013 1:03 pm

Re: Help with RF module link with high & low priority in pic

Postby yonghui » Tue Jul 30, 2013 12:21 pm

hi,

it will be better if u initialize all the required things in main loop 1st then only u enable the global and peripheral interrupt at the last line for initialization.
i am not sure u are using port B interrupt on change or RB0/INT0. please make sure that u initialize the correct one and clear the correct interrupt flag in the interrupt sub routine.

for Uart part. please always check in the main loop if the overrun occurred, if occurred reset the receiver by clearing CREN and set it again. else it will cause the uart to hang.
probably u can try add LED blinking in main loop or interrupt subroutine to see where the program actually hang
thanks&regards,
yh
yonghui
Moderator
 
Posts: 732
Joined: Mon Sep 28, 2009 3:27 pm

Re: Help with RF module link with high & low priority in pic

Postby Enyuin » Wed Jul 31, 2013 12:38 pm

Hi,
Yong Hui, I have solved the problem le, btw i came out with another problem. The timer0 doesn't work properly in my program and the delay function cannot be carry out properly, why would this happen?
CODE: SELECT_ALL_CODE
void T0_Start()   
{
   TMR0H=0xD2;                     // Values calculated for 1 second delay with 12MHz crystal
   TMR0L=0x38;
   INTCONbits.TMR0IF = 1;         //enable timer 0 overflow interrupt
   T0CONbits.TMR0ON=1;                 // Timer0 On
   while(INTCONbits.TMR0IF==0);        // Wait until TMR0IF gets flagged
   T0CONbits.TMR0ON=0;                 // Timer0 Off
   INTCONbits.TMR0IF=0;                // Clear Timer0 interrupt flag
}
CODE: SELECT_ALL_CODE
void Delay_ms ( int delay )
{
   int ms, i;
 
   for ( ms = 0; ms < delay; ms ++ )
   for ( i = 0; i < 450; i ++ );
}
CODE: SELECT_ALL_CODE
while(1)               //infinity loop //main loop
   {
      if ( num != 0 && counter == 0)
      {
         T0_Start();
         Delay_ms(10);
         num = 0;
      }
      else if (counter != 0 && num == 0)
      {
         int a,i;
         counter = 0;
         a = 0x01;
         for ( i = 0; i < 8; i++)
         {
            if ( i < 8)
            {
               LATD = a << i;
               Delay_ms(10);
            }
            else
            {
               break;
            }
         }
      }
      else if (counter == 0 && num ==0)
      {
         LATD = 0x55;
      }

The delay function was just work fine under the calculation which i have shown in my code, and it doesn't work properly if i delay longer which means that i increase the number of "for loop". And the timer was just get over without waiting for 1 sec.
I have put this code in other program, it just works fine, but it doesn't work in here.
Enyuin
Freshie
 
Posts: 7
Joined: Thu Jul 18, 2013 1:03 pm

Re: Help with RF module link with high & low priority in pic

Postby yonghui » Thu Aug 01, 2013 1:22 pm

for this portion of code:
CODE: SELECT_ALL_CODE
TMR0H=0xD2;                     // Values calculated for 1 second delay with 12MHz crystal
   TMR0L=0x38;
   INTCONbits.TMR0IF = 1;         //enable timer 0 overflow interrupt
   T0CONbits.TMR0ON=1;                 // Timer0 On
   while(INTCONbits.TMR0IF==0);        // Wait until TMR0IF gets flagged
   T0CONbits.TMR0ON=0;                 // Timer0 Off
   INTCONbits.TMR0IF=0;   


INTCONbits.TMR0IF = 1 this line, we dont need to set TMR0IF to 1. the flag itself will be set when timer overflowed.
if u wan to generate interrupt, u will needt o enable by setting the interrupt enable register, which probably is TMR0IE.
but in this case i think u dont use interrupt.


in the delay function, u had never used timer.
CODE: SELECT_ALL_CODE
void Delay_ms ( int delay )
{
   int ms, i;

   for ( ms = 0; ms < delay; ms ++ )
   for ( i = 0; i < 450; i ++ );
}


to use timer0 as counter, u will need to initialize the timer register properly. in PIC the clock frequency is divided by 4 of the oscillator. for example if 20Mhz the clock frequency is 5Mhz.
the frequency to the timer depends on the prescaler and postscaler also .


TMR0ON=1; to on timer
T08BIT =0; timer in 16bits mode
T0CS=0; to use internal instruction cycle as clock to timer
PSA=0; to assign prescaler
T0PS2=?
T0PS1=?
T0PS0=?

to bypass prescaler
PSA=1;


for example in your case FOSC/4=12Mhz/4 =3Mhz
T08BIT ; //select timer 16bits
PSA=1; //no prescaler

to delay for 1ms
timer ticks needed =3000-1=2999;
timer register value=65535-2999=62536;
timer flagwill be set only when timer0 register roll over to 0. so with this, total ticks of timer 0 will be 3000 ticks which is equivalent to 1ms. (3000x everyticks is 3Mzh^-1 seconds);

the the function to delay 1ms
void T0delay1ms(void)
{
TMR0H=0xF4;
TMR0L=0x48;
TMR0ON=1;
while(TMR0IF==0);
TMR0IF=0;
TMR0ON=0;
}

this function call will cause 1ms delay, ignoring the time taken to call the function and return from function , and time needed to load timer registers.
thanks&regards,
yh
yonghui
Moderator
 
Posts: 732
Joined: Mon Sep 28, 2009 3:27 pm

Re: Help with RF module link with high & low priority in pic

Postby Enyuin » Thu Aug 01, 2013 2:09 pm

Hi,
Yong Hui, actually i have assigned the interrupt code properly le.I put this code "INTCONbits.TMR0IF = 1" is due to i couldn't get the delay properly, so that's why i added in. For my prescaler is 1:256, is just dun delay for 1 ms and btw it hangs there.
Thank you for typing so long to explain to me.
Enyuin
Freshie
 
Posts: 7
Joined: Thu Jul 18, 2013 1:03 pm

Re: Help with RF module link with high & low priority in pic

Postby Enyuin » Thu Aug 01, 2013 2:47 pm

Actually, the code works fine if the delay below few milliseconds, but it goes wrong when the delay becomes 1s.
CODE: SELECT_ALL_CODE
for (j = 0; j< 1000; j++)
               {   
                  T0_Start();
               }

It works fine under go debugging, but actually the code went wrong when doing the real experiment, it just gets hanged.
I think the problem is after come out from isr routine. Since the interrupt does work in just a few milli or mircoseconds, when it comes out, we couldn't put a timer with long time delay to control my other function, right?
That's why i use delay function to solve the problem.
Enyuin
Freshie
 
Posts: 7
Joined: Thu Jul 18, 2013 1:03 pm

Re: Help with RF module link with high & low priority in pic

Postby robosang » Sun Aug 04, 2013 11:25 am

Confused! I agreed with yonghui, the previous code does not use the timer 0 function at all in the delay_ms, so what is the use for timer 0. Also, the function of timer 0 that you show is not ISR, will the interrupt jump to that function? ISR does not need to be called by other function, that is the whole point of doing interrupt.

Or you are using timer 0 to count delay only? Make it clear.
robosang
Expert
 
Posts: 1239
Joined: Wed Jun 10, 2009 5:37 pm


Return to PIC Microcontroller

Who is online

Users browsing this forum: No registered users and 14 guests