/*
**	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);
		}
	}
}
Beispiel #2
0
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);
	}
}
Beispiel #3
0
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]; 	 
  }
}
Beispiel #5
0
/********************************************************************
* 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 */
}
Beispiel #6
0
// 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;
	}	
}
Beispiel #7
0
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;
   }
}
Beispiel #10
0
//********************************
//		加上延时抖动的读取,一次读取一个
//********************************
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';
	 }
}
Beispiel #11
0
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();
	}
}
Beispiel #13
0
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);//密码错误,提示重新输入
                 
      }

    }    
  }
  
  
}
Beispiel #14
0
/****************************************************************************
* 程序入口函数
****************************************************************************/
void main(void)
{
    InitLed();		      //设置LED1相应的IO口
    InitKey();            //设置S1相应的IO口
    
    while(1)
    {
        if (KeyScan())    //按键按下则改变LED状态
            LED1 = ~LED1;       
    }
}
Beispiel #15
0
/********************************************************************
 * 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
Beispiel #16
0
/*******************************************************************************
* 函 数 名 :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);
	 }
}
Beispiel #17
0
void KeyListened(void) {

    unsigned char sta = KeyStaSwitch(KeyScan());

    switch (sta) {
        case KEY_STA_DOWN : {
            Lock315Assoc();
        } break;
        case KEY_STA_LHOLD : {
            SystemReset();
        } break;
    }
    
}
Beispiel #18
0
/*******************************************************************************
* 函 数 名 :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();
	}
}
Beispiel #20
0
/********************************************************************
函数功能:定时器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();
   }
  }
 }
}
Beispiel #21
0
// 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 --;
    }
  }  
}
Beispiel #22
0
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;
}
Beispiel #23
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  
}
Beispiel #24
0
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); 			
	}
}
Beispiel #25
0
/*******************************************************************************
* 函 数 名 :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();
			}  
		}   
	}
}
Beispiel #26
0
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 ; 
			 }
		 }	
	}
////////////////////////////////////////////////////////




///////////////////////////////////////////////////////

}
Beispiel #27
0
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 ; 
		}
	}
}
Beispiel #28
0
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();
    }
}
Beispiel #29
0
  //**************************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;
 } 
}
Beispiel #30
0
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;
}