; ; PIC12F675 ; Gullwing Door Mirror Controller Ver 0.2 ; Programmed by DD ; 2005/12/18 ; ; Data Format ; +---------------+ ; | | |O|O|I|O|A|A| GPIO I:Input O:Output A:Analog Input ; +---------------+ ; Input Data ; GP3 => Open/Close Switch (Open:1, Close:0) ; AN0 => Motor Status of Driver's Door Mirror ; AN1 => Motor Status of Passenger's Door Mirror ; ; Output Data ; GP2 => Open/Close Signal 1:OPEN 0:CLOSE ; GP4 => Passenger's side ; GP5 => Driver's side ; ; 解説 ; GP2の出力によって、OPENかCLOSEかが決まる。 ; GP4が1のときは、助手席側のモーターが、GP2の出力によって決まった動作を行う。 ; GP2=0(CLOSE)のとき、モーターが動作中は、AN1が12/5=2.4V(2.0V以上)となる。 ; モーターがロックすると、AN1が2V以下となる。 ; GP2=1(OPEN)のとき、モーターが動作中は、AN1が0V(0.2V以下)となる。 ; モーターがロックすると、AN1が0.5V以上となる。 ; GP5もGP4と同様。 ; ; Function ; GP3(SW)をONにすると、ドアミラーがCLOSEする。 ; GP3(SW)をOFFにすると、ドアミラーがOPENする。 ; OPEN(CLOSE)中にSWを操作すると、OPEN(CLOSE)動作終了後、CLOSE(OPEN)動作に入る。 ; ドアミラーのOPEN(CLOSE)中はAN0,1を監視し、変化があればモーターを停止する。(最大8秒) ; ; ; Flow Chart ; (START): ; TRISIO = 00001011 (Output: GP5,GP4,GP2, Input:GP3,GP1,GP0) ; ANSEL=00010011 (GP4,GP2=Digital I/O AN1,AN0=Analog Input, OSC/8) ; (SLP): ; GP2=0, GP4=0, GP5=0 ; Read GP3 ; INTCON = 10001000 (Global Interrupt enable, Port change interrupt enable) ; Sleep z.z.z.... ; Go to START ; (INT0): ; If GPIF(INTCON0)=1 then ; Wait for 200ms ; GPIF(INTCON0)=0 ; if GP3=1 go to OPEN. ; else go to CLOSE. ; Go to SLP ; (OPEN): ; GP2=1, GP4=1, GP5=1 ; Wait for 300 msec ; counter=75 ; Flag0 = 00000011 ; Flag1 = 00000011 ; (OPEN1) Wait for 50 msec. ; ADCON0 = 00000100 (Select AN1) ; call READAN ; if (AN1>26(0.5V)) then ; if (Flag1 > 0) Flag1 = Flag1-1 ; if (Flag1 == 0) GP4=0 ; Wait for 50 msec. ; ADCON0 = 00000000 (Select AN0) ; call READAN ; if (AN0>26(0.5V)) then ; if (Flag0 > 0) Flag0 = Flag0-1 ; if (Flag0 ==0) GP5=0 ; conuter = counter-1 ; if ((Flag0>0 || Flag1>0) & counter>0) goto OPEN1 ; if GP3=0 go to CLOSE ; Go to SLP ; ; (CLOSE): ; GP2=0, GP4=1, GP5=1 ; Wait for 300 msec ; counter=75 ; Flag0 = 00000011 ; Flag1 = 00000011 ; (CLOSE1) Wait for 100 msec. ; ADCON0 = 00000100 (Select AN1) ; call READAN ; if (AN1<102(2V)) then ; if (Flag1 > 0) Flag1 = Flag1-1 ; if (Flag1 == 0) GP4=0 ; Wait for 50 msec. ; ADCON0 = 00000000 (Select AN0) ; call READAN ; if (AN0<102(2V)) then ; if (Flag0 > 0) Flag0 = Flag0-1 ; if (Flag0 ==0) GP5=0 ; conuter = counter-1 ; if ((Flag0>0 || Flag1>0) & counter>0) goto CLOSE1 ; if GP3=1 go to OPEN ; Go to SLP ; ; Functions ; (READAN) ; Clear ADIF ; ADCON0(bit1) GO/DONE = 1 ; (ADWAIT) ; if ADCON0(bit1) GO/DONE = 1 ; go to ADWAIT ; W=ADRESH ; RETURN list p=pic12F675 include "p12f675.inc" ; Defining constant MAXTIME EQU d'75' VOL05V EQU d'26' VOL2V EQU d'102' ; ; __FUSES _CPD_OFF & _CP_OFF & _BODEN_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT ; Configuration Code = 0xFFEA ; When burning PIC, the following configuration is necessary ; MCLR is OFF ; Code Protection(CP) is OFF ; Watch Dog Timer(WDT) is OFF ; Clock is Internal RC Oscillator cblock 0x20 ;Store variables above control registers wcnt1 ;Wait Counter1 (For 50ms Wait) wcnt2 ;Wait Counter2 (For 50ms Wait) waitcnt ;Wait Counter counter ;Time counter for waiting 7500msec Flag0 ;Flag for locking motor (3=>0) Flag1 ;Flag for locking motor (3=>0) endc org 0x00 ;Start of Code Space goto START org 0x04 ;Interrupu Vector goto INT0 ;========================================= ; Start Program (& Wake up from Sleep) ;========================================= START bsf STATUS,RP0 ;Set Bank1 movlw b'00001011' ;Output: GP5,GP4,GP2, Input:GP3,GP1,GP0 movwf TRISIO ;Set GPIO Input/Output movlw b'00001000' ;GP3 as Interrupt movwf IOC movlw b'10000000' ;Pull-up Disable movwf OPTION_REG movlw b'01100011' ;GP4,GP2=Digital I/O AN1,AN0=Analog Input, OSC/64 movwf ANSEL SLP bcf STATUS,RP0 ;Set Bank0 movlw b'00000000' ;GP5,4,2=0 movwf GPIO movf GPIO,W ;Read GPIO movlw b'00000000' ;A/D Converter OFF movwf ADCON0 movlw b'10001000' ;Global Interrupt enable, Port change interrupt enable movwf INTCON sleep goto START ; ; Seesaw SW Operated (Interrupt) ; INT0 btfss INTCON,GPIF ;if GPIF(INTCON0)=0 goto SLP ; go to SLP call wait50ms ;Wait for 200ms to prevent from chattering of SW call wait50ms call wait50ms call wait50ms bcf INTCON,GPIF ;GPIF=0 btfsc GPIO,GP3 ;If GP3=1 goto OPEN ; go to OPEN goto CLOSE ;else go to CLOSE ; ; Opening mirror operation ; OPEN movlw b'00110100' ;GP2=1, GP4=1, GP5=1 movwf GPIO call wait50ms ;Wait for 300ms call wait50ms call wait50ms call wait50ms call wait50ms call wait50ms movlw MAXTIME ;conuter=Maximun time (*100msec) movwf counter movlw d'2' movwf Flag0 ;Flag0=2 movwf Flag1 ;Flag1=2 OPEN1 movlw b'00000101' ;Select AN1 movwf ADCON0 call wait50ms call READAN sublw VOL05V ;if AN10 decf Flag1,F ; Decrement Flag1 movf Flag1,F btfsc STATUS,Z ;if Flag1=0 bcf GPIO,GP4 ; GP4=0 OPEN2 movlw b'00000001' ;Select AN0 movwf ADCON0 call wait50ms call READAN sublw VOL05V ;if AN00 decf Flag0,F ; Decrement Flag0 movf Flag0,F btfsc STATUS,Z ;if Flag0=0 bcf GPIO,GP5 ; GP5=0 ; OPEN3 decfsz counter,F ;counter=counter-1 goto OPEN4 ;if counter=0 go to OPEN4 goto OPEN5 OPEN4 movf Flag0,W ;W=Flag0 iorwf Flag1,W ;W=Flag0 or Flag1 btfss STATUS,Z ;If Flag0>0 || Flag1>0 then goto OPEN1 ; Go to OPEN1 OPEN5 btfss GPIO,GP3 ;If GP3=0 goto CLOSE ; go to CLOSE return ; ; Closing mirror operation ; CLOSE movlw b'00110000' ;GP2=0, GP4=1, GP5=1 movwf GPIO call wait50ms ;Wait for 300ms call wait50ms call wait50ms call wait50ms call wait50ms call wait50ms movlw MAXTIME ;conuter=Maximun time (*100msec) movwf counter movlw d'2' movwf Flag0 ;Flag0=2 movwf Flag1 ;Flag1=2 CLOSE1 movlw b'00000101' ;Select AN1 movwf ADCON0 call wait50ms call READAN sublw VOL2V ;if AN1>VOL2V then btfss STATUS,C goto CLOSE2 ; go to CLOSE2 movf Flag1,F btfss STATUS,Z ;If Flag1>0 decf Flag1,F ; Decrement Flag1 movf Flag1,F btfsc STATUS,Z ;if Flag1=0 bcf GPIO,GP4 ; GP4=0 CLOSE2 movlw b'00000001' ;Select AN0 movwf ADCON0 call wait50ms call READAN sublw VOL2V ;if AN0>VOL2V then btfss STATUS,C goto CLOSE3 ; go to CLOSE3 movf Flag0,F btfss STATUS,Z ;If Flag0>0 decf Flag0,F ; Decrement Flag0 movf Flag0,F btfsc STATUS,Z ;if Flag0=0 bcf GPIO,GP5 ; GP5=0 ; CLOSE3 decfsz counter,F ;counter=counter-1 goto CLOSE4 ;if counter>0 go to CLOSE4 goto CLOSE5 CLOSE4 movf Flag0,W ;W=Flag0 iorwf Flag1,W ;W=Flag0 or Flag1 btfss STATUS,Z ;If Flag0>0 || Flag1>0 then goto CLOSE1 ; Go to CLOSE1 CLOSE5 btfsc GPIO,GP3 ;If GP3=1 goto OPEN ; go to OPEN return ;Subroutine ;================================ ; Read A/D ;================================ READAN bcf PIR1,ADIF bsf ADCON0,GO_DONE ;GO/DONE=1 ADWAIT btfsc ADCON0,GO_DONE ;If GO/DONE=1 goto ADWAIT ; go to ADWAIT movf ADRESH,W ;W=ADRESH return ;================================ ; Wait for 50ms ;================================ wait50ms movlw d'65' ;*65 movwf wcnt2 waitlp2 clrf wcnt1 waitlp1 decfsz wcnt1,F goto waitlp1 decfsz wcnt2,F goto waitlp2 return end