BACK
;==================================================
;
; This file is a basic code for Linbot.
; Linbot is a intelegent line tracer.
; Linbot's CPU is a PIC16F876.
;
;==================================================
;
; Filename: LINBOT.ASM
; Date: Sept,2001
; File Version: 1.0
;
; Author: James Jeong
; Company: Microrobot(www.microrobot.com)
;
;===============================================
LIST P=16F876
#INCLUDE <P16F876.INC>
;; Macros.
BANK0 MACRO
BCF STATUS,RP1
BCF STATUS,RP0
ENDM
BANK1 MACRO
BCF STATUS,RP1
BSF STATUS,RP0
ENDM
BANK2 MACRO
BSF STATUS,RP1
BCF STATUS,RP0
ENDM
BANK3 MACRO
BSF STATUS,RP1
BSF STATUS,RP0
ENDM
TURN_ON MACRO ARG1,ARG2
BCF ARG1,ARG2 ; Bit Clear.
ENDM
TURN_OFF MACRO ARG1,ARG2
BSF ARG1,ARG2 ; Bit Set.
ENDM
;;; Tempolary register defination.
START_GPR EQU 0x20 ; Start of the General Purpose Register.
DELAY_CNT1 EQU START_GPR+0
DELAY_CNT2 EQU START_GPR+1
DELAY_STACK1 EQU START_GPR+2
DELAY_STACK2 EQU START_GPR+3
TEMP_STACK1 EQU START_GPR+4
TEMP_STACK2 EQU START_GPR+5
TEMP_STACK3 EQU START_GPR+6
;;; Register defination.
L_AD_REG EQU START_GPR+8
C_AD_REG EQU START_GPR+9
R_AD_REG EQU START_GPR+10
F_AD_REG EQU START_GPR+11
VR_AD_REG EQU START_GPR+12
FRONT_REF_REG EQU START_GPR+13
SENSOR_REG EQU START_GPR+14
HISTORY_REG EQU START_GPR+15
;;; Each bit defination of the register.
#DEFINE PRE_OP_FLAG HISTORY_REG,0 ; Previous Operation.
#DEFINE LEFT_FLAG SENSOR_REG,0 ; AD
#DEFINE CENTER_FLAG SENSOR_REG,1 ; AD
#DEFINE RIGHT_FLAG SENSOR_REG,2 ; AD
#DEFINE FRONT_FLAG SENSOR_REG,3 ; AD
;;; Port pin defination.
#DEFINE LEFT_AD_IN PORTA,0 ; AN0
#DEFINE CENTER_AD_IN PORTA,1 ; AN1
#DEFINE RIGHT_AD_IN PORTA,2 ; AN2
#DEFINE FRONT_AD_IN PORTA,3 ; AN3
#DEFINE BUZZER_OUT PORTA,4 ; BUZZER
#DEFINE REF_AD_IN PORTA,5 ; REFRENCE VOLTAGE AN4
#DEFINE PUSH_SW_IN PORTB,0 ; PUSH SWITCH
#DEFINE JUMPER_SW_IN PORTB,1 ; JUMPER SWITCH
#DEFINE FRONT_IR_OUT PORTB,2 ; INFRARED LED
#DEFINE RIGHT_IR_OUT PORTB,3 ; INFRARED LED
#DEFINE CENTER_IR_OUT PORTB,4 ; INFRARED LED
#DEFINE LEFT_IR_OUT PORTB,5 ; INFRARED LED
#DEFINE RM_IN2_OUT PORTC,0 ; RIGHT MOTOR IN2 (RIGHT MOTOR CONTROLS
LEFT WHEEL.)
#DEFINE RM_IN1_OUT PORTC,1 ; RIGHT MOTOR IN1
#DEFINE LM_IN1_OUT PORTC,2 ; LEFT MOTOR IN1 (LEFT MOTOR CONTROLS RIGHT
WHEEL.)
#DEFINE LM_IN2_OUT PORTC,3 ; LEFT MOTOR IN2
#DEFINE FRONT_LED_OUT PORTC,4 ; LED
#DEFINE RIGHT_LED_OUT PORTC,5 ; LED
#DEFINE CENTER_LED_OUT PORTC,6 ; LED
#DEFINE LEFT_LED_OUT PORTC,7 ; LED
;;; Constant defination.
#DEFINE PWM_HIGH .115
#DEFINE PWM_LOW .20
#DEFINE PWM_VLOW .5
;=============================================
ORG 0X000 ; PROCESSOR RESET VECTOR
NOP ; FOR ICE
GOTO START ; GO TO BEGINNING OF PROGRAM
ORG 0X004 ; INTERRUPT VECTOR
GOTO ISR
;=============================================
ISR
RETFIE
;=============================================
START
CALL INIT_PORT
CALL INIT_ADC
CALL INIT_PWM
CALL START_SIGN
MOVLW .50
MOVWF FRONT_REF_REG
;;
MAIN
CALL READ_LEFT
CALL DELAY_1MS
CALL READ_CENTER
CALL DELAY_1MS
CALL READ_RIGHT
CALL DELAY_1MS
CALL READ_VR
CALL READ_FRONT
CLRF SENSOR_REG ; CLEAR SENSOR_REG
MOVF L_AD_REG,W
SUBWF VR_AD_REG,W ; VR - L_AD_REG
BTFSC STATUS,C
BSF LEFT_FLAG ; IF L_AD_REG > VR_AD_REG THEN SET FLAG.
MOVF C_AD_REG,W
SUBWF VR_AD_REG,W
BTFSC STATUS,C
BSF CENTER_FLAG ; IF C_AD_REG > VR_AD_REG THEN SET FLAG.
MOVF R_AD_REG,W
SUBWF VR_AD_REG,W
BTFSC STATUS,C
BSF RIGHT_FLAG ; IF R_AD_REG > VR_AD_REG THEN SET FLAG.
MOVF F_AD_REG,W
SUBWF FRONT_REF_REG,W
BTFSS STATUS,C
BSF FRONT_FLAG ; IF F_AD_REG > VR_AD_REG THEN SET FLAG.
TURN_OFF LEFT_LED_OUT
TURN_OFF CENTER_LED_OUT
TURN_OFF RIGHT_LED_OUT
TURN_OFF FRONT_LED_OUT
BTFSC LEFT_FLAG
TURN_ON LEFT_LED_OUT
BTFSC CENTER_FLAG
TURN_ON CENTER_LED_OUT
BTFSC RIGHT_FLAG
TURN_ON RIGHT_LED_OUT
BTFSC FRONT_FLAG
TURN_ON FRONT_LED_OUT
CALL DELAY_1MS
MOVLW B'00000111' ;
ANDWF SENSOR_REG,W ;
ADDWF PCL ; JUMP WITH TABLE.
GOTO NO_LINE ;0
GOTO LEFT_LINE ;1
GOTO CENTER_LINE ;2
GOTO LEFT_CENTER_LINE ;3
GOTO RIGHT_LINE ;4
GOTO NUL_LINE ;5
GOTO RIGHT_CENTER_LINE ;6
GOTO CENTER_LINE ;7
NO_LINE BTFSC PRE_OP_FLAG
GOTO LEFT_LINE
GOTO RIGHT_LINE
GOTO MAIN
LEFT_LINE CALL LEFT_SMALL
BSF PRE_OP_FLAG ; PRE_OP_FLAG=1
GOTO MAIN
CENTER_LINE CALL GO1
GOTO MAIN
LEFT_CENTER_LINE CALL LEFT_VSMALL
GOTO MAIN
RIGHT_LINE CALL RIGHT_SMALL
BCF PRE_OP_FLAG ; PRE_OP_FLAG=0
GOTO MAIN
NUL_LINE CALL GO1
GOTO MAIN
RIGHT_CENTER_LINE CALL RIGHT_VSMALL
GOTO MAIN
;==========================================
DELAY_10US
GOTO $+1
GOTO $+1
RETURN
;===========================================
DELAY_50US
MOVWF DELAY_STACK1
MOVLW .15
MOVWF DELAY_CNT1
D_50US_1
DECFSZ DELAY_CNT1
GOTO D_50US_1
MOVF DELAY_STACK1,W
RETURN
;===========================================
DELAY_100US
MOVWF DELAY_STACK1
MOVLW .30
MOVWF DELAY_CNT1
D_100US_1
DECFSZ DELAY_CNT1
GOTO D_100US_1
MOVF DELAY_STACK1,W
RETURN
;===========================================
DELAY_500US
MOVWF DELAY_STACK1
MOVLW .164
MOVWF DELAY_CNT1
D_500US_1
DECFSZ DELAY_CNT1
GOTO D_500US_1
MOVF DELAY_STACK1,W
RETURN
;===========================================
DELAY_1MS
MOVWF DELAY_STACK1
MOVLW .198
MOVWF DELAY_CNT1
D_1MS_1
GOTO $+1
DECFSZ DELAY_CNT1
GOTO D_1MS_1
MOVF DELAY_STACK1,W
RETURN
;===========================================
DELAY_5MS
CALL DELAY_1MS
CALL DELAY_1MS
CALL DELAY_1MS
CALL DELAY_1MS
CALL DELAY_1MS
RETURN
;===========================================
DELAY_50MS
MOVWF DELAY_STACK2
MOVLW .50
MOVWF DELAY_CNT2
D_50MS_1
CALL DELAY_1MS
DECFSZ DELAY_CNT2
GOTO D_50MS_1
MOVF DELAY_STACK2,W
RETURN
;===========================================
DELAY_100MS
MOVWF DELAY_STACK2
MOVLW .100
MOVWF DELAY_CNT2
D_100MS_1
CALL DELAY_1MS
DECFSZ DELAY_CNT2
GOTO D_100MS_1
MOVF DELAY_STACK2,W
RETURN
;===========================================
DELAY_500MS
CALL DELAY_100MS
CALL DELAY_100MS
CALL DELAY_100MS
CALL DELAY_100MS
CALL DELAY_100MS
RETURN
;===========================================
DELAY
MOVWF DELAY_CNT2
DELAY_LOOP1
CALL DELAY_1MS
DECFSZ DELAY_CNT2
GOTO DELAY_LOOP1
RETURN
;=======================================
INIT_PORT
BANKSEL PORTA
MOVLW B'11111111' ; BUZZER OFF
MOVWF PORTA
MOVLW B'11111111' ; IRLEDs OFF
MOVWF PORTB
MOVLW B'11110000' ; LEDs(1111) & MOTORs(0000) OFF
MOVWF PORTC
BANKSEL TRISC
MOVLW B'00000000'
MOVWF TRISC
MOVLW B'11000011'
MOVWF TRISB
BCF OPTION_REG,NOT_RBPU ; PULL UP PORTB
; FOR PUSH AND JUMPER SWs INPUT.
MOVLW B'00101111'
MOVWF TRISA
BANK0
RETURN
;===========================
;===========================
INIT_ADC
BANKSEL ADCON0
MOVLW B'01000001' ; FOSC/8, AN0, A/D IS TURNED ON.
MOVWF ADCON0
BANKSEL ADCON1
MOVLW B'00000010' ; LEFT JUSTIFIED. AD=AN0~AN5. REF=VDD,VSS.
MOVWF ADCON1
BANK0
RETURN
;=============================================
INIT_PWM
BANKSEL T2CON
MOVLW B'00000101'
MOVWF T2CON ; PRESCALER =4, POSTSCALER =1:1
; TIMER2 ON
; TIMER2 CLOCK = 0.25MHz
MOVLW B'00001111'
MOVWF CCP1CON ; 2 LSBS=0, PWM MODE
MOVWF CCP2CON ; 2 LSBS=0, PWM MODE
BANKSEL PR2
MOVLW 0XFF
MOVWF PR2 ; PERIOD = 980HZ = 250000/255
BANKSEL CCPR1L
MOVLW 0X00 ; STOP RIGHT WHEEL(LEFT MOTOR)
MOVWF CCPR1L ; PWM DUTY CYCLE REGISTER
MOVLW 0X00 ; STOP LEFT WHEEL(RIGHT MOTOR)
MOVWF CCPR2L ; PWM DUTY CYCLE REGISTER
RETURN
;========================================
;========================================
START_SIGN
BANK0
TURN_ON BUZZER_OUT
TURN_ON LEFT_LED_OUT
CALL DELAY_100MS
TURN_OFF BUZZER_OUT
CALL DELAY_100MS
TURN_OFF LEFT_LED_OUT
TURN_ON CENTER_LED_OUT
CALL DELAY_100MS
CALL DELAY_100MS
TURN_OFF CENTER_LED_OUT
TURN_ON RIGHT_LED_OUT
CALL DELAY_100MS
CALL DELAY_100MS
TURN_OFF RIGHT_LED_OUT
RETURN
;=====================================
READ_FRONT
BANKSEL ADCON0
MOVLW B'01011001' ; FOSC/8, AN3, A/D IS TURNED ON.
MOVWF ADCON0
TURN_ON FRONT_IR_OUT
CALL DELAY_50US
TURN_OFF FRONT_IR_OUT
BSF ADCON0,GO_DONE
R_F_1
BTFSC ADCON0,GO_DONE
GOTO R_F_1
MOVF ADRESH,W
MOVWF F_AD_REG
BANK0
RETURN
;=====================================
READ_LEFT
BANKSEL ADCON0
MOVLW B'01000001' ; FOSC/8, AN0, A/D IS TURNED ON.
MOVWF ADCON0
TURN_ON LEFT_IR_OUT
CALL DELAY_10US
CALL DELAY_10US
TURN_OFF LEFT_IR_OUT
BSF ADCON0,GO_DONE
R_L_1
BTFSC ADCON0,GO_DONE
GOTO R_L_1
MOVF ADRESH,W
MOVWF L_AD_REG
BANK0
RETURN
;======================================
READ_CENTER
BANKSEL ADCON0
MOVLW B'01001001' ; FOSC/8, AN1, A/D IS TURNED ON
MOVWF ADCON0
TURN_ON CENTER_IR_OUT
CALL DELAY_10US
CALL DELAY_10US
TURN_OFF CENTER_IR_OUT
BSF ADCON0,GO_DONE
R_C_1
BTFSC ADCON0,GO_DONE
GOTO R_C_1
MOVF ADRESH,W
MOVWF C_AD_REG
BANK0
RETURN
;====================================
READ_RIGHT
BANKSEL ADCON0
MOVLW B'01010001' ; FOSC/8, AN2, A/D IS TURNED ON
MOVWF ADCON0
TURN_ON RIGHT_IR_OUT
CALL DELAY_10US
CALL DELAY_10US
TURN_OFF RIGHT_IR_OUT
BSF ADCON0,GO_DONE
R_R_1
BTFSC ADCON0,GO_DONE
GOTO R_R_1
MOVF ADRESH,W
MOVWF R_AD_REG
BANK0
RETURN
;======================================
READ_VR
BANKSEL ADCON0
MOVLW B'01100001' ; FOSC/8, AN0, A/D IS TURNED ON
MOVWF ADCON0
CALL DELAY_10US
CALL DELAY_10US
BSF ADCON0,GO_DONE
R_V_1
BTFSC ADCON0,GO_DONE
GOTO R_V_1
MOVF ADRESH,W
MOVWF VR_AD_REG
BANK0
RETURN
;=======================================
SET_STOP
BANKSEL CCPR1L
MOVLW 0X00 ; PWM = 0
MOVWF CCPR1L ;
MOVLW 0X00 ; PWM = 0
MOVWF CCPR2L ;
RETURN
;=======================================
GO1
BANKSEL CCPR1L
MOVLW PWM_HIGH ;
MOVWF CCPR1L ;
MOVLW PWM_HIGH ;
MOVWF CCPR2L ;
BANK0
RETURN
;====================================
LEFT_SMALL
BANKSEL CCPR1L
MOVLW PWM_HIGH ;
MOVWF CCPR1L ;
MOVLW PWM_LOW ;
MOVWF CCPR2L ;
BANK0
RETURN
;====================================
LEFT_VSMALL
BANKSEL CCPR1L
MOVLW PWM_HIGH ;
MOVWF CCPR1L ;
MOVLW PWM_VLOW ;
MOVWF CCPR2L ;
BANK0
RETURN
;===================================
RIGHT_SMALL
BANKSEL CCPR1L
MOVLW PWM_LOW
MOVWF CCPR1L ;
MOVLW PWM_HIGH ;
MOVWF CCPR2L ;
BANK0
RETURN
;======================================
RIGHT_VSMALL
BANKSEL CCPR1L
MOVLW PWM_VLOW
MOVWF CCPR1L ;
MOVLW PWM_HIGH ;
MOVWF CCPR2L ;
BANK0
RETURN
;=====================================
END ; End of Program
;=====================================
BACK
|