;;;;;;; P4 for QwikFlash board ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Generate a jitterfree 10 Hz square wave on CCP1 output using compare mode ; with extension. ; Use 10 MHz crystal and 2.5 MHz internal clock rate. ; ;;;;;;; Program hierarchy ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ;Mainline ; Initial ; ;HiPriISR (included just to show structure) ; ;LoPriISR ; CCP1handler ; TMR1handler ; ;;;;;;; Assembler directives ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; list P=PIC18F452, F=INHX32, C=160, N=0, ST=OFF, MM=OFF, R=DEC, X=ON #include P18F452.inc __CONFIG _CONFIG1H, _HS_OSC_1H ;HS oscillator __CONFIG _CONFIG2L, _PWRT_ON_2L & _BOR_ON_2L & _BORV_42_2L ;Reset __CONFIG _CONFIG2H, _WDT_OFF_2H ;Watchdog timer disabled __CONFIG _CONFIG3H, _CCP2MX_ON_3H ;CCP2 to RC1 (rather than to RB3) __CONFIG _CONFIG4L, _LVP_OFF_4L ;RB5 enabled for I/O errorlevel -311 ;Turn off message when 3-byte variable is loaded HalfPeriod equ 125000 ;Number of 0.4 us clock cycles in 0.05 seconds ;;;;;;; Variables ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; cblock 0x000 WREG_TEMP STATUS_TEMP TMR1X ;Eight-bit extension to TMR1 CCPR1X ;Eight-bit extension to CCPR1 DTIMEL ;Half-period value DTIMEH DTIMEX endc ;;;;;;; Macro definitions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MOVLF macro literal,dest movlw literal movwf dest endm ;;;;;;; Vectors ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; org 0x0000 ;Reset vector nop goto Mainline org 0x0008 ;High priority interrupt vector goto HiPriISR org 0x0018 ;Low priority interrupt vector goto LoPriISR ;;;;;;; Mainline program ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Mainline rcall Initial ;Initialize everything LOOP_ ENDLOOP_ ;;;;;;; Initial subroutine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; This subroutine performs all initializations of variables and registers. Initial MOVLF low HalfPeriod,DTIMEL ;Load DTIME with HalfPeriod MOVLF high HalfPeriod,DTIMEH MOVLF upper HalfPeriod,DTIMEX MOVLF B'11010000',TRISC ;Set I/O for PORTC MOVLF 0x81,T1CON ;Turn on TMR1 MOVLF B'00001000',CCP1CON ;Select compare mode bsf RCON,IPEN ;Enable priority levels bcf IPR1,TMR1IP ;Assign low priority to TMR1 interrupts bcf IPR1,CCP1IP ; and to CCP1 interrupts clrf TMR1X ;Make first 24-bit compare occur quickly MOVLF 2,CCPR1X bsf PIE1,CCP1IE ;Enable CCP1 interrupts bsf PIE1,TMR1IE ;Enable TMR1 interrupts bsf INTCON,GIEL ;Enable low-priority interrupts to CPU bsf INTCON,GIEH ;Enable all interrupts return ;;;;;;; HiPriISR interrupt service routine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; HiPriISR ;High-priority interrupt service routine ; ; retfie FAST ;Return and restore STATUS, WREG, and BSR ; from shadow registers ;;;;;;; LoPriISR interrupt service routine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LoPriISR ;Low-priority interrupt service routine movff STATUS,STATUS_TEMP ;Set aside STATUS and WREG movwf WREG_TEMP LOOP_ IF_ PIR1,CCP1IF == 1 rcall CCP1handler CONTINUE_ ENDIF_ IF_ PIR1,TMR1IF == 1 rcall TMR1handler CONTINUE_ ENDIF_ BREAK_ ENDLOOP_ movf WREG_TEMP,W ;Restore WREG and STATUS movff STATUS_TEMP,STATUS retfie ;Return from interrupt, reenabling GIEL CCP1handler IF_ PIR1,TMR1IF == 1 ;If Timer1's overflow flag is set IF_ CCPR1H,7 == 0 ; and compare had occurred after that incf TMR1X,F ; then increment TMR1 extension bcf PIR1,TMR1IF ; and clear flag ENDIF_ ENDIF_ movf TMR1X,W ;Check whether extensions are equal subwf CCPR1X,W IF_ .Z. btg CCP1CON,0 ;Toggle control bit movf DTIMEL,W ;and add half period to CCPR1 addwf CCPR1L,F movf DTIMEH,W addwfc CCPR1H,F movf DTIMEX,W addwfc CCPR1X,F ENDIF_ bcf PIR1,CCP1IF ;Clear flag return TMR1handler incf TMR1X,F ;Increment Timer1 extension bcf PIR1,TMR1IF ;Clear flag and return to polling routine return end