Wednesday, March 22, 2006

PIC: EXAMPLE 10

EXAMPLE 10

Module CCP1 as PWM signal generator

Since the CCP modules have a wide range of possibilities they are commonly used in practice. This example illustrates the use of CCP1 module in PWM mode. Bits of the CCP1CON register determine that the module operates as a single-output PWM. The same bits determine the PWM frequency to be 4.88 kHz. To make things more interesting, the duration of the output P1A (PORTC,2) pulses may be changed by means of push-buttons symbolically called "DARK" and "BRIGHT". Push-buttons are tested in interrupt routine initiated by the timer TMR1. Any change affects the LED diode so that it changes light intensity. Note that port B does not use external resistors because internal pull-up resistors are enabled. The whole process of generating PWM signal is performed "behind the scenes", which enables the microcontroller to do other things.
Example 10 - Module CCP1 as PWM signal generator

Source Code

;********************** Header **********************************************
;************* DEFINING VARIABLES *******************************************
      cblock       0x20            ; Block of variables starts at address 20h
      w_temp                       ; Variable at address 20h
      pclath_temp                  ; Variable at address 21h
      status_temp                  ; Variable at address 22h
      endc
      
      #define      DARK PORTB,0    ; Push-button "DARK" is connected
                                   ; to PORTB,0 pin
      #define      BRIGHT PORTB,1  ; Push-button "BRIGHT" is connected
                                   ; to PORTB,1 pin
;************************ PROGRAM START *************************************

      org          0x0000          ; First program instruction address
      goto         main            ; Jump to label "main"

;************************ INTERRUPT ROUTINE *********************************

      org          0x0004          ; Interrupt vector
      
      movwf        w_temp          ; Save register W
      
      movf         STATUS          ; Save register STATUS
      movwf        status_temp
      
      movf         PCLATH          ; Save register PCLATH
      movwf        pclath_temp
      
      banksel      CCPR1L
      btfss        DARK            ; Tests push-button "DARK"
      decf         CCPR1L          ; Push-button is pressed - decrement CCP1L by 1
      btfss        BRIGHT          ; Testing push-button "BRIGHT"
      incf         CCPR1L          ; Push-button is pressed - increment CCP1L by 1
      
      movf         pclath_temp,w   ; PCLATH is given its original content
      movwf        PCLATH
      movf         status_temp,w   ; STATUS is given its original content
      movwf        STATUS
      swapf        w_temp,f        ; W is given its original content
      swapf        w_temp,w
      
      banksel      PIR1            ; Selects bank containing PIR1
      bcf          PIR1,TMR1IF     ; Clears interrupt flag TMR1IF
      
      bsf          TMR1H,7         ; Accelerates timer TMR0 counting
      bsf          TMR1H,6         ;
      bsf          INTCON,GIE      ; Global interrupt enabled
      retfie                       ; Return from interrupt routine
      
;************************ MAIN PROGRAM **************************************

main                               ; Start of the main program
      banksel      ANSEL           ; Selects bank containing register ANSEL
      clrf         ANSEL           ; Clears registers ANSEL and ANSELH
      clrf         ANSELH          ; All pins are digital
      
      banksel      OPTION_REG      ; Selects bank containing register ANSEL
      bcf          OPTION_REG,7    ; Pull-up resistors enabled      
      bsf          WPUB,0          ; Pull-up resistors enabled
      bsf          WPUB,1          ; on port B pins 0 and 1
      
      banksel      TRISC           ; Selects bank containing register TRISC
      clrf         TRISC           ; All port C pins are configured as outputs
      
      banksel       T1CON          ; Selects bank containing register T1CON
      bcf           T1CON,TMR1CS   ; TMR1 operates as a timer
      bcf           T1CON,T1CKPS0  ; Prescaler rate is 1:8
      bcf           T1CON,T1CKPS1
      bsf           T1CON,TMR1ON   ; Activates timer TMR1
      
      banksel       PIE1           ; Selects bank containing register PIE1
      bsf           PIE1,TMR1IE    ; Interrupt TMR1 is enabled
      bsf           INTCON,PEIE    ; Peripheral modules interrupts are
                                   ; enabled
      bsf           INTCON,GIE     ; Global interrupt enabled
      
      movlw         B'11111101'    ; Prescaler TMR2 = 1:4
      banksel       T2CON
      movwf         T2CON
      movlw         B'11111111'    ; Number in register PR2
      banksel       PR2
      movwf         PR2
      
      banksel       CCP1CON
      movlw         B'00001100'    ; Bits to configure CCP1 module
      movwf         CCP1CON
loop
      goto          loop           ; Remain here
      end                          ; End of program