; list p=PIC12F675 ; ; Copyright 2003 Sugihara Toshio. ; All rights reserved. ; #include ; PIC12F675 ; Clock=32768Hz 8192 orders/s ; WDT=on, PowerUpTimer=on ; Protect=off, Oscllator=LP ; GP3=Digital IO, BrownOutDetect=off nextadr equ H'20' ;next eeadr to write adrnow equ H'2c' ;eeadr just to write timeh equ H'21' ;higher byte of timer timel equ H'22' ;lower byte of timer timec equ H'23' ;bit0 is 1 if time is changed ring equ H'24' ;bit0 is 1 if just after ringing swnow equ H'25' ;status of door SW now (0=on) swold equ H'26' ;previous status of door SW cfgmem equ H'27' ;bit0=up bit1=down (if 1 ringing is on) loopnum equ H'28' ;Used in Waitxms routine timesec equ H'29' ;Used in Susumu for calculating seconds num0 equ H'2a' ;Used in Status counting routine num1 equ H'2b' ;Used in Status counting routine tone equ H'2d' ;tone timer for ringing admy equ H'2e' ;Dummu for frequency A bcount equ H'2f' ;Counter for ringing ;--Program start ;Always come to H'00' from POR or RESET or WdtTimeOut org H'00' ;bank 0 is selected clrwdt ;Stop interrupt clrf INTCON ;I/O setup movlw B'00000001' movwf GPIO movlw H'07' ;Set GP2,GP1,GP0 to movwf CMCON ;Digital I/O bsf STATUS,RP0 ;Select Bank 1 clrf ANSEL ;Select GP3-0 to Digital I/O movlw H'08' ;Set GP0-GP2 into outputs movwf TRISIO ;GP3 is only input movlw B'11010110' ;prescaler is for TMR0 and 128:1 movwf OPTION_REG ;Pull up is globally off clrf WPU ;Pull up is off by every pin bcf STATUS,RP0 ;Select Bank 0 movlw B'00000001' movwf GPIO ;Set I/O stop mode ;Set tmr0 as zero clrf TMR0 ;TMR0 does overflow every 4 seconds bcf INTCON,2 ;clear TMR0 overflow bit ;Set initial values to variables clrf nextadr clrf timeh clrf timel movlw H'01' movwf timec ;treat as time is changed movwf ring ;treat as just after ringing clrf swnow clrf swold clrf timesec ;;;;;;;;;;;;;;;;;;;;;This is important setting for this program;;;; movlw B'00000011' ;ring set up for bit0=up bit1=down movwf cfgmem ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; InitialWait ;Wait for 1 sec for initial wait movlw D'250' call Waitxms movlw D'250' call Waitxms movlw D'250' call Waitxms movlw D'250' call Waitxms ;search next writing address SearchAdr clrwdt btfsc nextadr,7 ;if address >= 128? goto SearchNotFound ;Yes, set address 0 as nextadr and write ;No. movf nextadr,W ;Read value call EERead ;from EEPROM xorlw H'ff' btfsc STATUS,Z ;Value is H'ff'? goto Mainloop ;Yes. Search is done. ;No. Keep searching incf nextadr,F ;nextadr += 2 incf nextadr,F goto SearchAdr ;Keep searching. SearchNotFound clrf nextadr ;nextadr is zero bsf STATUS,RP0 ;Select Bank 1 clrf EEADR ;address 0 movlw H'ff' ;data H'ff' call EEWrite ;Write data to EEPROM ;Select Bank 0 (in EEWrite routine) Mainloop ;Check current status of Door SW movf swnow,W ;Save sw value movwf swold ;to old value clrf num0 ;Reset number of clrf num1 ;status found Checklp1 clrwdt btfss GPIO,3 goto Checklp2 incf num1,F Checklp3 btfsc num0,4 goto CheckZero btfsc num1,4 goto CheckOne goto Checklp1 Checklp2 incf num0,F goto Checklp3 ;swnow becomes 0 CheckZero clrf swnow ;swnow = 0 btfss cfgmem,1 ;is down mode enabled? goto NotBeep ;No. No beep ;Yes. goto CheckBeep ;swnow becomes 1 CheckOne movlw H'01' movwf swnow ;swnow = 1 btfss cfgmem,0 ;is up mode enabled? goto NotBeep ;No. No beep ;Yes. goto CheckBeep ;Decide to beep the speaker CheckBeep movf swnow,W xorwf swold,W btfsc STATUS,Z ;If swnow==swold? goto NotBeep ;Yes. No changing -> Not Beep ;No. change occured. btfsc ring,0 ;Is it just after ringing? goto NotBeep ;Yes. Not Beep ;No. It's time to beep. ;Beep the speaker Beep clrwdt btfss timec,0 ;Is time changed? goto BeepGo ;No. Just beep. ;Yes. Record the time ;Calculate further next address movf nextadr,W ;Copy nextadr movwf adrnow ;into adrnow addlw D'2' movwf nextadr ;nextadr += 2 btfsc nextadr,7 ;nextadr >= 128? clrf nextadr ;Yes. nextadr = 0; ;No. Do nothing ;Write H'ff' to nextadr movf nextadr,W bsf STATUS,RP0 ;Select Bank 1 movwf EEADR ;Set nextadr into EEADR movlw H'ff' ;Write H'ff' into call EEWrite ;nextadr ;Write current timeh into adrnow movf adrnow,W bsf STATUS,RP0 ;Select Bank 1 movwf EEADR bcf STATUS,RP0 ;Select Bank 0 movf timeh,W call EEWrite ;Write current timel into adrnow+1 incf adrnow,W bsf STATUS,RP0 ;Select Bank 1 movwf EEADR bcf STATUS,RP0 ;Select Bank 0 movf timel,W call EEWrite ;clear time changed flag clrf timec BeepGo movlw D'2' ;Beep is 2 times movwf bcount BeepGoLoop ;Charge C for 2ms clrf GPIO movlw D'2' call Waitxms bsf GPIO,0 ;Ring D movlw D'206' ;D is for 206 times movwf tone RingD ;A ch mode bcf GPIO,2 bsf GPIO,1 goto RingD2 RingD2 goto RingD3 RingD3 nop ;B ch mode bcf GPIO,1 bsf GPIO,2 clrwdt decf tone,F btfss STATUS,Z ;Is D done? goto RingD ;No. keep ringing D ;Yes. ;Charge C for 2ms clrf GPIO movlw D'2' call Waitxms clrf admy ;clear admy adjuster bsf GPIO,0 ;Ring A ;First, ringing A for 256 times movlw D'0' ;A is for 468 times movwf tone RingA ;Ach mode (9 or 10 cycles) bcf GPIO,2 bsf GPIO,1 incf admy,F btfss admy,0 goto RingA2 RingA2 clrwdt nop goto RingA4 RingA4 ;Bch mode(9 cycles) bcf GPIO,1 bsf GPIO,2 nop nop nop movlw D'212' decfsz tone,F ;Is A done? goto RingA ;No. keep ringing A ;Yes. ;Keep ringing A for 212 times movwf tone RingAA ;Ach mode (9 or 10 cycles) bcf GPIO,2 bsf GPIO,1 incf admy,F btfss admy,0 goto RingAA2 RingAA2 clrwdt nop goto RingAA4 RingAA4 ;Bch mode(9 cycles) bcf GPIO,1 bsf GPIO,2 nop nop nop nop decfsz tone,F ;Is AA done? goto RingAA ;No. keep ringing AA ;Yes. decfsz bcount,F ;Ringing goes on 2 times goto BeepGoLoop ;Stop all sound movlw B'00000001' movwf GPIO ;Set it is just after ringing. bsf ring,0 ;Wait for 2 seconds movlw D'250' call Waitxms ;1 movlw D'250' call Waitxms ;2 movlw D'250' call Waitxms ;3 movlw D'250' call Waitxms ;4 movlw D'250' call Waitxms ;5 movlw D'250' call Waitxms ;6 movlw D'250' call Waitxms ;7 movlw D'250' call Waitxms ;8 goto AfterRing ;Ringing is done NotBeep clrf ring ;It's not just after ringing. AfterRing clrwdt ;Init I/O port again. bcf STATUS,RP0 ;Select Bank 0 movlw H'07' ;Set GP2,GP1,GP0 to movwf CMCON ;Digital I/O bsf STATUS,RP0 ;Select Bank 1 clrf ANSEL ;Select GP3-0 to Digital I/O movlw H'08' ;Set GP0-GP2 into outputs movwf TRISIO ;GP3 is only input clrf WPU ;Pull up is off by every pin bcf STATUS,RP0 ;Select Bank 0 movlw B'00000001' movwf GPIO ;Set I/O stop mode ;Check clock btfsc INTCON,2 ;if TMR0 is overflow call Susumu ;Yes. Susumu will be called ;No. Do nothing goto Mainloop ;Go back to mainloop ;Wait for about Wreg * 0.9765625 mili seconds ;clrwdt and TMR0 overflow are considered. Waitxms movwf loopnum ;Save time to wait to memory Waitxmsnext nop clrwdt btfsc INTCON,2 ;if TMR0 is overflow call Susumu ;Yes. Susumu will be called ;No. Do nothing decf loopnum,F ;decrement loop number btfss STATUS,Z ;loop number becomes 0 ? goto Waitxmsnext ;No. keep waiting ;Yes. Waiting is done. return ;Increment clock Susumu bcf INTCON,2 ;Clear overflow flag incf timesec,F ;timesec * 4 = second movf timesec,W sublw D'15' ;W = 15 - timesec btfss STATUS,Z ;If timesec becomes 15? return ;No. minutes is not changed and return. ;Yes. minutes should be incremented. bsf timec,0 ;Time is changed(minutes order) clrf timesec ;reset seconds incf timel,F ;increment minutes btfss STATUS,Z ;timel becomes 0? return ;No. return. ;Yes. increment timeh incf timeh,F incf timeh,W btfss STATUS,Z ;timeh becomes H'ff'? return ;No. return. ;Yes. clrf timeh ;timeh becomes 0 return ;Before: Address is in W register ;After: Read value is in W register EERead bsf STATUS,RP0 ;Select Bank 1 movwf EEADR ;Write address bsf EECON1,RD ;Read data from EEPROM movf EEDATA,W ;Set read value to W register bcf STATUS,RP0 ;Select Bank 0 return ;Value to write is already in W register EEWriteError ;Before: Address is in EEADR ; Wrinting value is in W register ;After: Wrote success if return. ; EEADR is not changed ; value is in EEDATA EEWrite bsf STATUS,RP0 ;Select Bank 1 movwf EEDATA ;Write Data into EEDATA bsf EECON1,WREN ;Allow write cycle movlw H'55' movwf EECON2 movlw H'AA' movwf EECON2 bsf EECON1,WR ;Wait for writing EEWriteWait clrwdt btfsc EECON1,WR ;Writing is done? goto EEWriteWait ;No, keep waiting. ;Yes, writing is done. bcf EECON1,WREN ;Disable write cycle ;Read data from EEPROM to verify movf EEDATA,W ;Read value to write bsf EECON1,RD ;Do read cycle xorwf EEDATA,F ;EEDATA should be zero if values are the same btfss STATUS,Z ;Write succeed? goto EEWriteError ;No. Error occured. ;Yes. movwf EEDATA ;Write wrote value to EEDATA bcf STATUS,RP0 ;Select Bank 0 return end