Re: Displaying RPM on LCD Help pls mikroc code

Discussion in 'Embedded Systems and Microcontrollers' started by vivek1925, Nov 26, 2011.

  1. vivek1925

    Thread Starter New Member

    May 12, 2010
    11
    0
    Hi People,

    I am trying to calculate the RPM of a bicycle and I have written the code in mikroc for calculating the time it takes for falling and the rising edge of a reed switch which is connected to the rear wheel.

    Therefore 1 pulse = 1 revolution in this case, so I have attached the code below and for testing purpose I have created a simulation phase which will display the RPM on a LCD but the LCD does not display it for some reason!

    I used the CCP2CON register RC1 to capture the falling and the rising edge.

    All I see is '1' displayed on the LCD with the welcome text.

    This is the code:

    //#include <stdio.h>
    char *text = "Cadence";
    char buffer[20];
    //char *text1 = "RPM";
    float Rpm;
    unsigned int Rot_time = 0;
    unsigned short Pulse_HSL; // holding falling edge time for start of timing sequence
    unsigned int Pulse_HSH;
    unsigned short Pulse_EL; // rising edge for end time sequence
    unsigned int Pulse_EH;
    //unsigned float Rot_PH = 0;
    //unsigned float Rot_PL = 0;
    void main()
    {
    Soft_Uart_Init(PORTC,7,6,57600,0);
    delay_ms(500);
    PORTB = 0;
    TRISB = 0;
    TRISD = 0; //Set all PORTD for output
    PORTD = 0;
    TRISC = 0x02; //RC1 as input for CCP2
    Lcd_Init(&PORTB);
    Lcd_Cmd(Lcd_clear);
    Lcd_Out(1 ,1 ,text);

    INTCON = 0; //Disable all Interrupts for initialization of other registers
    T3CON = 0; //0000 0000 was $C0 Sets Timer1 as source clock for CCP1 and CCP2 leaves timer3 off
    CCP2CON = 0x04; // set for every faling edge, 05 every rising edge capture
    //CCP2CON = 0x06; //set for 4th rising edge, $07 Initially Set CCP2 for 16th Rising Edge Capture
    T1CON = 0x01; //set for 8 bit time read, prescaler of 1 and turn timer 1 on
    //T1CON = 0x81; // set for 16bit read, prescaler 1 and timer1on
    TMR1L = 0x00; //zero timer registers
    TMR1H = 0x00;
    INTCON = 0xC0; //Enable Interrupts

    while(1)
    {
    //Lcd_cmd(Lcd_clear);
    //delay_ms(1000);
    if(PIR2.CCP2IF == 0 && CCP2CON == 0x04) // if flag is set and pulse is trigerred
    Rot_time = (Pulse_EH<<8|Pulse_EL) - (Pulse_HSH<<8|Pulse_HSL);
    Rpm = 240000000/Rot_time;//combining both hi and low byte of rotation period
    wordtostr(Rpm,buffer);
    //sprintf(buffer, "%12s", Rpm); // this is taking F* lot of ROM locations
    Lcd_Out(2,1,buffer); // Print text on LCD
    Soft_Uart_write(buffer);

    }
    }

    void interrupt()
    {
    //INTCON.GIE = 0; // clearing GIE to prevent any other interrupts while handling this one

    if(PIR2.CCP2IF == 1)
    {
    switch(CCP2CON)
    {
    case 0x04: // start time of the sequence i.e. falling edge and gets start time
    Pulse_HSL = CCPR2L; // capture pulse high start time
    Pulse_HSH = CCPR2H; // get captured time high byte
    CCP2CON = 0x05;
    PIR2.CCP2IF = 0; // reset the flag
    break;

    case 0x05: // end time sequence so timing sequence complete, calculate time intervals
    Pulse_EL = CCPR2L; // get time of the rising edge
    Pulse_EH = CCPR2H;
    //Rot_PL = Pulse_EL - Pulse_HSL; // rotation time = Pulse time HI + pulse time LOW
    //if(STATUS == 0){ Pulse_EH = Pulse_EH - 1; }
    //Rot_PH = Pulse_EH - Pulse_HSH;
    CCP2CON = 0x04; // set start next timing sequence for falling edge.
    PIR2.CCP2IF = 0;
    break;

    default: rpm = 0;
    } // switch
    } // if

    } // interrupt

    The text i.e in red is the code where I am printing the RPM on a LCD.
    I have also attached the schematic where you can test the code and see the LCD output for your reference.

    Please help me resolve this issue, I am using Mikroc v8.2 and PIC18f452 with 16mhz. I used Proteus professional simulation software for generating the schematic.

    If you have any other question please feel free to reply me!

    Cheers
    vivek
     
  2. ke5nnt

    Active Member

    Mar 1, 2009
    384
    15
    Please place the [ code] [/ code] tags around your code. No spaces.
     
  3. vivek1925

    Thread Starter New Member

    May 12, 2010
    11
    0
    Hi,

    Sorry for the previous post, here is what you asked for!

    Code ( (Unknown Language)):
    1. //#include <stdio.h>
    2. char *text = "Cadence";
    3. char buffer[20];
    4. //char *text1 = "RPM";
    5. float Rpm;
    6. unsigned int Rot_time = 0;
    7. unsigned short Pulse_HSL;   // holding falling edge time for start of timing sequence
    8. unsigned int Pulse_HSH;
    9. unsigned short Pulse_EL;   // rising edge for end time sequence
    10. unsigned int Pulse_EH;
    11. //unsigned float Rot_PH = 0;
    12. //unsigned float Rot_PL = 0;
    13. void main()
    14. {
    15.       Soft_Uart_Init(PORTC,7,6,57600,0);
    16.       delay_ms(500);
    17.       PORTB = 0;
    18.       TRISB = 0;
    19.       TRISD = 0;  //Set all PORTD for output
    20.       PORTD = 0;
    21.       TRISC = 0x02;  //RC1 as input for CCP2
    22.       Lcd_Init(&PORTB);
    23.       Lcd_Cmd(Lcd_clear);
    24.       Lcd_Out(1 ,1 ,text);
    25.  
    26.       INTCON  = 0;  //Disable all Interrupts for initialization of other registers
    27.       T3CON   = 0;  //0000 0000  was $C0 Sets Timer1 as source clock for CCP1 and CCP2 leaves timer3 off
    28.       CCP2CON = 0x04; // set for every faling edge, 05 every rising edge capture
    29.       //CCP2CON = 0x06;  //set for 4th rising edge, $07 Initially Set CCP2 for 16th Rising Edge Capture
    30.       T1CON   = 0x01;  //set for 8 bit time read, prescaler of 1 and turn timer 1 on
    31.       //T1CON = 0x81; // set for 16bit read, prescaler 1 and timer1on
    32.       TMR1L   = 0x00; //zero timer registers
    33.       TMR1H   = 0x00;
    34.       INTCON  = 0xC0;  //Enable Interrupts
    35.  
    36. [COLOR=Red]while(1)
    37. {
    38.       //Lcd_cmd(Lcd_clear);
    39.       //delay_ms(1000);
    40.       if(PIR2.CCP2IF == 0 && CCP2CON == 0x04) // if flag is set and pulse is trigerred
    41.       Rot_time = (Pulse_EH<<8|Pulse_EL) - (Pulse_HSH<<8|Pulse_HSL);
    42.       Rpm = 240000000/Rot_time;//combining both hi and low byte of rotation period
    43.       wordtostr(Rpm,buffer);
    44.       //sprintf(buffer, "%12s", Rpm);     // this is taking F* lot of ROM locations
    45.       Lcd_Out(2,1,buffer);     // Print text on LCD
    46.       Soft_Uart_write(buffer);
    47.  
    48. }
    49. }[/COLOR]
    50. void interrupt()
    51. {
    52.       //INTCON.GIE = 0; // clearing GIE to prevent any other interrupts while handling this one
    53.  
    54.       if(PIR2.CCP2IF == 1)
    55.       {
    56.         switch(CCP2CON)
    57.         {
    58.           case 0x04: // start time of the sequence i.e. falling edge and gets start time
    59.           Pulse_HSL = CCPR2L; // capture pulse high start time
    60.           Pulse_HSH = CCPR2H; // get captured time high byte
    61.           CCP2CON = 0x05;
    62.           PIR2.CCP2IF = 0; // reset the flag
    63.           break;
    64.  
    65.           case 0x05: // end time sequence so timing sequence complete, calculate time intervals
    66.           Pulse_EL = CCPR2L; // get time of the rising edge
    67.           Pulse_EH = CCPR2H;
    68.           //Rot_PL = Pulse_EL - Pulse_HSL; // rotation time = Pulse time HI + pulse time LOW
    69.           //if(STATUS == 0){ Pulse_EH = Pulse_EH - 1; }
    70.           //Rot_PH = Pulse_EH - Pulse_HSH;
    71.           CCP2CON = 0x04; // set start next timing sequence for falling edge.
    72.           PIR2.CCP2IF = 0;
    73.           break;
    74.  
    75.           default:  rpm = 0;
    76.          } // switch
    77.        }  // if
    78.        
    79. }   // interrupt
    Cheers
    vivek
     
  4. MrChips

    Moderator

    Oct 2, 2009
    12,415
    3,354
    Can you say what the LCD is showing?
     
  5. vivek1925

    Thread Starter New Member

    May 12, 2010
    11
    0
    Hi,

    LCD is only showing -1 all the time
     
  6. Motardo

    New Member

    Sep 21, 2011
    20
    2
    In your main(), while(1) you write
    if(PIR2.CCP2IF == 0 && CCP2CON == 0x04) // if flag is set and pulse is trigerred
    Do you mean if(PIR2.CCP2IF == 1 ...?
    Also your Pulse_HSL, etc variables should be defined as volatile or the compiler might skip generating code to actually read their values.
     
  7. Yako

    New Member

    Nov 24, 2011
    245
    2
    I like MikroC, it is a very underrated compiler in my opinion.

    It can be tricky sometimes; things need to be in the right order.

    PIC18f452 is bit of an overkill for your project.
     
    Last edited: Nov 26, 2011
  8. absf

    Senior Member

    Dec 29, 2010
    1,490
    371
    I found a couple of mistakes in your schematic. You put your xtal on pin 7 and 14 which should be 13 & 14. Though this doesn't hurt as you already defined the osc freq inside the PIC. But on the real HW it would not work.

    You also connected the counter/timer to the input CCP2A with a switch pulled high with 100K. I know you want to send pulses to the CCP using the switch but how fast can you press the switch? What you need to connect to this point is a function generator. Set it to square wave of about 10 Hz should do.

    Have you corrected your software and try again?

    Allen
     
Loading...