0
\$\begingroup\$

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)
     {

     } 
}
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.