PROGRAM O ;************************************ *** ; written by: John Morton * ; date: 10/01/05 * ; version 1.0 * ; file saved as phonecard.asm * ; for P12F675 * ; clock frequency: internal 4MHz * ; *************************************** ; Program Description: A smart card for a phone box list P=12F675 include "c:\pic\p12f675.inc" ;============== ; Declarations: W_temp equ 20h STATUS_temp equ 21h temp equ 22h Mark125 equ 23h Post125 equ 24h Post15 equ 25h org 0 ; first instruction to be executed goto Start ; org 4 ; interrupt service routine goto isr ; ;=========== ; Subroutines: Init bsf STATUS, RP0 ; goes to Bank 1 call 3FFh ; calls calibration address movwf OSCCAL ; moves w. reg into OSCCAL movlw b'111110' ; all inputs except GP0 movwf TRISIO ; clrf WPU ; weak pull-ups disabled movlw b'11000111' ; sets up timer and some pin movwf OPTION_REG ; settings clrf PIE1 ; turns off peripheral ints. clrf IOC ; disables GPIO change int. clrf VRCON ; turns off comparator V. ref. clrf ANSEL ; makes GP0:3 digital I/O pins bcf STATUS, RP0 ; back to Bank 0 clrf GPIO ; resets input/output port movlw b'00010000' ; sets up interrupts movwf INTCON ; movlw b'00000111' ; turns off comparator movwf CMCON ; clrf T1CON ; turns off TMR1 clrf ADCON0 ; turns off A to D conv. movlw d'125' ; sets up postscalers movwf Post125 ; movlw d'15' ; movwf Post15 ; retfie ; returns from Init isr movwf W_temp ; stores w.reg in temp register movfw STATUS ; stores STATUS in temp movwf STATUS_temp ; register bcf INTCON, 1 ; resets INT interrupt flag bcf STATUS, RP0 ; makes sure weÕre in Bank 0 movfw GPIO ; reads value of GPIO movwf temp ; rrf temp, f ; rotates right three timesÉ rrf temp, f ; rrf temp, w ; Éleaving result in w. reg andlw b'000111' ; masks bits 3-5 call CardValue ; converts code into minutes bsf STATUS, RP0 ; goes to Bank 1 movwf EEDATA ; stores minutes in EEDATA clrf EEADR ; selects EEPROM address 00h bsf EECON1, 2 ; enables a write operation movlw 0x55 ; now follows the Ôsafe movwf EECON2 ; combinationÕ movlw 0xAA ; movwf EECON2 ; bsf EECON1, 1 ; starts the write operation EELoop btfsc EECON1, 1 ; has write operation finished? goto EELoop ; no, still high, so keeps looping movfw STATUS_temp ; restores STATUS register to movwf STATUS ; original value swapf W_temp, f ; restores working register to swapf W_temp, w ; original value retfie ; returns, enabling GIE CardValue addwf PCL, f ; returns with new number of retlw d'2' ; minutes for the card retlw d'5' ; retlw d'10' ; retlw d'20' ; retlw d'40' ; retlw d'60' ; one hour retlw d'120' ; two hours retlw 0 ; (erases card) ;============ ; Program Start Start call Init ; initialisation routine Main bsf STATUS, RP0 ; selects Bank 1 clrf EEADR ; selects EEPROM address 00h bsf EECON1, 0 ; initiates an EEPROM read movfw EEDATA ; reads EEDATA bcf STATUS, RP0 ; selects Bank 0 btfss STATUS, Z ; is it 0? goto Active ; no, so goes to Active bcf GPIO, 0 ; turns off GP0 sleep ; goes to sleep nop ; goto Main ; loops back to Main Active bsf GPIO, 0 ; turns on GP0 btfss GPIO, 1 ; is a call in progress? goto Active ; no, so keeps waiting movfw Mark125 ; has one minute passed? subwf TMR0, w ; btfss STATUS, Z ; goto Active ; no, so keeps looping movlw d'125' ; addwf Mark125 ; decfsz Post125 ; goto Active ; movlw d'125' ; movwf Post125 ; decfsz Post15 ; goto Active ; movlw d'15' ; one minute has passed, so movwf Post15 ; resets final postscaler bsf STATUS, RP0 ; goes to Bank 1 clrf EEADR ; selects EEPROM address 00h bsf EECON1, 0 ; reads EEPROM address 00h decf EEDATA ; subtracts 1 minute from card bsf EECON1, 2 ; enables a write operation bcf INTCON, 7 ; disables global interrupts movlw 0x55 ; now follows the Ôsafe movwf EECON2 ; combinationÕ movlw 0xAA ; movwf EECON2 ; bsf EECON1, 1 ; starts the write operation EELoop btfsc EECON1, 1 ; has write operation finished? goto EELoop ; no, still high, so keeps looping bcf STATUS, RP0 ; back to Bank 0 bsf INTCON, 7 ; enables global interrupts goto Main ; loops back to start END