Hy.
I want to make a program who toggle a led using compare mode, set output on match (CCP1IF bit is set). I dont know if it is possible what i want to do. Anyway the RB0 is always ON. I know, it must be ON because when the value loaded in ccpr1 register matches with the value of tmr1 register the RB0 is set. But if want to reset the RB0 output ? I have doing this in interrupt() function writing the next statement : ccp1con=0b00001001; And now the RB0 stay always OFF.
#include <system.h>
#pragma DATA _CONFIG1, _EXTRC_CLKOUT & _WDT_OFF & _LVP_OFF
void interrupt()
{
if((pir1 & 0x01) && (pir1 & 0x04))
{
clear_bit(pir1, 0); // clear TMR1IF
clear_bit(pir1, 2); // clear CCP1IF
ccp1con = 0b00001001; // clear output on match
}
}
void main()
{
trisb = 0xf0;
portb = 0x00;
tmr1h = 0;
tmr1l = 0;
ccpr1l = 0x60;
ccpr1h = 0xEA;
cmcon = 0x07;
t1con = 0b00000001; // prescaler = 1
intcon = 0b11000000;
pie1 = 0b00000101;
ccp1con = 0b00001000; // set output on match
while(1)
{
}
}
1 Answer 1
I've done this by having the compare match trigger an interrupt, and then the interrupt toggles the pin by reading the data.
Sorry, my example is in assembler, but you should get the gist:
(inside the interrupt service code)
btfss PIR1,CCP1IF ; is there a timer 1/compare interrupt?
goto INotTmr1
;; process timer 1 interrupt.
clrf TMR1L ; clear timer 1
clrf TMR1H ; clear timer 1
bcf PIR1,CCP1IF ; clear compare match interrupt bit.
btfss PORTC,LED1 ; is led1 hi?
goto ITmr11 ; no.
bcf PORTC,LED1 ; lower led1 bit.
goto INotTmr1 ; done.
ITmr11 ; led1 bit was low.
bsf PORTC,LED1 ; raise led1 bit.
INotTmr1 ; end of timer 1 interrupt code.
(in the setup code)
;; set up timer 1
movlw b'00000000' ; set up timer 1.
movwf T1CON ; set up timer 1.
movlw b'00001010' ; timer 1 compare throws interrupt.
movwf CCP1CON ; set up compare mode.
movlw h'ff' ; init compare value.
movwf CCPR1L ; set up initial compare (invalid)
movwf CCPR1H ; set up initial compare (invalid)
then turn on timer 1 when you are ready to start toggling
Good luck with your project.