INCLUDE P16F628.INC radix decimal ; GLOBAL VARIABLES tmr1comparel equ 0x70 ; compare this 24 bit value with timer1 + timer1msb tmr1comparem equ 0x71 tmr1compareh equ 0x72 TMR1MSB equ 0x73 ; turns timer1 into a 24 bit counter cpfl equ 0x74 ; counts per frame, 16 bit value cpfh equ 0x75 framecounter equ 0x76 ; frame counter which indicates which frame is currently displayed wreg equ 0x7f ; when interrupt is called, store status and wreg sreg equ 0x7e ; PROGRAM COSNTANTS trisasetup equ b'11111111' ; writes to TRISA trisbsetup equ b'00000000' ; writes to TRISB tmr1setup equ b'00000000' ; writes to T1CON comparatorsetup equ b'00110010' ; writes to CMCON vrefsetup equ b'11001011' ; writes to VRCON comparesetup equ b'00001010' ; writes to CCP1CON interruptsetup equ b'01000000' ; writes to INTCON peripheralsetup equ b'01000101' ; writes to PIE1 comparatormask equ b'01000000' ; mask for compartor connected to trigger tmr1start equ 0x0b ; timer 1 load value, accounts for time timer1 is disabled framecountermsb equ 0x07 ; most significant bit of frame counter ; PROGRAM STARTS HERE org 0x00 goto start org 0x04 goto isrh isrh: bcf INTCON,GIE ; disable all interrupts movwf wreg ; store interrupted wreg and status movf STATUS,w movwf sreg btfsc PIR1,CMIF ; test for a comparator change interrupt goto comparatorisr btfsc PIR1,CCP1IF ; test for a timer 1 compare interrupt goto compareisr btfsc PIR1,TMR1IF ; test for a timer 1 overflow interrupt goto tmr1overflowisr movf sreg,w ; restore wreg and status register movwf STATUS movf wreg,w call ereset bsf INTCON,GIE ; re-enable interrupts, should never get to this point retfie ; return from interrupt call. comparatorisr: banksel PIR1 ; clear the interrupt flag bcf PIR1,CMIF movlw comparatormask ; check to see we have a rising edge on the proper comparator andwf CMCON,w ; mask CMCON with comparator mask. if the result is not zero btfsc STATUS,Z ; then we have some positive something, we need to see if it is a rising edge goto exit ; xorwf comparatorlast,w ; btfsc STATUS,Z ; if the XOR results in a zero, then the state of the bit is the same ; goto exit ; this means a rising edge has occured banksel T1CON bcf T1CON,TMR1ON ; disable timer1 movf TMR1H,w ; grab and store upper 16 bits of 24 bit timer1 movwf cpfl ; and store into cpf (essentialy divide timer1 by 256) movf TMR1MSB,w movwf cpfh movlw tmr1start ; reset the timer movwf TMR1L clrf TMR1H bsf T1CON,TMR1ON ; re-enable timer1 clrf TMR1MSB ; clear the upper 8 bits of 24 bit timer1 clrf framecounter ; reset the frame counter clrf tmr1comparel ; reset timer1 compare value clrf tmr1comparem clrf tmr1compareh call loadanddisplay banksel CCPR1L ; load the compare register and update timer1comparem movf cpfl,w movwf CCPR1L movwf tmr1comparel movf cpfh,w movwf CCPR1H movwf tmr1comparem banksel PIR1 clrf PIR1 ; clear all pending interrupts banksel PIE1 ; re-enable comapre interrupt if it was disabled by "over frame count" bsf PIE1,CCP1IE goto exit compareisr: banksel PIR1 bcf PIR1,CCP1IF ; clear the interrupt flag movf tmr1compareh,w subwf TMR1MSB,w ; see if upper 8 bits match btfss STATUS,Z ; if the result is zero, the values match goto exit ; results dont match, come back next time incfsz framecounter,f ; next frame, increment frame counter goto framesok banksel PIE1 bcf PIE1,CCP1IE ; disable the compare interrupt, we are done displaying goto exit framesok: call loadanddisplay movf cpfl,w ; 24 bit + 16 bit -> 24 bit (add CPF to timer1compare) addwf tmr1comparel,f movlw 1 btfsc STATUS,C addwf tmr1comparem,f btfsc STATUS,C addwf tmr1compareh,f movf cpfh,w addwf tmr1comparem,f movlw 1 btfsc STATUS,C addwf tmr1compareh,f banksel CCPR1L ; load the compare register with new compare value movf tmr1comparel,w movwf CCPR1L movf tmr1comparem,w movwf CCPR1H goto exit tmr1overflowisr: banksel PIR1 bcf PIR1,TMR1IF ; clear interrupt flag incf TMR1MSB,f ; increment upper 8 bits of timer 1 goto exit exit: movf sreg,w ; restore wreg and status register movwf STATUS movf wreg,w bsf INTCON,GIE ; re-enable interrupts, should never get to this point retfie loadanddisplay: ;bcf framecounter,framecountermsb ; only necessary beacuse 16f628 has only 128 bytes eeprom banksel EEADR ; movf framecounter,w ; read from the eeprom bcf STATUS,C rrf framecounter,W ; divide frame counter by 2 (only 128 bytes of eeprom in 16f628) movwf EEADR bsf EECON1,RD ; initaite the read movf EEDATA,W ; get the data banksel PORTB ; display the data on port B movwf PORTB return start: clrf tmr1comparel clrf tmr1comparem clrf tmr1compareh clrf TMR1MSB clrf cpfl clrf cpfh clrf framecounter banksel TRISA ; initializ direction registers for ports A and B movlw trisasetup movwf TRISA movlw trisbsetup movwf TRISB banksel T1CON movlw tmr1setup ; setup timer 1 movwf T1CON movlw comparatorsetup ; prepare comparator movwf CMCON banksel PIR1 bcf PIR1,CMIF banksel VRCON ; prepare refrence voltage module movlw vrefsetup movwf VRCON banksel CCP1CON movlw comparesetup ; prepare the ccp module for compare movwf CCP1CON movlw interruptsetup ; prepare the interrupt register movwf INTCON banksel PIE1 movlw peripheralsetup ; prepare peripheral interrupts movwf PIE1 banksel T1CON bsf T1CON,TMR1ON ; enable timer 1 bsf INTCON,GIE ; enable global interrupts loop: ; loop forever goto loop ereset: clrf tmr1comparel clrf tmr1comparem clrf tmr1compareh clrf TMR1MSB clrf cpfl clrf cpfh clrf framecounter banksel TRISA ; initialize direction registers for ports A and B movlw trisasetup movwf TRISA movlw trisbsetup movwf TRISB banksel T1CON movlw tmr1setup ; setup timer 1 movwf T1CON movlw comparatorsetup ; prepare comparator movwf CMCON banksel PIR1 bcf PIR1,CMIF banksel VRCON ; prepare refrence voltage module movlw vrefsetup movwf VRCON banksel CCP1CON movlw comparesetup ; prepare the ccp module for compare movwf CCP1CON movlw interruptsetup ; prepare the interrupt register movwf INTCON banksel PIE1 movlw peripheralsetup ; prepare peripheral interrupts movwf PIE1 banksel T1CON bsf T1CON,TMR1ON ; enable timer 1 return ORG 2100H ; loads eeprom with display data DE 0x62,0x91,0x91,0x91,0x4e ; S DE 0,0,0,0 DE 0x7f,0xc0,0xf8,0xc0,0x7f ; W DE 0,0,0,0,0,0,0 DE 0,0,0,0,0,0,0,0;DE 0x04,0x10,0x3a,0x10,0x04 ; paw DE 0,0,0,0,0,0,0 DE 0x7e,0x81,0x81,0x89,0x4e ; G DE 0,0,0,0 DE 0x7e,0x81,0x81,0x81,0x7e ; O DE 0,0,0,0,0,0,0 DE 0x7e,0x81,0x81,0x81,0x42 ; C DE 0,0,0,0 DE 0x7e,0x81,0x81,0x81,0x7e ; O DE 0,0,0,0 DE 0xfe,0x01,0x01,0x01,0xfe ; U DE 0,0,0,0 DE 0x7e,0x81,0x81,0x89,0x4e ; G DE 0,0,0,0 DE 0x62,0x91,0x91,0x91,0x4e ; S DE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DE 0x7f,0x80,0x80,0x80,0x7f ; U DE 0,0,0,0 end