I'm trying to measure the width of incoming pulses. The width can be 70us or 140us. I must be able to receive up to 1160 pulses per second (1160 Hz). If the pulse is 70us, I must increase the EnergyCount, if it is 140us I must decrease the EnergyCount. I'm trying to use CCP1 module to do this but it doesn't work. I'm using TMR1 for CCP1. I'm also using TMR0 to check when a second has passed but this is also not working. I've set the speed of the 18F2550 to 4MHz internal oscillator. And I've attached a LED to PORTA.F0 to see when a interrupt occurs. I'm displaying the pulse width and the amount of pulses I received in a second, on a LCD.
Any help with this will greatly be appreciated.
Thanks in advance
Code: Select all
unsigned int t1, pulsewidth;
unsigned int EnergyCount = 0;
unsigned int prev_t1 = 0;
char txt[10];
unsigned int t0_cnt=0;
unsigned int tmr_0_flag=0;
unsigned int CCP_mode=0;
void interrupt(){
t1= ((CCPR1H << 8) + CCPR1L); // put CCP timer 16bit value in t1
if(INTCON.TMR0IF ==1)
{
INTCON.TMR0IF =0b0;
tmr_0_flag=1;
return;
}
PIE1.CCP1IE = 0b0; //Disable interrupt (If CCP1 mode is changed interrupt will occur)
if(CCP1CON.CCP1M0== 0b1){
CCP_mode=0;
}else{
CCP_mode=1;
}
PIR1.CCP1IF = 0b0; //Clear CCP1 interrupt flag
PIE1.CCP1IE = 0b1; //CCP1 interrupt enable */
if(PORTC.F2==1){
prev_t1 = t1;
}else{
if(t1>prev_t1)
pulsewidth = t1-prev_t1;
else
pulsewidth = (0xFFFF - prev_t1) + t1;
if (pulsewidth >= 50)
EnergyCount = EnergyCount - 1; //
else
EnergyCount = EnergyCount + 1; //
}
}
void main() {
TRISA=0;
PORTA=0;
TRISC=0x07;
TRISB = 0; // PORTB is output
Lcd_Config(&LATB,2,3,1,7,6,5,4);
Lcd_Init(&LATB); // Initialize LCD connected to PORTB
Lcd_Cmd(Lcd_CLEAR); // Clear display
Lcd_Cmd(Lcd_CURSOR_OFF); // Turn cursor off
WordToStr(pulsewidth,txt);
T0CON.T08BIT = 0b1; //Timer0 is 8bit timer
T0CON.T0CS = 0b0; //Internal clock source
T0CON.PSA = 0b0; //Prescaler Active
T0CON.T0PS0 = 0b1; //Prescaler bit
T0CON.T0PS1 = 0b1; //Prescaler bit
T0CON.T0PS2 = 0b1; //Prescaler bit
INTCON.TMR0IF = 0b0; //Clear timer0 interrupt flag
INTCON.TMR0IE =0b1; //Timer0 interrupt enable
T1CON.TMR1CS=0b0; //Timer1 source = other
T1CON.T1CKPS0=0b1; //Prescaler
T1CON.T1CKPS1=0b1; //Prescaler to 1:8 (4000000/4/8=125000 (1/125000 = 8us))
T1CON.T1OSCEN=0b0; //Timer1 OSC off
T1CON.T1RUN=0b0; //Device clock is derived from another source
T1CON.RD16=0b1; //timer1 is 16 bit (TMR1H,TMR1L)
T1CON.TMR1ON=0b1; //Timer1 is turned on
T0CON.TMR0ON = 0b1; //Timer0 is turned on
CCP1CON= 0b0000; //Capture off
PIR1.CCP1IF = 0b0; //Clear CCP1 interrupt flag
T3CON.T3CCP1 = 0b0; //Select Timer1 as source
T3CON.T3CCP2 = 0b0;
CCP1CON.CCP1M0= 0b1; //Capture on (Rising Edge = 0101) (Falling Edge = 0100)
CCP1CON.CCP1M1= 0b0;
CCP1CON.CCP1M2= 0b1;
CCP1CON.CCP1M3= 0b0;
PIE1.CCP1IE = 0b1; //Enable CCP1 Interrupt
INTCON.PEIE = 0b1; //Enable Perephiral interrupt
INTCON.GIE = 0b1; //Enable Global interrupt
while (1){
WordToStr(pulsewidth,txt);
Lcd_Out(1,8,txt);
WordToStr(EnergyCount,txt);
Lcd_Out(2,8,txt);
if(tmr_0_flag==1){
tmr_0_flag=0;
if(t0_cnt==31){
EnergyCount = 0;
t0_cnt=0;
}else{
t0_cnt++;
}
}
if(CCP_mode==0){
CCP1CON.CCP1M0= 0b0; //Capture on (Rising Edge = 0101) (Falling Edge = 0100)
PORTA=0xff;
}
if(CCP_mode==1){
CCP1CON.CCP1M0= 0b1; //Capture on (Rising Edge = 0101) (Falling Edge = 0100)
PORTA=0x00;
}
}
}