;******************************** ; PIC16F648A ; 2011-05-13 ; Author: Naoki ;******************************** LIST P=pic16f648a INCLUDE p16f648a.inc __CONFIG _BOREN_OFF & _CP_OFF & _WDT_OFF & _LVP_OFF & _MCLRE_OFF & _XT_OSC & _PWRTE_ON ;***** Variables **************** CONSTANT T1AL = 0x74, T1AH = 0xe5 CONSTANT T1LL = 0x76, T1LH = 0xe5 CONSTANT LEAPC = 0x0D CBLOCK 20h lcount wSave sSave cnt stat ENDC s_stat EQU 0 ;motor stat s_dire EQU 1 ;direction ;********* Reset Vectorl ******** ORG H'0000' GOTO MAIN ;********* Interrupt Vector ***** ORG H'0004' BTFSC PIR1,TMR1IF ;timer1 interrupt GOTO t1intr ; occurred BTFSC INTCON,RBIF ;portB Int-on-chg GOTO keyService BCF INTCON,T0IE ;timer0 disable interrupt RETFIE ;******************************** ;Timer1 expired ;******************************** t1intr MOVWF wSave ;save Wreg SWAPF STATUS,W ; MOVWF sSave ;save STATUS BCF PIR1,TMR1IF ;clear TMR1 Interrupt Flag DECFSZ lcount,F GOTO t1intr_1 MOVLW LEAPC MOVWF lcount MOVLW T1LL ;leap timer1 value Low MOVWF TMR1L ; MOVLW T1LH ;leap timer1 value High MOVWF TMR1H ; GOTO t1intr_2 t1intr_1 MOVLW T1AL ;ave timer1 value Low MOVWF TMR1L ; MOVLW T1AH ;ave timer1 value High MOVWF TMR1H ; t1intr_2 CALL step_control SWAPF sSave,W ; MOVWF STATUS ;load STATUS SWAPF wSave,F ; SWAPF wSave,W ;load Wreg RETFIE ;******************************** ;PortB Interrupt-on-change ;******************************** keyService MOVWF wSave ;save Wreg SWAPF STATUS,W ; MOVWF sSave ;save STATUS BCF INTCON,RBIE ;disable PortB interrupt COMF PORTB,W ;read PortB BCF INTCON,RBIF ;Clear PortB interrupt flag CALL delay16 ;do de-bounce CALL sw1_on ;motor control keyRelease CALL delay16 ;de-bounce COMF PORTB,W ;read PortB Again ANDLW B'00100000' ; BTFSC STATUS,Z ;key still pressed? GOTO key_end ;no key-released GOTO keyRelease key_end BCF INTCON,RBIF ;clear PortB interrupt flag BSF INTCON,RBIE ;enable PortB interrupt SWAPF sSave,W ; MOVWF STATUS ;load STATUS SWAPF wSave,F ; SWAPF wSave,W ;load Wreg RETFIE ;******************************** ;Initialize PortA/B, Timer0, Timer1 ;******************************** init CLRF PORTA ;initialize PortA CLRF PORTB ;initialize PortB banksel TRISA ;select bank1 MOVLW B'11100000' ;RB0-4:output,RB5-7:input MOVWF TRISB ; MOVLW 0x00 ;prescaler:256, PortB Pull-Up enable MOVWF OPTION_REG ; CLRF PIE1 ;disable Perif interrupt BSF PCON,OSCF ;Oscillator 4MHz banksel TMR0 ;select bank0 CLRF INTCON ;disable all interrupts CLRF T1CON ;stop timer1 CLRF PIR1 ;timer1 interrupt flag off MOVLW T1AL ;ave timer1 value Low MOVWF TMR1L ; MOVLW T1AH ;ave timer1 value High MOVWF TMR1H ; MOVLW LEAPC ;leap counter MOVWF lcount ; CLRF cnt CLRF stat banksel PIE1 BSF PIE1,TMR1IE ;timer1 interrupt enable banksel INTCON BCF INTCON,RBIF ;portB clear flag BSF INTCON,RBIE ;portB enable interrupt BSF INTCON,PEIE ;peripheral interrupt enable BSF INTCON,GIE ;global interrupt enable RETURN ;******************************** ;Main routine ;******************************** MAIN CALL init main_loop NOP GOTO main_loop ;******************************** ;output motor control data ;******************************** step_control MOVF cnt,W SUBLW 0x03 BTFSC STATUS,Z GOTO set0 INCF cnt,F GOTO incd set0 CLRF cnt incd BTFSC stat,s_dire GOTO rotB MOVFW cnt CALL tableF GOTO step_end rotB MOVFW cnt CALL tableB step_end MOVWF PORTB RETURN ;******************************** ;Read input ;******************************** sw1_on BTFSS stat,s_stat GOTO start_motor stop_motor BTFSC stat,s_dire GOTO ind_f MOVLW B'00010000' MOVWF PORTB GOTO done ind_f CLRF PORTB done BCF T1CON,TMR1ON ;timer1 stop BCF PIR1,TMR1IF ;clear timer1 interrupt flag GOTO sw1_end start_motor BSF T1CON,TMR1ON ;timer1 start sw1_end INCF stat,F RETURN ;******************************** ;Wait routine ;******************************** delay16 banksel OPTION_REG MOVLW B'00000101' MOVWF OPTION_REG ;prescaler 1:64 banksel TMR0 CLRF TMR0 BCF INTCON,T0IF ;clear timer0 interrupt flag BSF INTCON,T0IE ;enable timer0 interrupt checkAgain BTFSS INTCON,T0IF ;timer0 overflowed? GOTO checkAgain ;no check again BCF INTCON,T0IE ;else clear mask BCF INTCON,T0IF ;clear timer0 interrupt flag RETURN tableF ADDWF PCL,F RETLW B'00000001' RETLW B'00001000' RETLW B'00000100' RETLW B'00000010' tableB ADDWF PCL,F RETLW B'00010001' RETLW B'00010010' RETLW B'00010100' RETLW B'00011000' END |