Frequency counter using 7-segment

Discussion in 'Embedded Systems and Microcontrollers' started by jj_alukkas, Aug 11, 2011.

  1. jj_alukkas

    Thread Starter Well-Known Member

    Jan 8, 2009
    751
    5
    Im trying to build a frequency counter using a pic 16F628 and the Capture pin from the CCP module on port RB3 and 2 multiplexed 7 segment displays. Did most of the coding, but I dont have any idea what values I can expect from CCPR1H and CCPR1 registers, so donno what to do with them. I think it should be 0-255 After checking a couple of existing projects using capture pin, I made it up to add together and get divided by 100.. Still It doesnt show anything on my display. I need a 30-200Hz counter, so totally confused if my routine is not initialized properly or if I mixed something up. The displays are working fine and expect to show values on 2 digits as 03-20 for 30-200hz range. Where could I have gone wrong? Please Help. Coded in Hi Tech C, no errors.

    Code ( (Unknown Language)):
    1. #include <HTC.H>
    2. #define _XTAL_FREQ 4000000                    //Internal OSC Freq
    3.  
    4. #define SEGMENT_TRIS     TRISB                //Display Segments Connected Ports
    5. #define SEGMENT_PORT    PORTB
    6.  
    7. #define DIGIT_TRIS    TRISA                    //Display Digit select data ports
    8. #define DIGIT_PORT    PORTA
    9.  
    10. __CONFIG(INTIO & WDTDIS & PWRTDIS & BORDIS & LVPDIS );  //Config Bits
    11.  
    12. unsigned char digits[2]={0,0};                //Defining the Digit Array
    13. //unsigned char kontrol, control;
    14. float counter;
    15.  
    16. void Wait(unsigned char delay)                //Delay Loops
    17. {
    18.     for(;delay;delay--)
    19.         __delay_us(100);
    20. }
    21.  
    22. void SevenSegment(unsigned char num)        //Defining the segment pattern for each digit 0-9
    23. {
    24.    switch(num)
    25.    {
    26.       case 0:
    27.         SEGMENT_PORT= 0B01000000;            // Defined in the order xGFEDCBA segments
    28.          break;
    29.  
    30.       case 1:
    31.         SEGMENT_PORT= 0b11111001;
    32.          break;
    33.  
    34.       case 2:
    35.         SEGMENT_PORT= 0B00100100;
    36.          break;    
    37.  
    38.       case 3:
    39.         SEGMENT_PORT= 0B00110000;
    40.          break;
    41.  
    42.       case 4:
    43.         SEGMENT_PORT= 0B10011001;
    44.          break;
    45.  
    46.       case 5:
    47.         SEGMENT_PORT= 0B00010010;
    48.          break;
    49.  
    50.       case 6:
    51.         SEGMENT_PORT= 0B00000010;
    52.          break;
    53.  
    54.       case 7:
    55.         SEGMENT_PORT= 0B11111000;
    56.          break;
    57.  
    58.       case 8:
    59.         SEGMENT_PORT= 0B00000000;
    60.          break;
    61.  
    62.       case 9:
    63.         SEGMENT_PORT= 0B00010000;
    64.          break;
    65.    }
    66. }
    67.  
    68. void DisplayInit()
    69. {
    70.    
    71.     SEGMENT_TRIS=0b00001000;            //Config segment ports as outputs
    72.     DIGIT_TRIS=0b00100000;                //Config Digit Ports as Outputs
    73.  
    74.     DIGIT_PORT=0B00000011;                //Digit select port state
    75.    
    76.     //Setup Timer0 for the Digit Scanning Operation
    77.     PS0=1;                                //Prescaler is divide by 64
    78.     PS1=0;
    79.     PS2=1;
    80.  
    81.     PSA=0;                                //Timer Clock Source is from Prescaler
    82.  
    83.     T0CS=0;                                //Prescaler gets clock from Internal OSC
    84.    
    85.     T0IE=1;                                //Enable TIMER0 Interrupt
    86.     PEIE=1;                                //Enable Peripheral Interrupt
    87.     GIE=1;                                //Enable INTs globally
    88.  
    89.     TMR0=1;                                //Staring timer0    
    90. }    
    91.  
    92. void Print(unsigned short num)            // This function splits a number to Ones and Tens for display on each digit
    93. {
    94.    
    95.     unsigned char i=0;
    96.     unsigned char j;
    97.     if(num>99) return;
    98.     while(num)
    99.     {
    100.         digits[i]=num%10;                //Splitting Numbers and Storing in Arrays
    101.         i++;
    102.  
    103.         num=num/10;
    104.     }
    105.     for(j=i;j<2;j++) digits[j]=0;
    106. }    
    107.  
    108. void SevenSegISR()                        // Display Scanner which update the multiplexed Displays    
    109. {
    110.    
    111.     TMR0=150;
    112.     static unsigned char i;
    113.     if(i==1)
    114.         i=0;                            //Checking end of Display Scan
    115.     else
    116.         i++;                            //Incrementing to next digit for refresh
    117.    
    118.     DIGIT_PORT=((DIGIT_PORT & 0b00111111)|(1<<i)); //Display Output on the Digits
    119.     SevenSegment(digits[i]);            //Write the digit[i] in the ith display.
    120. }        
    121.  
    122. void interrupt ISR()                    //Interrupt Service Routine for Display
    123. {
    124.     if(T0IE && T0IF)                    //Check if TMR0 has Overflowed
    125.     {
    126.         SevenSegISR();                    //Call the SevenSegISR
    127.         T0IF=0;                            //Clear Flag for Timer0
    128.     }
    129.    
    130. }            
    131.  
    132. void main()
    133.  
    134. {
    135.     CMCON=0x07;
    136.     //unsigned int value;
    137.     float frequency;
    138.     TMR1CS = 0;                //Timer1 uses int clk as osc source
    139.     TMR1IF = 0;                //Reset Timer1 Flag Bit
    140.     TMR1H  = 0x00;  TMR1L = 0x00;    //Reset Timer1 Registers
    141.     T1CKPS1 = 0;  T1CKPS0 = 0; //1:1 Timer1 Prescalar
    142.     T1SYNC = 0;                //External Clock Input sync off
    143.     TMR1IE = 1;                //Timer1 Interrupt enabled
    144.     TMR1ON = 1;             //Timer1 Enabled and started
    145.     CCP1M3 = 0; CCP1M2 = 1; CCP1M1 = 0; CCP1M0 = 1;    //Capture Mode enabled on rising edge
    146.     CCP1IE = 1;                //Prevent False Interrupts
    147.     GIE = 1;                 //Interrupt Enable
    148.       PEIE = 1;                //Global Interrupts Enable    
    149.     DisplayInit();             //Initialize the Seven Segment Displays
    150.     while(1)
    151.     {
    152.        
    153.         // if capture interrupt changed, update 'value' from CCP value
    154.       if ( CCP1IF )
    155.     {
    156.     counter=(CCPR1H+CCPR1L)/100;
    157.     CCP1IF = 0;
    158.      }
    159.      // if timer interrupt: reset timer and toggle Port B.2
    160.     if ( TMR1IF )
    161.     {
    162.     TMR1H = 0x00;  TMR1L = 0x00;
    163.     TMR1IF = 0;
    164.       }
    165.         Print(counter);
    166.         __delay_ms(100);
    167.        
    168.     }
    169.        
    170. }
    171. [/i][/i][/i]
    Chip is a 16F628, RB0-RB2,RB4-RB7 segment drivers... RA0-RA1- digit drivers, RB3 as capture pin, int osc, RB3 driven by optocoupler.. Timer0 for display mux refresh, Timer1 for capture interrupt. 2 led 7 segment displays muxed..

    Input fed through this ckt
    [​IMG]

    Sources are a 9-0-9 ac transformer, pc soundcard output using function generator and a 50Khz multimeter square wave output.. none of these could be detected..
     
    Last edited: Aug 11, 2011
  2. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,392
    1,606
    You have a lot going on in this "simple" project, and if any piece fails you can get results such as you say.

    You need to break the chain. Test each part first, then link together.

    - does the 7 seg really respond to BCD data? Try giving it a few test values.

    - does the isolator driver really work? You need to make sure something is coming out, if you have a scope you probably did that. If you just have a voltmeter you need to drive it on and off slowly so the voltmeter can tell you if it works.

    I'll on my way out now, will check back later after I look at the CCP.

    Meanwhile, two words for you: CODE TAGS !! ;)
     
  3. jj_alukkas

    Thread Starter Well-Known Member

    Jan 8, 2009
    751
    5
    I actually started coding with the display. If I print 53, display shows 53, but when I went for this ccp section, i didnt know how to 'take' the output without a display.. so had to put everything together and that made me lose it all.. The 7 segment shows just 00 when the ccp codes are used and im getting crazy seeing global interupts everywhere. The timer0 and timer1 along with the GIE and all makes me confused. somewhere it will be 0 and somewhere its 1. I started building step by step, but now its a mess. Could you tell me anyway to check the ccp module alone so that i can test it without the display code?

    Isolator section is fine, multimeter shows hi and lows fine for the inputs I give. overall hardware is fine I guess, its just the ccp :(

    sorry abt the code tags.. I clicked on quote tags and thought as code tags :p My mistake.
     
  4. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,392
    1,606
    Tried the code a bit in MPLAB. I needed to change a few things, I believe you have the old compiler. Do download the current version it comes packed along with MPLAB. AFAIK the old one has some bugs. The new one has changed the definitions for __CONFIG:

    Code ( (Unknown Language)):
    1. __CONFIG(FOSC_INTOSCIO & WDTE_OFF & PWRTE_OFF & BOREN_OFF & LVP_OFF ); //Config Bits
    I get a compiler bark for "Print(counter);" as counter is a float and Print is looking for an unsigned short. Since your input is an integer from a counter and so is your output (number between 0 and 99 on the display) there is no reason to use floats here, do it all with integers as it will be faster and perhaps more accurate too.

    You should be able to simulate this inside MPLAB just fine. You can set a frequency at RB3 using Debugger | Stimulus to set some frequency there.

    I did that and saw the ISR gets hung up once your Timer1 tosses an interrupt and the ISR doesn't handle it, so it gets stuck doing the ISR over and over and over.
    Your ISR needs to look something like this:
    Code ( (Unknown Language)):
    1. void interrupt ISR() //Interrupt Service Routine for Display
    2. {
    3. //  if(T0IE && T0IF)  //Check if TMR0 has Overflowed
    4.   if(T0IF)            //Check if TMR0 has Overflowed (no need to check T0IE)
    5.   {
    6.     SevenSegISR();    //Call the SevenSegISR
    7.     T0IF=0;           //Clear Flag for Timer0
    8.   }
    9.  
    10.   if (TMR1IF)
    11.   {
    12.     // do something with this information???
    13.     TMR1IF = 0;
    14.   }
    15. }
    Besides just doing raw code dump next time please include a description of the logic behind the code.
     
  5. jj_alukkas

    Thread Starter Well-Known Member

    Jan 8, 2009
    751
    5
    Thanks for your reply, I have the newer compiler, but once I installed, all my fuses showed up as errors and I thought it was a bug :p lol :p will install it now..
    The thing is display uses timer0 and an interrupt for the digit selection scan and has an interrupt ISR() with just

    Code ( (Unknown Language)):
    1. void interrupt ISR()            //Interrupt Service Routine for Display
    2. {
    3.      if(T0IE && T0IF)                    //Check if TMR0 has Overflowed
    4.      {         SevenSegISR();         //Call the SevenSegISR
    5.                T0IF=0;                    //Clear Flag for Timer0
    6.      }
    7. }
    And to run the capture module, Timer1 must be used and I didnt know where to put the interrupt and overflow checking stuffs for T1??

    So should I put the second interrupt within the first function or as a second one? Thats where all the mess starts..
    I'll try it the way you told.. all interrupts inside the isr()

    will check and see.. thanks for the sim tip.. can watch registers there :)
     
  6. jj_alukkas

    Thread Starter Well-Known Member

    Jan 8, 2009
    751
    5
    Did an update to picc 9.82, updated fuses, some quick check ups and all the corrections, placed timer1 iterrupts and overflow checks inside isr routine, integer value for counter, and checked.. now it started showing some results! for a 50hz input, it shows 88 and when its off, it shows 00. I can work out the math to bring it to range, but can you tell me what will be the range for CCPR1H+CCPR1L and for what input at RB0?? In what form will I get the data? hex? binary? With that, I may be able to get an idea for the math..

    Here's the updated code.

    Code ( (Unknown Language)):
    1. #include <HTC.H>
    2. #define _XTAL_FREQ 4000000                    //Internal OSC Freq
    3.  
    4. #define SEGMENT_TRIS     TRISB                //Display Segments Connected Ports
    5. #define SEGMENT_PORT    PORTB
    6.  
    7. #define DIGIT_TRIS    TRISA                    //Display Digit select data ports
    8. #define DIGIT_PORT    PORTA
    9.  
    10. __CONFIG(FOSC_INTOSCIO & WDTE_OFF & PWRTE_OFF & BOREN_OFF & LVP_OFF );  //Config Bits
    11.  
    12. unsigned char digits[2]={0,0};                //Defining the Digit Array
    13. unsigned short int counter;
    14.  
    15. void Wait(unsigned char delay)                //Delay Loops
    16. {
    17.     for(;delay;delay--)
    18.         __delay_us(100);
    19. }
    20.  
    21. void SevenSegment(unsigned char num)        //Defining the segment pattern for each digit 0-9
    22. {
    23.    switch(num)
    24.    {
    25.       case 0:
    26.         SEGMENT_PORT= 0B01000000;            // Defined in the order xGFEDCBA segments
    27.          break;
    28.  
    29.       case 1:
    30.         SEGMENT_PORT= 0b11111001;
    31.          break;
    32.  
    33.       case 2:
    34.         SEGMENT_PORT= 0B00100100;
    35.          break;    
    36.  
    37.       case 3:
    38.         SEGMENT_PORT= 0B00110000;
    39.          break;
    40.  
    41.       case 4:
    42.         SEGMENT_PORT= 0B10011001;
    43.          break;
    44.  
    45.       case 5:
    46.         SEGMENT_PORT= 0B00010010;
    47.          break;
    48.  
    49.       case 6:
    50.         SEGMENT_PORT= 0B00000010;
    51.          break;
    52.  
    53.       case 7:
    54.         SEGMENT_PORT= 0B11111000;
    55.          break;
    56.  
    57.       case 8:
    58.         SEGMENT_PORT= 0B00000000;
    59.          break;
    60.  
    61.       case 9:
    62.         SEGMENT_PORT= 0B00010000;
    63.          break;
    64.    }
    65. }
    66.  
    67. void DisplayInit()
    68. {
    69.    
    70.     SEGMENT_TRIS=0b00001000;            //Config segment ports as outputs
    71.     DIGIT_TRIS=0b00100000;                //Config Digit Ports as Outputs
    72.  
    73.     DIGIT_PORT=0B00000011;                //Digit select port state
    74.    
    75.     //Setup Timer0 for the Digit Scanning Operation
    76.     PS0=1;                                //Prescaler is divide by 64
    77.     PS1=0;
    78.     PS2=1;
    79.  
    80.     PSA=0;                                //Timer Clock Source is from Prescaler
    81.  
    82.     T0CS=0;                                //Prescaler gets clock from Internal OSC
    83.    
    84.     T0IE=1;                                //Enable TIMER0 Interrupt
    85.     PEIE=1;                                //Enable Peripheral Interrupt
    86.     GIE=1;                                //Enable INTs globally
    87.  
    88.     TMR0=1;                                //Staring timer0    
    89. }    
    90.  
    91. void Print(unsigned short num)            // This function splits a number to Ones and Tens for display on each digit
    92. {
    93.    
    94.     unsigned char i=0;
    95.     unsigned char j;
    96.     if(num>99) return;
    97.     while(num)
    98.     {
    99.         digits[i]=num%10;                //Splitting Numbers and Storing in Arrays
    100.         i++;
    101.  
    102.         num=num/10;
    103.     }
    104.     for(j=i;j<2;j++) digits[j]=0;
    105. }    
    106.  
    107. void SevenSegISR()                        // Display Scanner which update the multiplexed Displays    
    108. {
    109.    
    110.     TMR0=150;
    111.     static unsigned char i;
    112.     if(i==1)
    113.         i=0;                            //Checking end of Display Scan
    114.     else
    115.         i++;                            //Incrementing to next digit for refresh
    116.    
    117.     DIGIT_PORT=((DIGIT_PORT & 0b00111111)|(1<<i)); //Display Output on the Digits
    118.     SevenSegment(digits[i]);            //Write the digit[i] in the ith display.
    119. }        
    120.  
    121. void interrupt ISR()                    //Interrupt Service Routine
    122. {
    123.     if(T0IE && T0IF)                    //Check if TMR0 has Overflowed
    124.     {
    125.         SevenSegISR();                    //Call the SevenSegISR
    126.         T0IF=0;                            //Clear Flag for Timer0
    127.     }
    128.     if ( CCP1IF )         // if capture interrupt changed, update 'value' from CCP value
    129.     {
    130.         counter=((CCPR1H+CCPR1L)/100)+20;
    131.         CCP1IF = 0;
    132.      }
    133.     if ( TMR1IF )         // if timer1 register overflow: reset timer
    134.     {
    135.     TMR1H = 0x00;  TMR1L = 0x00;
    136.     TMR1IF = 0;
    137.       }
    138. }            
    139.  
    140. void captureInit()
    141. {
    142.     CMCON=0x07;
    143.     TMR1CS = 0;                //Timer1 uses int clk as osc source
    144.     TMR1IF = 0;                //Reset Timer1 Flag Bit
    145.     TMR1H  = 0x00;  TMR1L = 0x00;    //Reset Timer1 Registers
    146.     T1CKPS1 = 0;  T1CKPS0 = 0; //1:1 Timer1 Prescalar
    147.     //T1SYNC = 0;                //External Clock Input sync off
    148.     TMR1IE = 1;                //Timer1 Interrupt enabled
    149.     TMR1ON = 1;             //Timer1 Enabled and started
    150.     CCP1M3 = 0; CCP1M2 = 1; CCP1M1 = 0; CCP1M0 = 1;    //Capture Mode enabled on rising edge
    151.     CCP1IE = 1;                //Prevent False Interrupts
    152.     GIE = 1;                 //Interrupt Enable
    153.       PEIE = 1;                //Global Interrupts Enable
    154. }
    155. void main()
    156.  
    157. {
    158.     DisplayInit();             //Initialize the Seven Segment Displays
    159.     captureInit();
    160.     while(1)
    161.     {
    162.         Print(counter);
    163.         __delay_ms(1000);
    164.        
    165.     }
    166.    
    167.        
    168. }
    169. [/i][/i][/i]
     
  7. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,392
    1,606
    I can't tell until you tell me what your logic is, what you are setting and what you expect to happen.

    It is nearly impossible to reverse engineer code to get the intent. That's what comments and flow charts are for.

    I can tell you that the CCPR1 registers will hold a copy of TMR1 when the interrupt happens. If we assume that TMR1 was cleared last time this happened then CCPR1 holds how many counts occurred since the last time, this is a period measurement. CCPR1 is made of two 8 bit registers, so to copy the value you need to do:

    Code ( (Unknown Language)):
    1. counter=((CCPR1H<<8 + CCPR1L);
    That is assuming a unsigned short int (counter) can hold 16 bits. Check that too.

    If you divide how many Timer1 clocks occur in 1 second (that should be a constant) by counter then you have the frequency.
     
  8. jj_alukkas

    Thread Starter Well-Known Member

    Jan 8, 2009
    751
    5
    mm.. looks logical.. i tried a sim watching the registers and with an input 50hz pulse.. The thing runs, for sometime, both the 8bit CCPR1 registers value changes and after some time gives an error core halted as pc register overflowed and was reset to 0x00. And on loading to the pic, I multiplied with 0.1362 which was the value i found when the sim was run with a 50hz and registers changed.. now i get crazy results in multiples of 11 like 22 44 99 :p let me try the shifting method to get the value to counter..

    if you dont mind, can you show me an example how to count number of captures between 2 timer1 interrupts? just a rough idea wud be enough, ill check commands..
     
  9. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,392
    1,606
    I would do the following in the ISR. Note no need to do anything here with Timer1 overflowing; if it does you have invalid data there but with a 1MHz clock a 30Hz signal the max count would be 10^6/30 = 33,333, and a 16 bit register can hold up to 65,535 without overflowing.

    This compiler can handle dividing 10^6 by counter, at least it compiled here.

    Code ( (Unknown Language)):
    1. void interrupt ISR()                    //Interrupt Service Routine
    2. {
    3.     if(T0IF)              //Check if TMR0 has Overflowed
    4.     {
    5.         SevenSegISR();                  //Call the SevenSegISR
    6.         T0IF=0;                         //Clear Flag for Timer0
    7.     }
    8.     if ( CCP1IF )         // if capture interrupt changed, update 'value' from CCP value
    9.     {
    10.         counter=(CCPR1H<<8 + CCPR1L);   // copy how many counts
    11.         TMR1 = 0;                       // reset Timer1 for the next time
    12.         CCP1IF = 0;                     // clear the CCP flag
    13.      }
    14. }            
    15.  
     
  10. jj_alukkas

    Thread Starter Well-Known Member

    Jan 8, 2009
    751
    5
    Tried operating on this code.. No response for any inputs.. Have doubt.. how will CCPR1H<<8 work on this? cant we do something like x 10^8 or something? because when I make it as (CCPR1H + CCPR1H)/100 the value changes..:confused:
     
  11. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    <<8 means left shift 8 times, the same as multiply by 256, but it forces the complier to do it the most efficient way.
    If you have 1 in CCPR1H you can't just add it to CCPR1L because it means 256.
    I don't know if C handles the case where CCPR1L overflows just after you read CCPR1H so it is probably best to stop the timer to read it if you can.
     
  12. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,392
    1,606
    CCPR1 L & H are not counters, not part of Timer1. They hold the last latched value of Timer1 when the RB3 input transistions. Latched. Not counting. No need to do anything special but read them within the first 65.5 milliseconds of the interupt routine triggered by that same transition. Should you read them after that, then you just get the next reading of the period.

    (The other part was quite true and well taken.)
     
  13. jj_alukkas

    Thread Starter Well-Known Member

    Jan 8, 2009
    751
    5
    That code had problems in interrupts and fetching data.. I found a similar code online designed to something else and modified it for a frequency counter.. now it works just fine and accuracy +/- 1Hz for the internal osc.. it works only till 100hz, have to get it beyond that.. I think I will use this one as it uses fewer lines of code and will have room if I need to add more stuffs..

    Code ( (Unknown Language)):
    1. #include <htc.h>
    2. #define _XTAL_FREQ 4000000        
    3.  
    4. __CONFIG(FOSC_INTOSCIO & WDTE_OFF & PWRTE_OFF & BOREN_OFF & LVP_OFF );  //Config Bits
    5.  
    6. unsigned char control;
    7.  
    8. void interrupt ISR(){
    9. TMR1H=0; TMR1L=0;
    10. GIE=0;
    11.  
    12. control=1;
    13.  
    14. CCP1IF=0;
    15. GIE=1;
    16. }
    17.  
    18. main(void)
    19. {
    20. unsigned const char number[10]={0x40, 0xf9, 0x24,
    21.           0x30, 0x99,0x12,0x02,0xf8,0x00,0x10};
    22. unsigned char select[2]={1,2};
    23. unsigned int counter,value,remainder1,remainder2;
    24. float frequency;
    25. unsigned char a,i,display[5],data;
    26.  
    27. TRISA=0x00;
    28. TRISB=0x08;
    29. CMCON=0x07;
    30.  
    31. control=0;
    32. PORTA=0; PORTB=0;
    33.  
    34. CCP1IE=1;
    35.  
    36. CCP1CON=0b00000110;
    37.  
    38. T1CON=0b00100001;
    39.          
    40. GIE=1;
    41. PEIE=1;
    42.  
    43. for(;;){
    44.  
    45.  
    46. counter=256*CCPR1H+CCPR1L;
    47.  
    48. if(control==1)frequency=100000000/counter;
    49. if(control==0)frequency=0;
    50.  
    51. if(counter<10000)frequency=0;
    52.  
    53. control=0;
    54.  
    55. for(a=0;a<25;a++){
    56.  
    57.     value=(int)frequency;
    58.     display[2]=value/1000;
    59.     remainder1=value-(display[2]*1000);
    60.  
    61.     display[1]=remainder1/100;
    62.     remainder2=remainder1-(display[1]*100);
    63.  
    64.     //display[1]=remainder2/10;
    65.     //display[2]=remainder2-display[1]*10;
    66.    
    67.    
    68.     for(i=0;i<2;i++){
    69.         PORTB=0;
    70.         PORTA=0;
    71.  
    72.         data=number[display[i+1]];
    73.         PORTB=data&0xF8;
    74.         data=data<<0;
    75.         PORTB=PORTB|(data&0x0F);
    76.  
    77.         PORTA=select[i];
    78.         __delay_ms(6);
    79.     }
    80. }
    81. }
    82. }
    83. [/i]


    Here as Markd77 stated, CCPR1H was multiplied by 256 and a variable was placed in interrupt to detect if something was captured.. and checked to print the value.. now it works just fine..
     
Loading...