#include #include #include //timeout values for each task #define begin { #define end } #define maxkeys 16 #define nopush 1 #define maybepush 2 #define pushed 3 #define maybenopush 4 #define t1 20 // scan the keypad every 20 #define t2 40 // Display something on LCD every 40ms #define t3 100 // send new siganl every 100ms #define LCDwidth 16 //characters #asm .equ __lcd_port=0x12 #endasm #include // LCD driver routines char lcd_buffer[17]; unsigned char key,newkey,butnum,PushingFlag, modeFlag; unsigned char RcSpeedSetFlag, AutoSpeedSetFlag, AutoModeSetConfirmFlag, RcModeSetConfirmFlag; unsigned char SendModeFlag, SendRcSpeedFlag, SendAutoSpeedFlag, StopRcFlag; int time1, time2, time3; int pushstate, RcSpeed, AutoSpeed, speed; //key pad scan table flash unsigned char keytbl[16]={0xee, 0xed, 0xeb, 0xde, 0xdd, 0xdb, 0xbe, 0xbd, 0xbb, 0xe7, 0xd7, 0xb7, 0x77, 0x7d, 0x7e, 0x7b}; void signal(void); //transimitting siganls void keyscan(void); //scan the keypad void HandleKey(void); //match the keys to which signal to send void LcdDisplay(void); // Display something on LCD void initialize(void); //all the usual mcu stuff //********************************************************** //timer 0 compare ISR interrupt [TIM0_COMP] void timer0_compare(void) begin //Decrement the three times if they are not already zero if (time1>0) --time1; if (time2>0) --time2; if (time3>0) --time3; end //********************************************************** //********************************************************** //Entry point and task scheduler loop void main(void) begin initialize(); //main task scheduler loop while(1) begin if (time1==0) keyscan(); if (time2==0) LcdDisplay(); if (time3==0) signal(); end end //******************************* void signal(void) begin time3 = t3; if (StopRcFlag == 0) begin if (PushingFlag == 1) begin switch(butnum) { case 5: //signal to move forward PORTB.1 = 1; PORTB.2 = 0; PORTB.5 = 1; PORTB.7 = 0; break; case 8: //signal to move backward PORTB.1 = 0; PORTB.2 = 1; PORTB.5 = 0; PORTB.7 = 1; break; case 7: //signal to turn left PORTB.1 = 0; PORTB.2 = 1; PORTB.5 = 1; PORTB.7 = 0; break; case 9: //signal to turn right PORTB.1 = 1; PORTB.2 = 0; PORTB.5 = 0; PORTB.7 = 1; break; default://signal to stop PORTB.1 = 0; PORTB.2 = 0; PORTB.5 = 0; PORTB.7 = 0; break; } end else begin PORTB.1 = 0; PORTB.2 = 0; PORTB.5 = 0; PORTB.7 = 0; end end else if (SendModeFlag == 0) begin if (SendRcSpeedFlag == 1 || SendAutoSpeedFlag == 1) begin if (SendRcSpeedFlag == 1) begin speed = RcSpeed; StopRcFlag = 0; end if (SendAutoSpeedFlag == 1) speed = AutoSpeed; switch(speed) //determine which speed level to send { case 1: //signal to set speed to level 1 PORTB.1 = 1; PORTB.2 = 1; PORTB.5 = 0; PORTB.7 = 0; break; case 2: //signal to set speed to level 2 PORTB.1 = 1; PORTB.2 = 1; PORTB.5 = 0; PORTB.7 = 1; break; case 3: //signal to set speed to level 3 PORTB.1 = 1; PORTB.2 = 1; PORTB.5 = 1; PORTB.7 = 0; break; } SendRcSpeedFlag =0; SendAutoSpeedFlag =0; end else begin PORTB.1 = 0; PORTB.2 = 0; PORTB.5 = 0; PORTB.7 = 0; end end else begin switch(modeFlag) // determine which mode to send { case 1: //signal to set mode to remote control PORTB.1 = 0; PORTB.2 = 0; PORTB.5 = 0; PORTB.7 = 1; StopRcFlag = 0; break; case 2: //signal to set mode to auto PORTB.1 = 0; PORTB.2 = 0; PORTB.5 = 1; PORTB.7 = 1; StopRcFlag = 1; break; default: PORTB.1 = 0; PORTB.2 = 0; PORTB.5 = 0; PORTB.7 = 0; break; } SendModeFlag = 0; end // delay_ms(50); end //********************************************************** //Set it all up void initialize(void) begin //set up the ports DDRB=0xff; pushstate = nopush; PushingFlag = 0; modeFlag = 0; RcSpeedSetFlag =0; AutoSpeedSetFlag = 0; SendModeFlag = 0; SendRcSpeedFlag = 0; SendAutoSpeedFlag =0; StopRcFlag = 1; RcModeSetConfirmFlag = 0; AutoModeSetConfirmFlag = 0; RcSpeed = 3; AutoSpeed = 3; speed = 3; TIMSK=2; //turn on timer 0 cmp match ISR OCR0 = 250; //set the compare re to 250 time ticks //prescalar to 64 and turn on clear-on-match TCCR0=0b00001011; time1 = t1; time2 = t2; time3 = t3; lcd_init(LCDwidth); //initialize the display lcd_clear(); //clear the display //crank up the ISRs #asm sei #endasm end //********************************************************** //standard keypad scan with debounce void keyscan(void) { time1 = t1; //get lower nibble DDRC = 0x0f; PORTC = 0xf0; delay_us(5); key = PINC; //get upper nibble DDRC = 0xf0; PORTC = 0x0f; delay_us(5); key = key | PINC; //find matching keycode in keytbl if (key != 0xff) { for (butnum=0; butnum