/* ** 2.5ms毎にG/Aからくる割込み処理ルーチン1 */ void GA_Interrupt1(void) { UBYTE debug; ++IntTimerCounter; /* 2.5ms毎に行うルーチンを記述 */ /* 画処理 & 送信モータ制御 */ ScannerInt(); /* LCD/LED制御 */ #if 0 /* defined (HINOKI2) */ /* LCDドライバ変更対応 2002/05/15 T.Takagi */ if (!SYS_IsCGRAM_Writing) { SYS_IsDisplayingLCD = TRUE; DisplayLCD(); SYS_IsDisplayingLCD = FALSE; } #else DisplayLCD(); #endif /* キースキャン */ KeyScan(); if (IntTimerCounter & 0x00000001) { /* 5msに1回処理 */ #if (0) /* 1998/11/18 by T.Soneoka 以下の処理を2.5msで行うように上記に変更 */ ** /* LCD/LED制御 */ ** DisplayLCD(); ** /* キースキャン */ ** KeyScan(); #endif /* Thermal Printer 制御 */ PrinterTimerInt(); /* ** 済みスタンプ保険処理 ** 150ms以上On時間があると済みスタンプが壊れるため ** それ以上Onしている場合は強制的にOffする */ if (RelayPortStatus & IO_BIT_STAMP) { StampOnTime++; } else { StampOnTime = 0; } if (StampOnTime > (150/5)) { RelayPortStatus &= (~IO_BIT_STAMP); OutputWORD(GA_PGADR, RelayPortStatus); } } }
void main(void) { uchar tab_temper[]={"temper: "}; uchar tab_time[]={"now: : :"}; DS18B20SendChangeCmd(); LCD1602Config(); LCD1602WriteCommand(yh); LCD1602WriteStr(tab_temper, 8); LCD1602WriteCommand(er+3); LCD1602WriteStr(tab_time, 11); DS1302Config(); Timer1Config(); while(1){ LCD1602WriteCommand(0xc0); TempSisplay(DS18B20GetTmpValue(), yh+8); DS18B20SendChangeCmd(); KeyScan(); // TimeReresh(14,miao); // TimeReresh(11,fen); // TimeReresh(8,shi); } }
void main(void) { P0=0x00; // 初始化I/O口 P2=0x00; P1=0xFF; P3=0xFF; phase_2 = phase_1 + phase_difference; // 计算相位 frequence_2 = frequence_1 * bizhi; // 计算频率 ad9850_reset_serial_1(); ad9850_wr_serial_1(phase_1,frequence_1); ad9850_reset_serial_2(); ad9850_wr_serial_2(phase_2,frequence_2); while(1) { KeyScan(); // 扫描按键 if(KEY_flag==1) { phase_2 = phase_1 + phase_difference; frequence_2 = frequence_1 * bizhi; if(frequence_2 > 5000000) // frequence_2控制在10MHZ frequence_2 = 5000000; ad9850_reset_serial_1(); ad9850_wr_serial_1(phase_1,frequence_1); ad9850_reset_serial_2(); ad9850_wr_serial_2(phase_2,frequence_2); KEY_flag=0; // 清零 } } }
/*------------------------------------------------ 主函数 ------------------------------------------------*/ void main (void) { unsigned char num; PWM_ON=0; Init_Timer0(); //初始化定时器0,主要用于数码管动态扫描 TempData[0]=0x5E; //'d' TempData[1]=0x39; //'C' while (1) //主循环 { num=KeyScan(); //循环调用按键扫描 if(num==1)//第一个按键,速度等级增加 { if(PWM_ON<CYCLE) PWM_ON++; } else if(num==2)//第二个按键,速度等级减小 { if(PWM_ON>0) PWM_ON--; } TempData[5]=dofly_DuanMa[PWM_ON/10]; //显示速度等级 TempData[6]=dofly_DuanMa[PWM_ON%10]; } }
/******************************************************************** * KeyTask() - Read the keypad and updates KeyBuffer. * A task decomposed into states for detecting and * verifying keypresses. This task should be called * periodically with a period greater than the worst case * switch bounce time and less than the shortest switch * activation time minus the bounce time. The switch must * be released to have multiple acknowledged presses. * (Public) ********************************************************************/ void KeyTask(void) { INT8U cur_key; static INT8U last_key = 0; static KEYSTATES KeyState = KEY_OFF; cur_key = KeyScan(); if(KeyState == KEY_OFF){ /* Key released state */ if(cur_key != 0){ KeyState = KEY_EDGE; }else{ /* wait for key press */ } }else if(KeyState == KEY_EDGE){ /* Keypress detected state*/ if(cur_key == last_key){ /* Keypress verified */ KeyState = KEY_VERF; KeyBuffer = KeyCodeTable[cur_key - 1]; /*update buffer */ }else if( cur_key == 0){ /* Unvalidated, start over */ KeyState = KEY_OFF; }else{ /*Unvalidated, diff key edge*/ } }else if(KeyState == KEY_VERF){ /* Keypress verified state */ if((cur_key == 0) || (cur_key != last_key)){ KeyState = KEY_OFF; }else{ /* wait for release or key change */ } }else{ /* In case of error */ KeyState = KEY_OFF; /* Should never get here */ } last_key = cur_key; /* Save key for next time */ }
// Test keys void KeyPro() { switch( KeyScan() ) { //第一行键值码 case 0xee: P0 = leddata[0]; break; case 0xde: P0 = leddata[1]; break; case 0xbe: P0 = leddata[2]; break; case 0x7e: P0 = leddata[3]; break; //第二行键值码 case 0xed: P0 = leddata[4]; break; case 0xdd: P0 = leddata[5]; break; case 0xbd: P0 = leddata[6]; break; case 0x7d: P0 = leddata[7]; break; //第三行键值码 case 0xeb: P0 = leddata[8]; break; case 0xdb: P0 = leddata[9]; break; case 0xbb: P0 = leddata[10]; break; case 0x7b: P0 = leddata[11]; break; //第四行键值码 case 0xe7: P0 = leddata[12]; break; case 0xd7: P0 = leddata[13]; break; case 0xb7: P0 = leddata[14]; break; case 0x77: P0 = leddata[15]; break; //独立键盘 case 0xfe: P0 = leddata[16]; break; case 0xfd: P0 = leddata[17]; break; case 0xfb: P0 = leddata[18]; break; case 0xf7: P0 = leddata[19]; break; } }
int main() { InitData(); while(1) { ReadTimeAndJudgeAlarmArrival(); switch (mainLoop) { case 0: display_time(); break; case 1: display_data(); break; case 2: display_alarm(); break; case 3: display_sWatch(); break; } KeyScan(); } return 0; }
/******************************************************************************* * 函 数 名 :main * 函数功能 :主函数 * 输 入 :无 * 输 出 :无 *******************************************************************************/ void main() { UsartConfiguration(); printf("system begin\r\n"); Timer0Init(); Exit0Init(); SystemInit(); while(1) { KeyScan(); Display(ratio_value); // if(motor_count >= 5000)//每隔5s反转一次 // { // motor_count = 0; // motor_dir = !motor_dir; // printf("system switch dir\r\n"); // } if(time1s_tick>= 2000) { time1s_tick = 0; printf("%d %d\r\n",coder_count,motor_count); } } }
void TIM3_IRQHandler(void) { unsigned char KeyCode; TIM3_SR = 0; if (Delay_Counter) Delay_Counter--; if (Counter_20mS > 0) Counter_20mS--; else { // read key per 20mS Cursor_Counter++; if (Cursor_Counter > 24) { // 25*20mS=500mS Cursor_Counter = 0; Update[Item] = 1; Type = 1 - Type; } Counter_20mS = 20; if (Key_Wait_Counter) Key_Wait_Counter--; if (Key_Repeat_Counter) Key_Repeat_Counter--; KeyCode = KeyScan(); if (KeyCode != 0) Key_Buffer = KeyCode; } }
//******************************** // 加上延时抖动的读取,一次读取一个 //******************************** uchar KeyScan_once(void){ uchar keyValue,keyValue2; keyValue=KeyScan(); delay_ms(2); keyValue2=KeyScan(); if(keyValue==keyValue2 && keyValue!='n'){//两次扫描,消除抖动 if(key_value==keyValue){//如果还是上一次保存的值则代表一直按着,返回‘n’ return 'n'; }else{ //松开后第一次按下,返回该键的值 key_value=keyValue; return keyValue; } }else{ //因为读取键盘的值会多次刷新,所以在松开按键时key_value重置 key_value='n'; return 'n'; } }
void main() { TMOD = 0x01;//定时器0 工作模式1 16模式定时器 TH0 = (65536 - 46082)/256; TL0 = (65536 - 46082)%256; //定时50ms TR0 = 1; current_counter = time_counter; while(1) { uchar key = KeyScan(); if(key == 0xfe) { Beeeeeep(1); if(pause == 0) { pause = 1; } else if(pause == 1) { pause = 0; } } if(TF0 == 1 && pause == 0) { TF0 = 0; TH0 = 0x4b; TL0 = 0xfe; //定时50ms counter++; } if(counter == 20 && pause == 0) { counter = 0; //LED1 = ~LED1; current_counter--; } if(current_counter == 0) { Beeeeeep(beep_times); if(status == 1){ status = 0;} else if(status == 0){ status = 1;} if(status == 0){ current_counter = time_counter;} else if(status == 1){ current_counter = rest_counter;} } if(status == 0){ display(current_counter);} else if(status == 1){ displayLow(current_counter);} } }
/******************************************************************************* * 函 数 名 :main * 函数功能 :主函数 * 输 入 :无 * 输 出 :无 *******************************************************************************/ void main() { Timer0Init(); speed = 30; while(1) { KeyScan(); } }
void KeyPro() { uchar j,Flag; uchar static WrongTime,k; uchar temp[6]; num=KeyScan(); if(num!=16) //如果扫描是按键有效值则进行处理 { if(k==0) GUI_box(100,16,239,31,GRAY); if(k<6) //密码是6位,大于6位时不再输入按键值 { temp[k]=num; GUI_sprintf_char(100+k*9,16,num+'0',YELLOW,GRAY); } k++; //输入数值累加 if(k==7)//6位后的按键不输入数值,相当于确认按键(任意按键即可) { k=0; //计数器复位 Flag=1;//先把比较位置1 for(j=0;j<6;j++)//循环比较8个数值,如果有一个不等 则最终Flag值为0 Flag=Flag&&(temp[j]==password[j]);//比较输入值和已有密码 KeyFlag=0; if(Flag)//如果比较全部相同,标志位置1 { GUI_box(100,16,239,31,GRAY); GUI_sprintf_string(100,16,"Right,Come in!",RED,GRAY);//密码正确显示的信息 WrongTime=0; Flag=0; } else { ++WrongTime; if(WrongTime==3) { GUI_box(100,16,239,31,GRAY); GUI_sprintf_string(100,16,"Wrong,Three Times!",RED,GRAY);//密码错误三次 KeyFlag=0; // while(1); } GUI_box(100,16,239,31,GRAY); GUI_sprintf_string(100,16,"Wrong,Try again!",RED,GRAY);//密码错误,提示重新输入 } } } }
/**************************************************************************** * 程序入口函数 ****************************************************************************/ void main(void) { InitLed(); //设置LED1相应的IO口 InitKey(); //设置S1相应的IO口 while(1) { if (KeyScan()) //按键按下则改变LED状态 LED1 = ~LED1; } }
/******************************************************************** * Function: void ProcessIO(void) *******************************************************************/ void ProcessIO(void) { // User Application USB tasks if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; // キースキャン KeyScan(); //Call the function that behaves like a keyboard Keyboard(); }//end ProcessIO
/******************************************************************************* * 函 数 名 :main * 函数功能 :主函数 * 输 入 :无 * 输 出 :无 *******************************************************************************/ void main() { key_value_disp = 0; key_value = 0; while(1) { key_value=KeyScan(); if(key_value != 0xff) { key_value_disp = key_value; } LEDdisplay(key_value_disp); } }
void KeyListened(void) { unsigned char sta = KeyStaSwitch(KeyScan()); switch (sta) { case KEY_STA_DOWN : { Lock315Assoc(); } break; case KEY_STA_LHOLD : { SystemReset(); } break; } }
/******************************************************************************* * 函 数 名 :main * 函数功能 :主函数 * 输 入 :无 * 输 出 :无 *******************************************************************************/ void main() { int key_value; CarStop(); LED_OFF; LCD1602Init(); Timer0Init(); //5ms 执行一次 while(1) { key_value = KeyScan(); if(key_value == KEY1) { sys_status = 0; } if(key_value == KEY2) { sys_status = 1; } //执行部分 if(sys_status == 1) { VoidRun(); }else { ctrl_comm = COMM_STOP; CarStop(); } if(tick_5ms >= 5) { tick_5ms = 0; tick_200ms++; if(tick_200ms >= 40) { tick_200ms = 0; if(switch_flag) { LED_ON; switch_flag = 0; }else { LED_OFF; switch_flag = 1; } } } } }
/** Main program entry point. This routine configures the hardware required by the application, then * enters a loop to run the application tasks in sequence. */ int main(void) { //RFCOMM_SendFrame(0x10003000,0x10003004,4,4,130,0x10003200); uint16_t tick; SetupHardware(); LPC_TIM0->TCR = 1; Led1On(); Led2On(); Led1Off(); Led2Off(); EVENT_USB_Host_DeviceUnattached(); for (;;) { //uint8_t ButtonStatus = Buttons_GetStateMask(); /* Check if the system update interval has elapsed */ if(LPC_TIM0->IR &0x01) { /* Clear the timer compare flag */ LPC_TIM0->IR |= 0x01; if (RFCOMM_SensorStream){ Led1On(); } else{ if(tick++>=50) { tick = 0; Led1Not(); } } /* If the bluetooth stack is active, manage timeouts within each layer */ BluetoothAdapter_TickElapsed(); KeyScan(); if(sendFlag){ rfcomm_send_data(); } } BluetoothAdapter_USBTask(); USB_USBTask(); } }
/******************************************************************** 函数功能:定时器1中断处理函数。 入口参数:无。 返 回:无。 备 注:无。 ********************************************************************/ interrupt [TIM0_OVF] void Timer0Isr(void) { static uint8 i,Count; static uint16 KeyCount; TCNT0=0xFF-78; //定时器重装 KeyScan(); //按键扫描 Count++; //由于圈圈在这里并没有实现键盘的功能,所以用软件模拟一个右键 //如果读者自行实现了按键功能,请将这段代码注释掉,避免混乱 KeyCount++; if(KeyCount%790==0) //每4秒发一次 { KeyPress=KEY4; //KEY4是右键 KeyDown=KEY4; } if(KeyCount>=800) //50ms后,释放右键,这时将弹出右键菜单 { KeyCount=0; KeyPress=0; KeyUp=KEY4; } //////////////////模拟右键功能完毕////////////////////// if(Count>=25) //每秒闪烁8次 { Count=0; if(UsbLedBlink) //如果需要闪烁 { if(i) OnLed1(); else OffLed1(); i=!i; UsbLedBlink--; } else { if(ConfigValue) //如果配置值为非0,Led1闪烁后亮 { OnLed1(); } else //否则,Led1闪烁后灭 { OffLed1(); } } } }
// Timer A0 interrupt service routine. void timera_isr(void) __interrupt[TIMERA0_VECTOR] { // Toggle LED. //P1OUT ^= 0x01; //OPTIMIZATION: disable this interrupt most of the time: it should only be enabled at the end //of the serial/keypad interrupt //most of the time = if tasks[button] == 0 && tasks[keypad] == 0 //do not optimize for this as the variables mey be re-enabled by an interrupt if (tasks[button] == 1){ //the actual key value is scanned in the interrupt routine if (time == 0){ //debounce done KeyScan(); if (edge == 1){ //falling edge if (keyDown == 1){ //a key is down, which means it was NOT a real falling edge event time = BOUNCE_DELAY; return; } #ifdef DEBUG debug_printf("Button was released\n"); #endif //check if key code is correct? //check if it matches rising edge code? //send data to cpld, depending on game logic SetForPress(); } else { //rising edge if (keyDown == 0){ //no key is down, which means it was noise tasks[button] = 0; //nothing to do, it was just a glitch } WaitForRelease(); #ifdef DEBUG debug_printf("Button is Down\n"); #endif } } else{ //decrease the waiting time time --; } } }
int main() { setup(); unsigned int uiKey = 0; while(1) { uiKey = KeyScan(); if(uiKey == 0x8000) { *P_Watchdog_Clear = 0x0001; break; } *P_Watchdog_Clear = 0x0001; } while(1) { loop(); } return 0; }
/********************************************************** **Name: MenuConfig **Function: Menu config & display **Input: none **Output: none **********************************************************/ void MenuConfig(void) { u8 KeyValue=KeyScan(); //Get key value if(gb_SystemMode==C_SysMode_EntrySet) //Parameter select mode { RFParameterSelect(KeyValue); } else if(gb_SystemMode==C_SysMode_Modem) { ModemSelect(KeyValue); //Modem select mode } else { WorkModeSelect(KeyValue); //Work mode } DisplayRFParameter(); LCD_Display(); //Display }
void Task1(void *Id) { uint8_t n = 0 ; (void) Id; SysTick_Config(120000); // CPU_IntEn(); n = KeyScan(); DspRst(); // CheckLight(); // OSTimeDly(250); ConfigBCK(); InitStart(); GR_DBG_PRINTF("Variable System length %d ",sizeof(System) ); TIMER_Configuration(); TIMER1_Configuration(); System.Usb.OldUsbStatu = USB_STATUS ; switch(n) { case 1 : TESTA(); break ; // case 2 : TESTB(); break ; // case 3 : TESTC(); break ; // case 4 : TESTD(); break ; case 3 : TESTE(); break ; default :break ; } for(;;) { KeyDispose(); OSTimeDly(5); } }
/******************************************************************************* * 函 数 名 :main * 函数功能 :主函数 * 输 入 :无 * 输 出 :无 *******************************************************************************/ void main() { int key_value; CarStop(); LED_OFF; Timer0Init(); UltraSoundInit(); //5ms 执行一次 while(1) { key_value = KeyScan(); if(key_value == KEY1) { sys_status = 0; } if(key_value == KEY2) { sys_status = 1; } //执行部分 if(tick_5ms >= 5) { tick_5ms = 0; if(sys_status == 1) { Distance(); VoidRun(); }else { CarStop(); } } } }
void TESTD() //连拍老化测试 { uint16_t i =0 ; uint8_t m = 0 ; AA: for(i = 0 ; i <2000; i++) { PhotographFour(); OSTimeDly(200); } Light_Init(); SHOW_SCREEN(0xE8, "Press K4 To Run Again\n"); while(1) { m = KeyScan() ; if(m) { Select_Send(0xE9); if(m == 4) { goto AA ; } else { break ; } } } //////////////////////////////////////////////////////// /////////////////////////////////////////////////////// }
void KeyInfoDispose_Debug() { //按键检测处理 System.Key.Value = KeyScan() ; System.Key.Keylong = &Keylong ; if(!System.Key.Value) { // 处理休眠操作 } else { // GR_DBG_PRINTF("keylong is %d OK it is %d\n\n",*System.Key.Keylong,Keylong); // 处理唤醒操作 System.Key.NoKeyTime = 0 ; if(System.Dsp.Mode == SLEEP_MODE) { CheckMode(); } //处理按键操作 switch(System.Key.Value) { case 1 :// 顶白光 { Top_W_On(); PhotoMvLeft() ; }break ; case 2 :// check: 850 940 770 闪烁 长按:进入PCCAM { #ifdef ONE_SENSOR Top_IR940_On_test(); PhotoMvUp() ; #else if(*System.Key.Keylong) { switch(System.Dsp.Mode ) { case PCCAM_MODE : CheckMode(); break; default: PccamMode(); break; } } else { if(System.Dsp.Mode == CHECK_MODE||PCCAM_MODE) { switch(System.Led.Statu) { case TOP_IR850_ON : Top_IR940_On();break ; case TOP_IR940_ON : Right_IR770_On();break ; default :Top_IR850_On(); break ; } } } #endif }break ; case 3 ://check: 紫外-激光 长按:进入校正 { if(*System.Key.Keylong)// 进入校正功能 { if(System.Dsp.Mode == CHECK_MODE) { PriorExposure(); } } else { if((System.Dsp.Mode ==PCCAM_MODE)||(System.Dsp.Mode ==CHECK_MODE)) { Double_UV_On(); } PhotoMvRight() ; } }break ; case 4 ://check : sensor1 sensor2 sensor3 ,长按:608 { switch(System.Dsp.Mode) { #ifdef ONE_SENSOR case PCCAM_MODE : { if(*System.Key.Keylong) { CheckMode(); } } break ; #endif case VIEW_MODE : case CHECK_MODE : { if(*System.Key.Keylong) { PccamMode(); } else { // switch(System.Led.Statu) // { // case C608_PWR_ON: CheckMode();break; // default:C608_On(); break; // } PhotoZoomUp(); } } break ; default :break ; } }break ; case 5 ://check: 左白光 右白光 左红外, 右红外 view:翻页 放大 { switch(System.Dsp.Mode) { case PCCAM_MODE : case CHECK_MODE : { switch(System.Led.Statu) { case LEFT_W_ON : Right_W_On(); break ; case RIGHT_W_ON : Left_IR850_On(); break ; case LEFT_IR850_ON: Right_IR850_On(); break ; default :Left_W_On(); } }break; case VIEW_MODE : { switch(System.Dsp.ViewMode.Zoom) { case X0 : PhotoPrevious(); break; default : PhotoMvLeft() ; } }break; default :break ; } }break ; case 6 ://check: 底白光,底红外 view :右边翻页 { switch(System.Dsp.Mode) { case PCCAM_MODE : case CHECK_MODE : { switch(System.Led.Statu) { case BOT_W_ON : Bot_IR_On(); break ; default :Bot_W_On(); } }break; case VIEW_MODE : { switch(System.Dsp.ViewMode.Zoom) { //case X0 : PhotoNext(); break ; default : PhotoMvDown() ; break ; } }break; default :break ; } }break ; case 7 ://view--check ; { switch(System.Dsp.Mode) { case CHECK_MODE : { VerifyPassword(0x07,&CheckMode,&ViewMode); } break; case VIEW_MODE : { CheckMode(); } break; default :break ; } }break ; case 8 ://check:短按单拍,长按8连拍 ,view 长按删除,短按确认 { switch(System.Dsp.Mode) { case CHECK_MODE : { #ifdef ONE_SENSOR PhotographOne(); #else if(*System.Key.Keylong) { //PhotographOne(); } else { PhotographEight(); } #endif }break; case VIEW_MODE : { if(*System.Key.Keylong) { PhotoDelAll(); } else { } }break; default :break ; } }break ; case 9 ://check: 短按连拍,长按修改密码 // view:自动回放 { switch(System.Dsp.Mode) { case CHECK_MODE : { if(*System.Key.Keylong) { VerifyPassword(0x09,&CheckMode,&ChangePassWord); CheckMode(); } else { PhotographFour(); } }break; case VIEW_MODE : { PhotoAutoView(); // 自动回放 }break; default :break ; } }break ; default : break ; } } }
void Timer1BIntHandler(void) { uint32_t intStatus; intStatus = TimerIntStatus(TIMER1_BASE, true); TimerIntClear(TIMER1_BASE, intStatus); //g_ui32Counter++; timeCounter++; keyStatus = KeyScan(); if(keyStatus == 1) { iss = 1; M1_LED_ON; setMotorPowerMax(); pduty += 50; } else if(keyStatus == 2) { iss = 2; M1_LED_OFF; setMotorPowerMin(); } #ifdef USE_MCU2 switch(keyStatus) { case 0: M2_LED1_OFF; M2_LED2_OFF; break; case 1: M2_LED1_ON; //GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_0, 0x01); //GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_1, 0x02); break; case 2: M2_LED2_ON; //GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_0, 0x00); //GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_1, 0x00); M2_LED4_OFF; break; case 3: disVal++; if(disVal % 2 == 0) { M2_LED3_ON; M2_LED4_ON; } else { M2_LED3_OFF; M2_LED4_OFF; } break; } #endif if(timeCounter == NUMBER_OF_INTS) { //g_ui32Counter = 0; timeCounter = 0; #if 0 disVal++; if(disVal % 2 == 0) M1_LED_ON; else M1_LED_OFF; #endif //OLED_P6x8Num(2,4,disVal++); //stop_Timer0B(); } }
//**************************8 // 3整组测量。 //功能: 实现某组电池的整组测量。 //************************* void TotalGrpMeasure(void ) { unchar i; unchar s[12]; unint fint; float fres; float f,arf[3]; switch(MenuStatus) { case 2: if(CURPATH.CurrentDirStarClusID !=0) { CURPATH.CurrentDirStarClusID = 0; } if((ReadFile("CONFIG TXT", (unchar*)pCfgHead, 0,sizeof (CFG_HEAD))!=0xff))//取出系统头 { Index = 1; // t=*(unint*)Temp;再次出现字节对齐的问题,开始调试的时候是没问题的现在又出了。。。 s[0] = Index/1000+0x30; s[1] = (Index%1000)/100+0x30; s[2] = ((Index%1000)%100)/10+0x30; s[3] = ((Index%1000)%100)%10+0x30; s[4] = '\0'; Str_8x16(0,0,"组:"); Str_8x16(0,3,s); DispFanBai(0,3,4); MenuStatus =1000; } else { Str_8x16(1,0 ,"系统文件不存在"); Delay_ms(2000); MenuStatus = 3; return; } break; case 1000: switch(GetKey1()) { case ENTER_KEY: DispFanBai(0,3,4);//组位置取消反白 //先从config文件读出该组电池对应的组属性域; if( ReadFile("CONFIG TXT",(unchar*)pGrpHead,Index*64,sizeof (GRP_HEAD))==0xff) { Str_8x16(2,0,"系统配置文件错误"); Delay_ms(2000); MenuStatus =3; return; } //进入该组所在的目录如果没有该组就建立该组的目录。并在该目录下根据时间建立该组的测量文件 if(CURPATH.CurrentDirStarClusID !=0) { CURPATH.CurrentDirStarClusID = 0; } s[0] = Index/1000+0x30; s[1] = (Index%1000)/100+0x30; s[2] = ((Index%1000)%100)/10+0x30; s[3] = ((Index%1000)%100)%10+0x30; s[4] = '\0'; if(ChgDir(s)==0xff)//没有该目录建立该目录并进入 { CreateDir(s); } ChgDir(s); DIR *ID=(DIR*)&Temp[12]; s[0] = year/1000+0x30; s[1] = (year%1000)/100+0x30; s[2] = ((year%1000)%100)/10+0x30; s[3] = ((year%1000)%100)%10+0x30; s[4]=month/10+0x30; s[5]= month%10+0x30; s[6]= day/10+0x30; s[7]=day%10+0x30; s[8]='D'; s[9]='A'; s[10]='T'; s[11]=0; if(GetFileID(s, ID)==0xffff)//文件不存在建立之并根据config.txt建立该文件的默认头部 { CreateFile(s); pMeasureHead=(MEASURE_HEAD*)Temp; pMeasureHead->DeviceID=pCfgHead->DeviceID; pMeasureHead->BatGrpID=pGrpHead->BatGrpID; pMeasureHead->BatNumbers=pGrpHead->BatNumbers; AppendData(s,(unchar*)pMeasureHead,sizeof (MEASURE_HEAD)); } //判定该组电池今天已经测量了多少块以便进行下面的测量。 Index =(ID->FilePosit.Size-16)/8+1;//已经存在的电池测量数据组 if(Index>=pGrpHead->BatNumbers) { Str_8x16(1,0,"该组已经测量完毕"); Delay_ms(2000); MenuStatus =3; return; } s[0] = Index/1000+0x30; s[1] = (Index%1000)/100+0x30; s[2] = ((Index%1000)%100)/10+0x30; s[3] = ((Index%1000)%100)%10+0x30; s[4] = 0; Str_8x16(0,12,s); //给cy单片机上电打开串口并进行串口初始化; pRecv0Str=&Temp[20];//设置接收缓冲区的地址。 POWRON_CY; Init_Uart0; Uart0RxTimeOut = 0; //等待cy单片机的响应包; while(1) { if(GetKey2( pAck,Temp,10)!=NULL) { //判定得到的数据是否合法 if((Temp[4]==0x04)&&(Temp[5]==0x03)&&(Temp[6]==0x02)&&(Temp[7]==0x01)) { unchar data[4]; data[0] =10;//设定地址为10 data[1] = 0; data[2] = 0; data[3] = 0; SendCmd(SET_ADRESS,0,data); Uart0RxTimeOut =0; } break; } if(Uart0RxTimeOut>=250) { //cy单片机没有响应退出; Str_8x16(1,0,"测量模块没有响应"); Delay_ms(2000); POWROFF_CY; MenuStatus =3; return; } } while(1) { if(GetKey2( pAck,Temp,10)!=NULL)//得到cy的设定地址回应 { if(Temp[2]==10) { break; } break; } if(Uart0RxTimeOut>=250) { //cy单片机没有响应退出; Str_8x16(1,0,"测量模块没有响应"); Delay_ms(2000); POWROFF_CY; MenuStatus =3; return; } } DispFanBai(0,12,4);//电池编号位置加反白; //Index = 1; MenuStatus =2000; break; case UP_KEY: if(Index ==pCfgHead->NumberBatGrps) { Index=1; } else { Index++; } s[0] = Index/1000+0x30; s[1] = (Index%1000)/100+0x30; s[2] = ((Index%1000)%100)/10+0x30; s[3] = ((Index%1000)%100)%10+0x30; s[4] = '\0'; Str_8x16(0,3,s); DispFanBai(0,3,4); break; case DOWN_KEY: if(Index==1) { Index = pCfgHead->NumberBatGrps; } else { Index--; } s[0] = Index/1000+0x30; s[1] = (Index%1000)/100+0x30; s[2] = ((Index%1000)%100)/10+0x30; s[3] = ((Index%1000)%100)%10+0x30; s[4] = '\0'; Str_8x16(0,3,s); DispFanBai(0,3,4); break; case ESC_KEY: break; default: break; } break; case 2000: //开始测量不响应任何按键 //发送测量命令给cy i = 0; while(1) { Uart0RxTimeOut=0; SendCmd(MEASURE_VOLT,10,s); while(1) { if(GetKey2( pAck,Temp,10)!=NULL) { memcpy((unchar*)&fint,&Temp[4],2); f=(float)fint/1000;//注意字节对齐问题; if((f>=pGrpHead->BatVoltMin)&&(f<=pGrpHead->BatVoltMax)) { arf[i]=f; i++; break; } } else if(Uart0RxTimeOut>=250)//超时退出; { //cy单片机没有响应退出; Str_8x16(1,0,"测量模块没有响应"); Delay_ms(2000); POWROFF_CY; MenuStatus =3; return; } } if(i==3) { //已经测量了3次 i =0; float f1 = fabsf(arf[0]-arf[1]); float f2 = fabsf(arf[0]-arf[2]); float f3 = fabsf(arf[2]-arf[1]); if((f1<=0.01)&&(f2<=0.01)&&(f3<=0.01))//比较有效性 { //夹子夹好了并连续得到三次合格的电压值; //退出电压测量进行电阻测量。 //*******************8 //发测量阻值的命令; Uart0RxTimeOut = 0; SendCmd(MEASURE_RES,10,s); DispFanBai(0,12,4);//取消反白。 f=(arf[0]+arf[1]+arf[2])/3; while(1) { if(GetKey2( pAck,Temp,10)!=NULL) { memcpy(Temp,&f,4); memcpy(&fint,&Temp[4],2); fres =(float)fint/1000; memcpy(Temp,&fres,4); // 显示出电压和内阻值; sprintf((char*)s,"%5.3f",f); Str_8x16(1,5,s); Str_8x16(1,5,s); Str_8x16(1,0,"电压:"); Str_8x16(1,10,"V"); sprintf((char*)s,"%5.3f",fres); Str_8x16(2,5,s); Str_8x16(2,0,"内阻:"); Str_8x16(2,10,"mΩ"); //测量结果存储到文件里 s[0] = year/1000+0x30; s[1] = (year%1000)/100+0x30; s[2] = ((year%1000)%100)/10+0x30; s[3] = ((year%1000)%100)%10+0x30; s[4]=month/10+0x30; s[5]= month%10+0x30; s[6]= day/10+0x30; s[7]=day%10+0x30; s[8]='D'; s[9]='A'; s[10]='T'; s[11]=0; AppendData(s,Temp,8); //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //开始下一个电池的测量 // Str_8x16(2,0, "ENT:下一个 ESC:退出"); ClrKeyBuf(); unchar key; s[0] = Index/1000+0x30; s[1] = (Index%1000)/100+0x30; s[2] = ((Index%1000)%100)/10+0x30; s[3] = ((Index%1000)%100)%10+0x30; s[4] = 0; Str_8x16(0,12,s); DispFanBai(0,12,4); //测完了当前电池再次反白此电池表明测量完 while(1)//等待用户操作; { KeyScan(); key=GetKey1(); if(key==ENTER_KEY) { if(Index==pGrpHead->BatNumbers) { //测到了最后一块电池退出系统。 Str_8x16(1,0,"整组测量完毕"); Delay_ms(2000); POWROFF_CY; MenuStatus =3; return; } else { Index++; } s[0] = Index/1000+0x30; s[1] = (Index%1000)/100+0x30; s[2] = ((Index%1000)%100)/10+0x30; s[3] = ((Index%1000)%100)%10+0x30; s[4] = 0; Str_8x16(0,12,s); Str_8x16(0,12,s); DispFanBai(0,12,4); Str_8x16(1,0," "); Str_8x16(2,0," "); Uart0RxTimeOut=0; break; } else if(key==ESC_KEY) { Delay_ms(2000); POWROFF_CY; MenuStatus =3; return; } //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ } break;//退出测量阻值的应答循环。 } else if(Uart0RxTimeOut>=250)//超时退出; { //cy单片机没有响应退出; Str_8x16(1,0,"测量模块没有响应"); Delay_ms(2000); POWROFF_CY; MenuStatus =3; return; } } //*************************************** //break; } else { //判定为夹子没有夹好 Str_8x16(3,0,"没夹好请重新测量"); unchar key; while(1) { KeyScan(); key=GetKey1(); if(key==ENTER_KEY) { i=0; Str_8x16(3,0," "); break;//继续重试当前电池的测量 } else if(key==ESC_KEY) //放弃对当前电池测量因为这个电池可能已经坏了接着测下面的电池。 { i =0; //先占据文件相应的位置等将来进行单独测量。 s[0] = year/1000+0x30; s[1] = (year%1000)/100+0x30; s[2] = ((year%1000)%100)/10+0x30; s[3] = ((year%1000)%100)%10+0x30; s[4]=month/10+0x30; s[5]= month%10+0x30; s[6]= day/10+0x30; s[7]=day%10+0x30; s[8]='D'; s[9]='A'; s[10]='T'; for (unchar j=0;j<8;j++) Temp[j]=0; AppendData(s,Temp,8); if(Index < pGrpHead->BatNumbers) { Index++; Str_8x16(3,0,"跳过测量下一只 "); } else { //测量完毕; Str_8x16(1,0,"整组测量完毕"); Delay_ms(2000); POWROFF_CY; MenuStatus =3; return; } s[0] = Index/1000+0x30; s[1] = (Index%1000)/100+0x30; s[2] = ((Index%1000)%100)/10+0x30; s[3] = ((Index%1000)%100)%10+0x30; s[4] = 0; Str_8x16(0,12,s); DispFanBai(0,12,4); } } // break; } // break; } } default: break; } }
int Chip8Emulate(void) { uint16_t opcode; uint8_t op1, op2; uint8_t vx,vy; uint8_t invalidOp; char tmps[20]; uint8_t i; uint16_t j; invalidOp=0; for(;;){ op1=c8ram[c8pc]; op2=c8ram[c8pc+1]; vx=op1&0x0F; vy=(op2>>4)&0x0F; opcode=(op1<<8)+op2; KeyScan(); if (keysX&KEY_MU) return KEY_MU; if (chip8debug>0) { if (keysX&KEY_PLUS) c8dt=2; OledXY(0,0); sprintf(tmps,"%04x:%04x %02x %02x",c8pc, opcode, c8dt, c8st); OledString(tmps); OledXY(0,6); sprintf(tmps,"%02x%02x%02x%02x%02x%02x%02x%02x",c8reg[0],c8reg[1],c8reg[2],c8reg[3],c8reg[4],c8reg[5],c8reg[6],c8reg[7]); OledString(tmps); OledXY(0,7); sprintf(tmps,"%02x%02x%02x%02x%02x%02x%02x%02x",c8reg[8],c8reg[9],c8reg[10],c8reg[11],c8reg[12],c8reg[13],c8reg[14],c8reg[15]); OledString(tmps); __delay_ms(100); } __delay_us(100); c8pc+=2; switch (opcode&0xF000) { case 0x0000: switch (opcode&0x00FF) { //---------------------------------------------------------------------------- case 0xE0: // 00E0 - CLS Clear the display. for (i=0; i<sizeof(c8screen); i++) { c8screen[i]=0x00; } Chip8RefreshScreen(); break; //---------------------------------------------------------------------------- case 0xEE: // 00EE - RET Return from a subroutine. // The interpreter sets the program counter to the // address at the top of the stack, then subtracts 1 // from the stack pointer. c8pc=c8stack[c8sp]; c8sp--; break; default: invalidOp=1; } break; //---------------------------------------------------------------------------- case 0x1000: // 1nnn - JP addr Jump to location nnn. // The interpreter sets the program counter to nnn. c8pc=opcode&0x0FFF; break; //---------------------------------------------------------------------------- case 0x2000: // 2nnn - CALL addr Call subroutine at nnn. // The interpreter increments the stack pointer, then puts the // current PC on the top of the stack. The PC is then set to nnn c8sp++; c8stack[c8sp]=c8pc; c8pc=opcode&0xFFF; break; //---------------------------------------------------------------------------- case 0x3000: // 3xkk - SE Vx, byte - Skip next instruction if Vx = kk. // The interpreter compares register Vx to kk, and if they are // equal, increments the program counter by 2. if (c8reg[vx]==op2) c8pc+=2; break; //---------------------------------------------------------------------------- case 0x4000: // 4xkk - SNE Vx, byte - Skip next instruction if Vx != kk. // The interpreter compares register Vx to kk, and if they are // not equal, increments the program counter by 2. if (c8reg[vx]!=op2) c8pc+=2; break; case 0x5000: switch (opcode&0x000F) { //---------------------------------------------------------------------------- case 0x00: // 5xy0 - SE Vx, Vy - Skip next instruction if Vx = Vy. // The interpreter compares register Vx to register // Vy, and if they are equal, increments the program // counter by 2. if (c8reg[vx]==c8reg[vy]) c8pc+=2; break; default: invalidOp=1; } break; //---------------------------------------------------------------------------- case 0x6000: // 6xkk - LD Vx, byte Set Vx = kk. // The interpreter puts the value kk into register Vx. c8reg[vx]=op2; break; //---------------------------------------------------------------------------- case 0x7000: // 7xkk - ADD Vx, byte Set Vx = Vx + kk. // Adds the value kk to the value of register Vx, then stores // the result in Vx. c8reg[vx]+=op2; break; case 0x8000: switch (opcode&0x000F) { //---------------------------------------------------------------------------- case 0x00: // 8xy0 - LD Vx, Vy Set Vx = Vy. // Stores the value of register Vy in register Vx. c8reg[vx]=c8reg[vy]; break; //---------------------------------------------------------------------------- case 0x01: // 8xy1 - OR Vx, Vy - Set Vx = Vx OR Vy. // Performs a bitwise OR on the values of Vx and Vy, // then stores the result in Vx. c8reg[vx]|=c8reg[vy]; break; //---------------------------------------------------------------------------- case 0x02: // 8xy2 - AND Vx, Vy Set Vx = Vx AND Vy. // Performs a bitwise AND on the values of Vx and Vy, // then stores the result in Vx. c8reg[vx]&=c8reg[vy]; break; //---------------------------------------------------------------------------- case 0x03: // 8xy3 - XOR Vx, Vy - Set Vx = Vx XOR Vy. // Performs a bitwise exclusive OR on the values of Vx // and Vy, then stores the result in Vx. c8reg[vx]^=c8reg[vy]; break; //---------------------------------------------------------------------------- case 0x04: // 8xy4 - ADD Vx, Vy Set Vx = Vx + Vy, set VF = carry. // The values of Vx and Vy are added together. If the // result is greater than 8 bits (i.e., > 255,) VF is // set to 1, otherwise 0. Only the lowest 8 bits of the // result are kept, and stored in Vx. c8reg[15]=0; if (c8reg[vx]+c8reg[vy]>255) c8reg[15]=1; c8reg[vx]+=c8reg[vy]; break; //---------------------------------------------------------------------------- case 0x05: // 8xy5 - SUB Vx, Vy Set Vx = Vx - Vy, set VF = NOT borrow. // If Vx > Vy, then VF is set to 1, otherwise 0. Then // Vy is subtracted from Vx, and the results stored in Vx. c8reg[15]=0; if (c8reg[vx]>c8reg[vy]) c8reg[15]=1; c8reg[vx]-=c8reg[vy]; break; //---------------------------------------------------------------------------- case 0x06: // 8xy6 - SHR Vx {, Vy} Set Vx = Vx SHR 1. // If the least-significant bit of Vx is 1, then VF // is set to 1, otherwise 0. Then Vx is divided by 2. c8reg[15]=0; if ((c8reg[vx]&0x01)==0x01) c8reg[15]=1; c8reg[vx]/=2; break; //---------------------------------------------------------------------------- case 0x07: // 8xy7 - SUBN Vx, Vy Set Vx = Vy - Vx, set VF = NOT borrow. // If Vy > Vx, then VF is set to 1, otherwise 0. Then // Vx is subtracted from Vy, and the results stored in Vx. c8reg[15]=0; if (c8reg[vy]>c8reg[vx]) c8reg[15]=1; c8reg[vx]=c8reg[vy]-c8reg[vx]; break; //---------------------------------------------------------------------------- case 0x0E: // 8xyE - SHL Vx {, Vy} Set Vx = Vx SHL 1. // If the most-significant bit of Vx is 1, then VF is // set to 1, otherwise to 0. Then Vx is multiplied by 2. c8reg[15]=0; if ((c8reg[vx]&0x80)==0x80) c8reg[15]=1; c8reg[vx]*=2; break; default: invalidOp=1; } break; case 0x9000: switch (opcode&0x000F) { //---------------------------------------------------------------------------- case 0x00: // 9xy0 - SNE Vx, Vy Skip next instruction if Vx != Vy. // The values of Vx and Vy are compared, and if they // are not equal, the program counter is increased by 2. if (c8reg[vx]!=c8reg[vy]) c8pc+=2; break; default: invalidOp=1; } break; //---------------------------------------------------------------------------- case 0xA000: // Annn - LD I, addr Set I = nnn. // The value of register I is set to nnn. c8i=opcode&0x0FFF; break; //---------------------------------------------------------------------------- case 0xB000: // Bnnn - JP V0, addr Jump to location nnn + V0. // The program counter is set to nnn plus the value of V0. c8pc=(opcode&0x0FFF)+c8reg[0]; break; //---------------------------------------------------------------------------- case 0xC000: // Cxkk - RND Vx, byte - Set Vx = random byte AND kk. // The interpreter generates a random number from 0 to 255, // which is then ANDed with the value kk. The results are stored // in Vx. c8reg[vx]=rand()&op2; break; //---------------------------------------------------------------------------- case 0xD000: C8DRWvx_vy_nib(vx,vy,opcode&0x0F); break; case 0xE000: switch (opcode&0x00FF) { //---------------------------------------------------------------------------- case 0x9E: // Ex9E - SKP Vx Skip next instruction if key with the value of Vx is pressed. // Checks the keyboard, and if the key corresponding // to the value of Vx is currently in the down position // PC is increased by 2. if (keys&(1UL<<c8reg[vx])) c8pc+=2; break; //---------------------------------------------------------------------------- case 0xA1: // ExA1 - SKNP Vx Skip next instruction if key with the value of Vx is not pressed. // Checks the keyboard, and if the key corresponding to // the value of Vx is currently in the up position, //PC is increased by 2. if (!(keys&(1UL<<c8reg[vx]))) c8pc+=2; break; default: invalidOp=1; } break; case 0xF000: switch (opcode&0x00FF) { //---------------------------------------------------------------------------- case 0x07: // Fx07 - LD Vx, DT Set Vx = delay timer value. // The value of DT is placed into Vx. c8reg[vx]=c8dt; break; //---------------------------------------------------------------------------- case 0x0A: // Fx0A - LD Vx, K Wait for a key press, store the value of the key in Vx. // All execution stops until a key is pressed, then // the value of that key is stored in Vx. if (keys==0) { c8pc-=2; // if no key is pressed then set the // Program Counter back to this instruction again } else { if (keys==0x0001) c8reg[vx]=0; if (keys==0x0002) c8reg[vx]=1; if (keys==0x0004) c8reg[vx]=2; if (keys==0x0008) c8reg[vx]=3; if (keys==0x0010) c8reg[vx]=4; if (keys==0x0020) c8reg[vx]=5; if (keys==0x0040) c8reg[vx]=6; if (keys==0x0080) c8reg[vx]=7; if (keys==0x0100) c8reg[vx]=8; if (keys==0x0200) c8reg[vx]=9; if (keys==0x0400) c8reg[vx]=10; if (keys==0x0800) c8reg[vx]=11; if (keys==0x1000) c8reg[vx]=12; if (keys==0x2000) c8reg[vx]=13; if (keys==0x4000) c8reg[vx]=14; if (keys==0x8000) c8reg[vx]=15; } break; //---------------------------------------------------------------------------- case 0x15: // Fx15 - LD DT, Vx Set delay timer = Vx. // DT is set equal to the value of Vx. c8dt=c8reg[vx]; break; //---------------------------------------------------------------------------- case 0x18: // Fx18 - LD ST, Vx Set sound timer = Vx. // ST is set equal to the value of Vx. c8st=c8reg[vx]; break; //---------------------------------------------------------------------------- case 0x1E: // Fx1E - ADD I, Vx Set I = I + Vx. // The values of I and Vx are added, and the results // are stored in I. c8i+=c8reg[vx]; break; //---------------------------------------------------------------------------- case 0x29: // Fx29 - LD F, Vx Set I = location of sprite for digit Vx. // The value of I is set to the location for the // hexadecimal sprite corresponding to the value of Vx. // See section 2.4, Display, for more information on the // Chip-8 hexadecimal font. c8i=0x50+(vx)*5; break; //---------------------------------------------------------------------------- case 0x33: // Fx33 - LD B, Vx - Store BCD valye of Vx in memory locations I,I+1,I+2. // The interpreter takes the decimal value of Vx, and // places the hundreds digit in memory at location in I, // the tens digit at location I+1, and the ones digit // at location I+2. c8ram[c8i ]=(vx/100)%10; c8ram[c8i+1]=(vx/10)%10; c8ram[c8i+2]=(vx)%10; break; //---------------------------------------------------------------------------- case 0x55: // Fx55 - LD [I], Vx Store registers V0 through Vx in memory starting at location I. // The interpreter copies the values of registers V0 // through Vx into memory, starting at the address in I. for(j=0; j<=(vx); j++) { c8ram[c8i+j]=c8reg[j]; } break; //---------------------------------------------------------------------------- case 0x65: // Fx65 - LD Vx, [I] Read registers V0 through Vx from memory starting at location I. // The interpreter reads values from memory starting // at location I into registers V0 through Vx. for(j=0; j<=(vx); j++) { c8reg[j]=c8ram[c8i+j]; } break; default: invalidOp=1; } break; } if (invalidOp) { invalidOp=0; OledXY(0,7); sprintf((char *)tmps,"Err! %04x @ %04x",opcode,c8pc); OledString(tmps); OledRefresh(); } } // for(;;) return 0; }