#include "p33FJ12MC202.h"
//#define XTFREQ 7370000 //FRC frequency
#define FCY 39613000 //Instruction Cycle Frequency
#define BAUDRATE 9600
#define BRGVAL ((FCY/BAUDRATE)/16)-1
#define MILLISEC 8200
#define T_PULSE 2000
void DelayNmSec(unsigned int);
void PLL_Init (void);
unsigned int adc_value;
unsigned int t_max;
float ft_max = 38000.0;
float ft_pulse;
int main(void)
{
PLL_Init( );
AD1PCFGL = 0xFFFE; // all PORTB = Digital; RB12 = analog
LATB = 0x0000;
LATA = 0x0000;
TRISAbits.TRISA0 = 1; // RP3 input (analog)
TRISBbits.TRISB6 = 1; // RP6 input
TRISBbits.TRISB15 = 0; // RP15 output
RPOR7bits.RP15R = 18; // OC2 en RP15
RPINR3bits.T2CKR = 6; // TCK2 en RP2
// TIMER
TMR2 = 0; // Clear timer 2
PR2 = 0xFF00; // Interrupt every ...
IFS0bits.T2IF = 0; // Clr interrupt flag
IEC0bits.T2IE = 1; // Set interrupt enable bit
T2CONbits.TCKPS = 1; // 1:8 prescale, start TMR2
T2CONbits.TGATE = 1; // Gated time accumulation enabled
// Initialize Output Compare Module
OC1CONbits.OCM = 0; // Disable Output Compare Module
OC1CONbits.OCTSEL = 0; // Select Timer 2 as output compare time base
OC1R = 0xFFFF; // Load the Compare Register Value for rising edge
OC1RS = 0xFFFF; // Load the Compare Register Value for falling edge
//IPC0bits.OC1IP = 0x01; // Set Output Compare 1 Interrupt Priority Level
IFS0bits.OC1IF = 0; // Clear Output Compare 1 Interrupt Flag
IEC0bits.OC1IE = 0; // Enable Output Compare 1 interrupt
OC1CONbits.OCM = 5; // Select the Output Compare mode
// ADC
AD1CON1 = 0x00E0; // SSRC bit = 111 implies internal
// counter ends sampling and starts
// converting.
AD1CHS0= 0x0000; // Connect RB12/AN12 as CH0 input ..
// in this example RB12/AN12 is the input
AD1CSSL = 0;
AD1CON3 = 0x1F02; // Sample time = 31Tad, Tad = internal 2 Tcy
AD1CON2 = 0;
AD1CON1bits.ADON = 1; // turn ADC ON
T2CONbits.TON = 1; // TMR2 start!
while(1)
{
DelayNmSec( 50 );
AD1CON1bits.SAMP = 1; // start sampling then ...
while (!AD1CON1bits.DONE); // conversion done?
adc_value = ADC1BUF0; // yes then get ADC value
AD1CON1bits.DONE = 0; // Asegura reinicio
ft_max = (float) t_max - T_PULSE;
ft_pulse = ((float)adc_value)*ft_max / 1023.0;
OC1R = (unsigned int)ft_pulse;
OC1RS = OC1R + T_PULSE;
}
return 0;
}
void PLL_Init (void)
{
// Configure Oscillator to operate the device at 40Mhz
// Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
// Fosc= 8M*40/(2*2)=80Mhz for 8M input clock
PLLFBD = 41; // M=40
CLKDIVbits.PLLPOST=0; // N1=2
CLKDIVbits.PLLPRE=0; // N2=2
OSCTUN=0; // Tune FRC oscillator, if FRC is used
// Disable Watch Dog Timer
RCONbits.SWDTEN=0;
// clock switching to incorporate PLL
__builtin_write_OSCCONH(0x03); // Initiate Clock Switch to Primary
// Oscillator with PLL (NOSC=0b011)
__builtin_write_OSCCONL(0x01); // Start clock switching
while (OSCCONbits.COSC != 0b011); // Wait for Clock switch to occur
// Wait for PLL to lock
while( (OSCCON & 0x0020) == 0 ) {};
}
void DelayNmSec(unsigned int N)
{
unsigned int i;
while(N--)
{
for(i=0; i < MILLISEC; i++);
}
}
void __attribute__((__interrupt__, no_auto_psv)) _T2Interrupt(void)
{
IFS0bits.T2IF = 0; // clear interrupt flag
t_max = TMR2;
TMR2 = 0;
}