;Servo test routine, serv675C ;Author EdwardM __CONFIG _CP_OFF & _CPD_OFF & _WDT_OFF & _MCLRE_OFF & _BODEN_OFF & _HS_OSC #define __12F675 #include <12f675.inc> ;==================================== ; Pin Defs ;==================================== ; Pin1......Vdd ; Pin2......GP5 ; Pin3......CLKOUT............TEST.......OUT ; Pin4......GP3/MCLR/Vpp......CENTRE.....IN ; Pin5......AN2...............POT........Analog ; Pin6......GP1/ICPCLK........SWEEP......IN ; Pin7......GP0/ICPDTA........PWM........OUT ; Pin8......VSS ;==================================== ; RAM 0x20 to 0x5F ;==================================== CounterA equ 0x20 CounterB equ 0x21 CounterC equ 0x22 CounterD equ 0x23 Timer_rtn equ 0x24 temp_loops equ 0x25 us_loops equ 0x26 tempf equ 0x27 set_centre equ 0x28 old_ADC equ 0x29 ADC_low equ 0x2A ADC_high equ 0x2B mode_state equ 0x2C LOW_count equ 0x2D HIGH_count equ 0x2E last_low equ 0x2F last_high equ 0x30 max_low equ 0x31 max_high equ 0x32 min_low equ 0x33 min_high equ 0x34 inc_high equ 0x35 inc_low equ 0x36 inc_up equ 0x37 init_inc equ 0x38 last_pos_high equ 0x39 last_pos_low equ 0x3A Org 0x00 goto main table addwf PCL,f retlw D'254' retlw D'205' retlw D'153' retlw D'102' retlw D'77' retlw D'62' retlw D'48' retlw D'34' retlw D'26' retlw D'19' retlw D'13' retlw D'9' retlw D'6' retlw D'4' retlw D'2' retlw D'1' ;================================ ; 16 bit Comparison MAX ;================================ compMAX movf max_high,w subwf ADC_high,w btfss STATUS,Z goto res16A movf max_low,w subwf ADC_low,w res16A return ;================================ ; 16 bit Comparison MIN ;================================ compMIN movf ADC_high,w subwf min_high,w btfss STATUS,Z goto res16B movf ADC_low,w subwf min_low,w res16B return main call initial_setup main_loop call set_20ms_frame call set_position ;Position set from previous loop call check_pbuttons ;Check pushbuttons for mode change call check_mode ;Get current test mode call wait_end20ms goto main_loop ;================================ ; Wait for end of 20ms frame ;================================ wait_end20ms btfss PIR1,0 goto wait_end20ms return ;================================ ; Which mode are we in? ;================================ check_mode clrf inc_high clrf inc_low iorlw 0x00 ;w=0xFF if change btfsc STATUS,Z ; goto nochange ;If no jump, status has changed btfsc mode_state,0 ;Centre? goto do_centre btfsc mode_state,1 goto do_sweep ;must be sweep goto changetopot do_centre call get_ADC call set_ADC_limits dc1 movlw 0xFF ;1.5ms movwf LOW_count movlw 0x01 movwf HIGH_count clrf mode_state bsf mode_state,0 return nochange clrf inc_low clrf inc_high btfsc mode_state,0 ;Centre goto check_centre btfsc mode_state,1 ;Sweep goto check_sweep ;else set by pot position changetopot call get_ADC movf ADC_high,w movwf HIGH_count movf ADC_low,w movwf LOW_count clrf mode_state bsf mode_state,2 return check_centre call get_ADC call compMAX btfsc STATUS,C ;Carry set then out of range, set posn to pot goto changetopot call compMIN btfsc STATUS,C goto changetopot goto dc1 return check_sweep call get_ADC call div64 call SetCountper20ms btfss inc_up,0 goto cs1 call add_inc return cs1 call sub_inc return do_sweep call get_ADC call div64 call SetCountper20ms bsf inc_up,0 call add_inc return add_inc movfw inc_low addwf last_pos_low,f btfsc STATUS,C incf last_pos_high,f btfss last_pos_high,2 goto ai1 movlw 0x03 movwf HIGH_count movlw 0xFF movwf LOW_count bcf inc_up,0 return ai1 movfw last_pos_high movwf HIGH_count movfw last_pos_low movwf LOW_count return sub_inc movfw inc_low ;last_pos_low subwf last_pos_low,w ;inc_low,w movwf LOW_count movfw last_pos_high btfss STATUS,C addlw 0xFF movwf HIGH_count btfss HIGH_count,7 return movlw 0x00 movwf HIGH_count movwf LOW_count bsf inc_up,0 return div64 rrf ADC_low,f rrf ADC_low,f rrf ADC_low,f rrf ADC_low,f rrf ADC_low,f rrf ADC_low,f movlw 0x03 andwf ADC_low,f rlf ADC_high,f rlf ADC_high,f movlw 0x0C andwf ADC_high,w iorwf ADC_low,w return SetCountper20ms call table movwf inc_low clrf inc_high return ;================================ ; Check ADC ;================================ get_ADC movlw 0x8B ;Start ADC movwf ADCON0 sp2 btfsc ADCON0,1 ;check go/done bit for end of conversion goto sp2 bsf STATUS,RP0 ;set bank 1 movf ADRESL,w bcf STATUS,RP0 ;set bank 0 movwf ADC_low ;LOW_count movwf LOW_count movf ADRESH,w movwf ADC_high ;HIGH_count movwf HIGH_count return ;======================================== ; Set ADC limits ;======================================== set_ADC_limits clrw movwf max_low movwf max_high movwf min_low movwf min_high movf ADC_low,w addlw D'10' movwf max_low movf ADC_high,w btfsc STATUS,C addlw 0x01 movwf max_high movlw D'10' subwf ADC_low,w movwf min_low movf ADC_high,w btfss STATUS,C addlw 0xFF movwf min_high movlw 0x00 subwf min_high,f return ;======================================== ; Check pushbutton state for mode change ;======================================== check_pbuttons btfss GPIO,GPIO3 ;Centre? goto mode_centre btfss GPIO,GPIO1 ;Sweep? goto mode_sweep retlw 0x00 ;No change mode_centre clrf mode_state bsf mode_state,0 retlw 0xFF clrf inc_low clrf inc_high mode_sweep clrf mode_state bsf mode_state,1 retlw 0xFF ;================================ ; Set PWM output on ;================================ set_20ms_frame bsf GPIO,0 ;Output on movlw 0x3B ;Set timer to 20ms-setup time @10MHz movwf TMR1H movlw 0xBB movwf TMR1L movlw 0x01 movwf T1CON ;Timer enable bcf PIR1,0 ;Clear timer overflow flag return ;================================ ; Set position ;================================ set_position call init_delay ;Nominal 1ms delay movfw HIGH_count movwf last_pos_high movfw LOW_count movwf last_pos_low clrw iorwf LOW_count,f btfsc STATUS,Z goto low_zero low_nonzero decfsz LOW_count,f goto low_nonzero low_zero clrw iorwf HIGH_count,f btfsc STATUS,Z goto high_zero do_loops decfsz LOW_count,f goto do_loops decf HIGH_count,f goto low_zero high_zero bcf GPIO,0 ;Output off return init_delay movlw D'3' movwf CounterB movlw D'210' movwf CounterA loop decfsz CounterA,1 goto loop decfsz CounterB,1 goto loop return us_delay movlw D'4' movwf CounterA loopus decfsz CounterA,1 goto loopus nop nop nop nop nop return ;================================ ; Initial setup ;================================ initial_setup bcf STATUS,RP0 ;set bank 0 clrf GPIO ;set GPIO 's to 0 movlw 07H ; movwf CMCON ;Comparator control - off bsf STATUS,RP0 ;set bank 1 movlw 0x24 movwf ANSEL movlw 0x3E ;GP2/AN2 input only movwf TRISIO ;all others output, bank 1 bcf STATUS,RP0 ;set bank 0 movlw 0x89 ;Initialise adc movwf ADCON0 ;bank 0 bcf mode_state,0 ;Centre bcf mode_state,1 ;Sweep bsf mode_state,2 ;Pot call get_ADC clrf inc_low clrf inc_high movlw 0x01 movwf init_inc return end