include "hwreg-p16f628.h" // 16f628 config // enable internal oscillator FOSC2,FOSC1,FOSC0 = 100 // disable watchdog WDT = 0 // enable power up timer PWRTE = 0 // use MCLR as RA5 MCLRE = 0 // disable brown-out detect BODEN = 0 // low voltage prog disabled LVP = 0 // data memory not protected CPD = 1 // code memory not protected CP1,CP0,CP1,CP0 = 1111 // // see section 14.1 of PIC16F26X ref manual // microchip document name 40300b.pdf pragma cpu_config 0x3F10 include "LIB/strlib.bas" include "LIB/lcd_lib.bas" include "LIB/fifo_lib.bas" FIFO switch_event_fifo[6] include "LIB/debounce_lib.bas" include "LIB/servo_lib.bas" // NOTE: the use of the user defined character 7 // this is because the LCD uses the yen symbol in // place of where the ASCII backslash would normally // be // const char spin = "|/-", 7 // *.... // .*... // .*... // ..*.. // ...*. // ...*. // ....* // ..... // const ubyte backslash_glyph = 0x10, 0x08, 0x08, 0x04, 0x02, 0x02, 0x01, 0x00 //---------------------------------------------------------------------- //---------------------------------------------------------------------- ubyte ctl_val ubyte selected_servo ubyte intserv_cnt //---------------------------------------------------------------------- //---------------------------------------------------------------------- proc task_1() // PORTA bits 7, 6, 1 debounce_init(0xC2, 0x00) while 1 do debounce_queue_service() task_wait 1 done endproc //---------------------------------------------------------------------- //---------------------------------------------------------------------- proc task_2() char buff[10] ubyte last_ctl_val ubyte last_selected_servo uint loop_cnt ubyte acc servo_init(0) // PORTA bit 0 servo_define(0) servo_define(1) servo_define(2) servo_define(3) ctl_val = 127 selected_servo = 0 LCD_init() // LCD_define_glyph_code(7, &backslash_glyph) LCD_cursor_off() loop_cnt = 0 while 1 do last_ctl_val = ctl_val last_selected_servo = selected_servo task_wait 1 if last_selected_servo != selected_servo then LCD_set_pos((last_selected_servo & 1) << 3, (last_selected_servo & 2) >> 1) // ' ' == 0x20 LCD_write_char(0x20) LCD_set_pos((selected_servo & 1) << 3, (selected_servo & 2) >> 1) // '*' == 0x2A LCD_write_char(0x2A) endif if last_ctl_val != ctl_val then // doing this here helps reduce jitter on the servo servo_set_pulse(selected_servo, ctl_val) asm_start .print [{selected_servo}], [{ctl_val}] .print [{servo_wpulse_arr}][0], [{servo_wport_arr}][0], [{servo_wmask_arr}][0] .print [{servo_wpulse_arr}][1], [{servo_wport_arr}][1], [{servo_wmask_arr}][1] .print [{servo_wpulse_arr}][2], [{servo_wport_arr}][2], [{servo_wmask_arr}][2] .print [{servo_wpulse_arr}][3], [{servo_wport_arr}][3], [{servo_wmask_arr}][3] .breakpoint asm_end byte_to_str(&buff, ctl_val) strcat_code(&buff, " ") // LCD_set_pos(0, 0) LCD_set_pos(((selected_servo & 1) << 3) + 1, (selected_servo & 2) >> 1) LCD_write_str_inline(&buff) endif // LCD_set_pos(0, 1) // acc = (loop_cnt >> 7) & 0x03 // LCD_write_char(spin[acc]) // // acc = (loop_cnt >> 6) & 0x03 // LCD_write_char(spin[acc]) // // acc = (loop_cnt >> 5) & 0x03 // LCD_write_char(spin[acc]) // acc = (loop_cnt >> 3) & 0x03 // acc = (loop_cnt >> 2) & 0x03 // LCD_write_char(spin[acc]) loop_cnt += 1 done endproc //---------------------------------------------------------------------- //---------------------------------------------------------------------- proc main() ubyte acc ubyte switch_state // set PORTA to digital I/O instead of analog CMCON = 7 ctl_val = 0 selected_servo = 0 // set PORTA bit 0 to output (diag in intserv) TRISA = TRISA & ~1 task_start task_1 task_start task_2 switch_state = 0 while 1 do if switch_state == 0 then // wait for a switch event task_wait while_empty switch_event_fifo else // one or more switches is currently pressed // wait for 0.1 seconds between autoreapeat // or a switch event task_wait 2 while_empty switch_event_fifo endif while 1 do int switch_event ubyte switch_change switch_event = fifo_read_inline(&switch_event_fifo) if switch_event < 0 then break endif switch_change = switch_event // a switch change has occured // NOTE: process all switch change events if (switch_change & 0x7f) == 1 then // porta bit 1 changed state if (switch_change & 0x80) == 0 then // NOTE: this switch reads 1 for open and 0 for closed // so look to 1 to 0 transition which means from // open to closed (not pressed to pressed) selected_servo = (selected_servo + 1) & 3 ctl_val = servo_get_pulse(selected_servo) // ctl_val = ctl_val + 1 switch_state = switch_state | 0x84 else switch_state = switch_state & ~4 endif else if (switch_change & 0x7f) == 6 then // porta bit 6 changed state if (switch_change & 0x80) == 0 then // NOTE: this switch reads 1 for open and 0 for closed // so look to 1 to 0 transition which means from // open to closed (not pressed to pressed) if ctl_val != 1 then // decrease ctl_val -= 1 switch_state = switch_state | 0x81 endif else switch_state = switch_state & ~1 endif else if (switch_change & 0x7f) == 7 then // porta bit 7 changed state if (switch_change & 0x80) == 0 then // NOTE: this switch reads 1 for open and 0 for closed // so look for 1 to 0 transition which means from // open to closed (not pressed to pressed) if ctl_val != 255 then // increase number of flashes ctl_val += 1 switch_state = switch_state | 0x82 endif else switch_state = switch_state & ~2 endif endif done if (switch_state & 0x80) != 0 then // a switch press has just occured so insert // a pause beteen the switch press and // autorepeat // clear the just pressed flag switch_state = switch_state & ~0x80 // wait for 0.75 seconds or a switch event task_wait 15 while_empty switch_event_fifo else if (switch_state & 1) != 0 then if ctl_val != 1 then ctl_val -= 1 endif endif if (switch_state & 2) != 0 then if ctl_val != 255 then ctl_val += 1 endif endif endif done endproc //---------------------------------------------------------------------- //---------------------------------------------------------------------- proc intserv() if (intserv_cnt & 0x08) == 0 then PORTA = PORTA | 1 else PORTA = PORTA & ~1 endif intserv_cnt = intserv_cnt + 1 servo_service() endproc