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.
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