dsPIC Frequency counter

Discussion in 'Embedded Systems and Microcontrollers' started by D8666, Jun 27, 2014.

  1. D8666

    Thread Starter New Member

    Nov 15, 2013
    16
    0
    I'm trying to implement a frequency counter using a dsPIC30F4011 I have not used input capture or timer interrupts before so would anyone be able to have a look through my program and spot any obvious mistakes, my readings from the UART seem to be all over the place while reading a signal from a function generator, Ideally I'm looking to read frequencies from 0.5 HZ to 60 HZ, Thanks for your time.

    Code ( (Unknown Language)):
    1. # include <p30f4011.h>
    2. # include <math.h>
    3. # include <stdio.h>
    4. # include<InCap.h>
    5. # include <xc.h>
    6. # include <libpic30.h>
    7.  
    8. #define LED     LATDbits.LATD0
    9.  
    10.  
    11. // Configuration settings
    12. _FOSC(CSW_FSCM_OFF & FRC_PLL16);     // Fosc=16x7.5MHz, Fcy=30MHz
    13. // (units are instruction cycles, Tcy=33.33ns @ 30 MIPS)
    14. _FWDT(WDT_OFF);                      // Watchdog timer off
    15. _FBORPOR(MCLR_DIS);                  // Master Clear Pin disabled
    16.  
    17. /*************Global Variables and Constants*************/
    18. /*Variables used for period calculation*/
    19. unsigned int timePeriod= 0;
    20. unsigned int current_value=0,previous_value=0;
    21. unsigned int new_value=0;
    22.  
    23. void __attribute__((__interrupt__)) _IC7Interrupt(void);
    24. void __attribute__((__interrupt__, __shadow__)) _T2Interrupt(void);
    25.  
    26.  
    27. /****FUNCTION PROTOTYPES****/
    28. void IC7_SETUP(void);
    29. void TIMER2_SETUP (void);
    30. void setup();
    31.  
    32. /******MAIN BODY******/
    33. int main (void)
    34. {
    35. TRISD=0;                              // Setting Port D pins as outputs
    36. PORTD=0;                              // Reset The LED
    37. PORTD=0xff;                              // Light The LED, to test the PIC is working
    38. TRISB=0x003f;                           // Setting all PortB as inputs
    39. ADPCFG=0xffff;                        // Setting the analogue pin as digital inputs
    40.  
    41.  
    42. TIMER2_SETUP();                     // Calling the Timer Setup Function
    43. IC7_SETUP();                          // Calling the Input Setup Function
    44. setup();                            // Calling the UART function
    45.  
    46.  
    47. while(1)
    48. {
    49. }
    50. return (0);
    51. }
    52.  
    53. /***SETUP_IC****/
    54. void IC7_SETUP (void)
    55. {
    56. // Register 13-1: ICxCON: Input Capture x Control Register in datasheet //
    57. IC7CONbits.ICM= 0b011;                // Input Capture Mode Select (Every rising edge)
    58. IC7CONbits.ICBNE=0;                    // Input Capture Buffer Empty Status (Read Only)
    59. IC7CONbits.ICOV=0;                    // Input Capture Overflow Status Flag (Read Only)
    60. IC7CONbits.ICI= 00;                    // Select Number of Captures per Interrupt bits (00 = Interrupt on every capture event)
    61. IC7CONbits.ICTMR=1;                    // Input Capture Timer Select bits (1=TMR2 contents are captured on captured event)
    62. IC7CONbits.ICSIDL=0;                // Input Capture Module Stop in Idle Control(0=Input capture module will continue to operate in CPU Idle mode)
    63. // Register 6-6: IFS1: Interrupt Flag Status Register 1
    64. IFS1bits.IC7IF = 0;                   // Input Capture Channel 7 Interrupt Flag Status )0=Interrupt bit is cleared
    65. // Register 6-9: IEC1: Interrupt Enable Control Register 1
    66. IEC1bits.IC7IE = 1;                 // Input Capture Channel 7 Interrupt Enable bit (1 = Interrupt request enabled)
    67. }
    68.  
    69.  
    70. /****INTERRUPT FOR IC7****/
    71. // Capture Interrupt Service Routine
    72. //unsigned int timePeriod= 0;
    73. void __attribute__((__interrupt__, no_auto_psv )) _IC7Interrupt(void)
    74. {
    75.     previous_value=current_value;
    76.     current_value=IC7BUF;
    77.     printf("Current value =%d \n, ",current_value);
    78.     printf("Previous value =%d \n, ",previous_value);
    79.    
    80.     float time1 = 0;
    81.     float time2 = 0;
    82.     float time3 = 0;
    83.     float time4 = 0;
    84.     float frequency = 0;
    85.    
    86.     if(current_value>previous_value)
    87.     {
    88.         timePeriod = current_value-previous_value;
    89.         printf("timePeriod =%d \n, ",timePeriod);
    90.         time1 = timePeriod*pow(33.33,-9);
    91.         time2 = pow((float)time2, -9);
    92.         frequency = 1/time2;
    93.         printf("frequency=%f Hz \n, ",time1);
    94.     }
    95.    
    96. }
    97.  
    98.  
    99.  
    100. /***TIMER_SETUP***/
    101. void TIMER2_SETUP (void)
    102. {
    103. T2CON = 0x00;                 // Stops the Timer2 and reset control reg.
    104. T2CONbits.TCS=0;             // Using Internal Clock (Fosc/4)
    105. T2CONbits.T32=0;            // TMR2 and TMR3 form separate 16-bit timer
    106. T2CONbits.TCKPS=0;          // Using 1:1 prescale value
    107. T2CONbits.TGATE=0;            // Timer Gate Accumulation Disabled
    108. T2CONbits.TSIDL=0;            // Continue in Idle Mode*/
    109. TMR2 = 0x00;                 // Clear contents of the timer register
    110. PR2 = 0xFFFF;                 // Load the Period register with the value 0xFFFF
    111. IPC1bits.T2IP = 0x01;         // Setup Timer2 interrupt for desired priority leve
    112.                             // (This example assigns level 1 priority)
    113. IFS0bits.T2IF = 0;             // Clear the Timer2 interrupt status flag
    114. IEC0bits.T2IE = 1;             // Enable Timer1 interrupts
    115. T2CONbits.TON = 1;             // Start Timer1 with prescaler settings at 1:1 and
    116.                             // clock source set to the internal instruction cycle
    117. }
    118.  
    119. /* Example code for Timer1 ISR*/
    120. void __attribute__((__interrupt__, no_auto_psv, __shadow__)) _T2Interrupt(void)
    121. {
    122. /* Interrupt Service Routine code goes here         */
    123. IFS0bits.T2IF = 0; //Reset Timer1 interrupt flag and Return from ISR
    124. }
    125.  
    126.  void setup()
    127. {
    128.     // Set up UART
    129.     // Default is 8 data bits, 1 stop bit, no parity bit
    130.     U1BRG = 48;                // 38400 baud @ 30 MIPS
    131.     U1MODEbits.UARTEN = 1;     // Enable UART
    132.     U1STAbits.UTXISEL = 1;     // interrupt when TX buffer is empty
    133.     U1STAbits.UTXEN = 1;       // Enable TX
    134. }
     
Loading...