list p=18f45j10 #include CBLOCK 0x0 conw, cons, conb ctr1, ctr2, ctr3, ctr4 ledc sres, sleft, sright, sside, botsta ENDC CONFIG DEBUG = OFF, XINST = OFF, STVREN = ON, WDTEN = OFF CONFIG CP0 = OFF, FCMEN = OFF, IESO = OFF, FOSC2 = ON CONFIG FOSC = HSPLL, WDTPS = 1, CCP2MX = DEFAULT org 0x0000 goto start org 0x0008 goto isr_high org 0x00018 goto isr_low #define CLOCK LATD, 3 #define DAT LATD, 2 #define LED_L LATD, 0 #define LED_R LATD, 1 #define DIR_CH CCP1CON, 7 #define LSSTA sside, 0 #define RSSTA sside, 1 set_right MACRO movlw 0x20 movwf CCPR1L movlw 0x60 movwf CCPR2L ENDM set_straight MACRO movlw 0x80 movwf CCPR1L movlw 0x85 movwf CCPR2L ENDM set_left MACRO movlw 0xa0 movwf CCPR1L movlw 0xE0 movwf CCPR2L ENDM start movlw b'11100000' movwf TRISD ;RD7-5 = in, rest out clrf PORTD clrf PORTC clrf LATD clrf LATC movlw b'00000100' movwf TRISC ;RC2 = in, rest out movlw b'00000111' movwf TRISE ;RE0-2 = in setf TRISA ;RA0-7 = in clrf PORTA clrf LATA movlw b'00001100' ;RB3-4 = in, rest out movwf TRISB clrf PORTB clrf LATB movlw 0x07 movwf CMCON ;Disable comparators movlw b'00000101' ;AN0-9 analog, rest digital movwf ADCON1 movlw b'00110110' movwf ADCON2 ;1.6us TAD, 12.8us TACQ, left justified clrf ECCP1AS ;Disable auto shutdown setf PR2 ;255 -> PR2 movlw b'01001100' movwf CCP1CON ;Full bridge forward movlw b'00001100' movwf CCP2CON set_straight clrf ECCP1DEL ;No dead band delay and autorestart bcf PIR1, 1 ;Clear timer 2 interrupt flag movlw b'00000101' movwf T2CON ;1:4 prescale, turn on timer 2 w8_t2 btfss PIR1, 1 ;Wait timer 2 interrupt flag goto w8_t2 clrf TRISC ;Set PA-D outs clrf TRISD bcf PIR1, 1 ;Clear timer 2 int flag goto main isr_high end_hisr retfie FAST isr_low movwf conw movff STATUS, cons movff BSR, conb end_lisr movf conw, w movff cons, STATUS movff conb, BSR ;************************************************************************* ; Delay subroutine ~2s ;************************************************************************* delay0 movlw d'5' movwf ctr1 dl03 setf ctr2 dl02 setf ctr3 dl01 decfsz ctr3, f bra dl01 decfsz ctr2, f bra dl02 decfsz ctr1, f bra dl03 return ;************************************************************************* ; Main Subroutine ;************************************************************************* main bcf DAT bsf CLOCK ;1 bcf CLOCK bsf CLOCK ;2 bcf CLOCK bsf CLOCK ;3 bcf CLOCK bsf CLOCK ;4 bcf CLOCK bsf CLOCK ;5 bcf CLOCK bsf CLOCK ;6 bcf CLOCK bsf CLOCK ;7 bcf CLOCK bsf CLOCK ;8 bcf CLOCK clrf botsta loop rcall read_sensors btfss botsta, 1 ;Line lost? bra normal_dir ;No, normal control btfss sres, 3 ;1st L snsr 1? bra loop ;No, back to checking btfss sres, 4 ;Yes, 1st R snsr 1? bra loop ;No, back to checking bcf botsta, 1 ;Bot found line bcf DIR_CH ;Go forwards again btfss botsta, 0 ;Last detection right? bra go_left_sharp ;No, left set_right ;Turn right rcall delay0 ;Delay bra loop go_left_sharp set_left ;Turn left rcall delay0 ;Delay bra loop normal_dir btfss sres, 3 ;1st L snsr 1? bra cpr ;No, compare sides btfss sres, 4 ;Yes, 1st R snsr 1? bra cpr ;No, compare sides btfsc LSSTA ;Left-most 0? bra leftmost1 ;No, check the other for 1 btfss RSSTA ;Right-most 0? bra go_forward ;Yes, go forward bsf botsta, 0 bra go_forward leftmost1 btfsc RSSTA ;Right-most 0? bra go_forward ;No, go forward bcf botsta, 0 ;Indicate last direction left bra go_forward cpr movf sright, w cpfsgt sleft ;sleft <= sright? bra check_z ;Yes, go check zero go_left ;No, go forward set_left ;Turn left bra loop check_z cpfseq sleft ;sright = sleft? bra go_right ;No, go right tstfsz sright ;sright = sleft = 0? bra go_forward ;No, go forward bsf botsta, 1 ;Yes, indicate backwards set_straight ;Go straight bsf DIR_CH ;Set backwards bra loop go_forward bcf botsta, 1 ;Indicate forward set_straight bra loop go_right set_right ;Turn right bra loop ;************************************************************************* ; Sensor read subroutine ;************************************************************************* read_sensors clrf sres ;Clear sensor result word clrf sleft ;Clear left amount clrf sright ;Clear right amount bsf DAT bsf CLOCK bcf CLOCK ;Clock the SIPO reg bcf DAT movlw b'00000101' rcall conv ;Left sensor 1 movlw d'128' subwf ADRESH, w btfsc STATUS, C incfsz sleft, f rlcf sres, f bsf CLOCK bcf CLOCK movlw b'00001001' rcall conv ;Left sensor 2 movlw d'128' subwf ADRESH, w btfsc STATUS, C incfsz sleft, f rlcf sres, f bsf CLOCK bcf CLOCK movlw b'00001101' rcall conv ;Left sensor 3 movlw d'128' subwf ADRESH, w btfsc STATUS, C incfsz sleft, f rlcf sres, f bsf CLOCK bcf CLOCK movlw b'00010001' rcall conv ;Left sensor 4 movlw d'128' subwf ADRESH, w btfsc STATUS, C incfsz sleft, f rlcf sres, f bsf CLOCK bcf CLOCK movlw b'00010101' rcall conv ;Right sensor 1 movlw d'128' subwf ADRESH, w btfsc STATUS, C incfsz sright, f rlcf sres, f bsf CLOCK bcf CLOCK movlw b'00011001' rcall conv ;Right sensor 2 movlw d'128' subwf ADRESH, w btfsc STATUS, C incfsz sright, f rlcf sres, f bsf CLOCK bcf CLOCK movlw b'00011101' rcall conv ;Right sensor 3 movlw d'128' subwf ADRESH, w btfsc STATUS, C incfsz sright, f rlcf sres, f bsf CLOCK bcf CLOCK movlw b'00100001' rcall conv ;Right sensor 4 movlw d'128' subwf ADRESH, w btfsc STATUS, C incfsz sright, f rlcf sres, f bsf CLOCK bcf CLOCK rcall check_leftmost rcall check_rightmost return ;************************************************************************* ; A/D conversion subroutine ;************************************************************************* conv movwf ADCON0 ;Select channel bsf ADCON0, GO wait_conv btfsc ADCON0, GO bra wait_conv nop return ;************************************************************************* ; Right-most sensor check ;************************************************************************* check_rightmost bcf RSSTA ;Left-most sensor indicating low bsf LED_R movlw b'00100101' rcall conv ;Begin conversion bcf LED_R btfss ADRESH,7 ;ADRESH > 125? return ;No, end bsf RSSTA ;Left-most sensor indicating high incf sright, f return ;End ;************************************************************************* ; Left-most sensor check ;************************************************************************* check_leftmost bcf LSSTA ;Left-most sensor indicating low bsf LED_L movlw b'00000001' rcall conv ;Begin conversion bcf LED_L btfss ADRESH,7 ;ADRESH >= 128? return ;No, end bsf LSSTA ;Right-most sensor indicating high incf sleft, f return ;End END