⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keypad.c

📁 GM5621原代码
💻 C
📖 第 1 页 / 共 4 页
字号:
   // code is greater than ADC
   SBYTE SB_Ret = 1;
   BYTE  diff;
   
   if (B_TableCode > B_Value)
   {
      diff = B_TableCode - B_Value;
      SB_Ret = -1;
   }
   else
      diff = B_Value - B_TableCode;
         
   if ( diff <= ADC_DELTA)
      SB_Ret = 0;

   return SB_Ret;
}
#endif //LBADC_USED


//******************************************************************************
//
// FUNCTION:   static KEY_INDEX TranslateADCKey(BYTE B_KeyPort)
// USAGE:      Comparing ADC value with table code by the method binary tree
//
// INPUT:      B_KeyPort - ADC key port number
//                   ADC_KEY1,ADC_KEY2,ADC_KEY3
// OUTPUT:      KEY_INDEX - id pushed key
//          If none of the key is pressed, return value Key_None
// GLOBALS:    NUMBER_OF_ADC_1Values - number of members in array ADC_1Values[]
//          ADC_1Values - translating ADC code to id key.
// USED_REGS:   None
//
//******************************************************************************
#if LBADC_USED
static gmt_KEY_INDEX __near TranslateADCKey(BYTE B_KeyPort)
{
   BYTE   B_Value;
   SBYTE  SB_Result;
   SWORD  B_Offset, B_Max, B_Min = 0;
   ST_ADC ROM  *ADC_Values;

#ifdef PORT_ADC_1_USED
   if (B_KeyPort == ADC_KEY1)
   {
      B_Max = NUMBER_OF_ADC_1Values - 1;
      B_Value  = KeyFilter(0,ScanAdcKey(LBADC_IN1));
      ADC_Values = ADC_1Values;
      }
#endif

#ifdef PORT_ADC_2_USED
   if (B_KeyPort == ADC_KEY2)
   {
      B_Max = NUMBER_OF_ADC_2Values - 1;
      B_Value  = KeyFilter(0,ScanAdcKey(LBADC_IN2));
      ADC_Values = ADC_2Values;
   }
#endif

#ifdef PORT_ADC_3_USED
   if (B_KeyPort == ADC_KEY3)
   {
      B_Max = NUMBER_OF_ADC_3Values - 1;
      B_Value  = KeyFilter(0,ScanAdcKey(LBADC_IN3));
      ADC_Values = ADC_3Values;
      }
#endif

   if (B_KeyPort >= MAX_ADC_KEY)
      return Key_None;

   // By comment out KeyDataPresent, which means:
   // Always searching keys no matter whether key is pressed or not. By doing this way,
   //then we don't have to assign any scancode for Key_None and any scancode can be used
   //as a valid scancode (even 0 or 0xff, previous assumed for Key_None).
   //
// if (KeyDataPresent(B_Value))
   {
      // Do a binary tree search of all the ADC1 values until we find the
      // real key value where our read value falls into the range of and
      // return this real value
      // If B_Min goes past B_Max, then no corresponding code was found so
      // we return Key_None.
      //
      while(B_Min <= B_Max)
      {
         B_Offset = ((WORD)B_Max + B_Min) / 2;
         //
         // Check if the value falls within the range of the current ADC
         // value we are pointing at.
         //
         SB_Result = CheckADCCode(ADC_Values[B_Offset].Code, B_Value);

         // Got a match, so we can return the value.
         //
         if (SB_Result == 0)
         {
            return(ADC_Values[B_Offset].KeyIndex);
         }
            else
         {
            if (SB_Result < 0)
               B_Max = B_Offset - 1;
                else
                  B_Min = B_Offset + 1;
         }
      }
   }
   return Key_None;
}
#endif //LBADC_USED


//******************************************************************************
//
// FUNCTION:   static KEY_VALUE ReadKey (void)
// USAGE:      Scan key state in each of the three LBADC channels (if used).
//          Note that:
//             KeyDataPresent(B_Key) should be redefined in cases where a
//             pull-up scheme is used for key detection (ie. a key press
//             brings the ADC return value closer to GND).
//             For special (noise) filtering, KeyFilter should be redefined
//             to reference the filtering function (eg. majority filter),
//             which takes as parameters the ADC input channel and the raw
//          ADC value.
//          To customize key filtering, compile using CUSTOM_ADCKEYFILTERING
//
// INPUT:      None
// OUTPUT:     KEY_VALUE - Bit 15 to Bit 13 is input source and
//                       - the rest is the data value from IR.
//             If none of the key is pressed, return value 0.
// GLOBALS:    B_ScanCode,B_LastKeyType, NUMBER_OF_ADC_1Values,
//          NUMBER_OF_ADC_2Values, NUMBER_OF_ADC_3Values,
//          NUMBER_OF_MultiplePortsValuesTranslation
// USED_REGS:  None
//
//******************************************************************************
#if USE_GETKEY_TIMER_ISR
struct
{
   BYTE useIsr;
   BYTE keyHead;
   BYTE keyTail;
   gmt_KEY_INDEX keyArray[13];
}IsrKeyStruct = {gmd_FALSE};

static gmt_KEY_INDEX __near ReadKey(void)
#else
gmt_KEY_INDEX far GetKey(void)
#endif
{
   gmt_KEY_INDEX  B_KeyCode = Key_None;
   gmt_KEY_INDEX  *Bp_ScanCode = B_ScanCode;
#if (USE_GPIO_KEYPAD | LBADC_USED | defined(PORT_IR_USED))
   BYTE     B_Key;
   BYTE     B_CountKey = 0;
#endif

#if defined(USE_EXTERNAL_KEY_HANDLER) && (USE_EXTERNAL_KEY_HANDLER)
   *Bp_ScanCode = B_Key = TranslateExternalKey();
   if (B_Key != Key_None)
   {
      B_LastKeyType = GPIO_KEY;
      B_KeyCode = B_Key;
      B_CountKey++;
   }
#else
   *Bp_ScanCode = Key_None;
#endif //USE_EXTERNAL_KEY_HANDLER
   Bp_ScanCode++;


#if USE_GPIO_KEYPAD
   #if (WB_MAJOR == 3) && (WB_MINOR == 1) && (WB_REVISION == 1)
      // For WB version 3.1.1.10 NUMBER_OF_SCAN_KEY is a ROM constant, so
      // us it in a regular runtime 'if' statement.
      // Get GPIO keypad key.
      // If any GPIO keys are mapped then we need to check GPIO keypad
      if (NUMBER_OF_SCAN_KEY)
      {
         *Bp_ScanCode = B_Key = TranslateGPIOKey();
         if (B_Key != Key_None)
         {
            B_LastKeyType = GPIO_KEY;
            B_KeyCode = B_Key;
            B_CountKey++;
         }
      }
       else
      {
         *Bp_ScanCode = Key_None;
      }
   #else // WB != 3.1.1x
      // For WB versions later than 3.1.1.10 NUMBER_OF_SCAN_KEY is a #define,
      // so us it in a compile time #if statement.
      // Get GPIO keypad key.
      // If any GPIO keys are mapped then we need to check GPIO keypad
      #if (NUMBER_OF_SCAN_KEY)
      {
         *Bp_ScanCode = B_Key = TranslateGPIOKey();
         if (B_Key != Key_None)
         {
            B_LastKeyType = GPIO_KEY;
            B_KeyCode = B_Key;
            B_CountKey++;
         }
      }
      #else
      {
         *Bp_ScanCode = Key_None;
      }
      #endif //NUMBER_OF_SCAN_KEY
   #endif //WB == 3.1.1.x
#else
   *Bp_ScanCode = Key_None;
#endif //USE_GPIO_KEYPAD
   Bp_ScanCode++;


#ifdef PORT_ADC_1_USED
   // Get key from multimedia keypad channel1
   // If any ADC_1 keys are mapped, then we need to check ADC1
   if (NUMBER_OF_ADC_1Values)
   {
      *Bp_ScanCode = B_Key = TranslateADCKey(ADC_KEY1);
      if (B_Key != Key_None)
      {
         B_LastKeyType = ADC_KEY;
         B_KeyCode = B_Key;
         B_CountKey++;
      }
   }
    else
      *Bp_ScanCode = Key_None;
#else
   *Bp_ScanCode = Key_None;
#endif
   Bp_ScanCode++;


#ifdef PORT_ADC_2_USED
   // Get key from multimedia keypad channel2
   // If any ADC_2 keys are mapped, then we need to check ADC2
   if (NUMBER_OF_ADC_2Values)
   {
      *Bp_ScanCode = B_Key = TranslateADCKey(ADC_KEY2);
      if (B_Key != Key_None)
      {
         B_LastKeyType = ADC_KEY;
         B_KeyCode = B_Key;
         B_CountKey++;
      }
   }
    else
      *Bp_ScanCode = Key_None;
#else
   *Bp_ScanCode = Key_None;
#endif
   Bp_ScanCode++;


#ifdef PORT_ADC_3_USED
   // Get key from multimedia keypad channel3
   // If any ADC_3 keys are mapped, then we need to check ADC3
   if (NUMBER_OF_ADC_3Values)
   {
      *Bp_ScanCode = B_Key = TranslateADCKey(ADC_KEY3);
      if (B_Key != Key_None)
      {
         B_LastKeyType = ADC_KEY;
         B_KeyCode = B_Key;
         B_CountKey++;
      }
   }
    else
      *Bp_ScanCode = Key_None;
#else
   *Bp_ScanCode = Key_None;
#endif
   Bp_ScanCode++;


#ifdef PORT_IR_USED
   // Get IR remote key.
   // If any IR keys are mapped, then we need to check IR
   if (NUMBER_OF_IRValues)
   {
      *Bp_ScanCode = B_Key = TranslateIrKey();
      if (B_Key != Key_None)
      {
         B_LastKeyType = IR_KEY;
         B_KeyCode = B_Key;
         B_CountKey++;
      }
   } else
   {
      *Bp_ScanCode = Key_None;
   }
#else
   *Bp_ScanCode = Key_None;
#endif
   Bp_ScanCode++;


#if WB_NUMBER_OF_INPUT_SOURCE > 1
   //
   // Get Multiple Ports keypad key.
   //
   if (B_CountKey > 1)
   {
      B_KeyCode = Key_None;
      if(NUMBER_OF_MultiplePortsValuesTranslation)
      {
            BYTE B_CountI;
         for (B_CountI = 0; B_CountI < NUMBER_OF_MultiplePortsValuesTranslation; B_CountI++)
         {
            BYTE B_Found = 0xff;
               BYTE B_CountJ;
            for (B_CountJ = 0; B_CountJ < NUMBER_OF_INPUT_SOURCE; B_CountJ++)
            {
               B_Found &= MultiplePortsValuesTranslation[B_CountI].Codes[B_CountJ] == B_ScanCode[B_CountJ];
            }
            if (B_Found)
            {
               B_KeyCode = MultiplePortsValuesTranslation[B_CountI].KeyIndex;
               break;
            }
         }
      }
   }
#endif

   #if DEBUG_INPUT
      if (B_KeyCode)
         msg("KeyValue = %d", B_KeyCode);
   #endif
#if USE_GETKEY_TIMER_ISR
   // don't allow array to fill up with same key elements.
   if(IsrKeyStruct.useIsr == gmd_TRUE)
   {
      BYTE i;
      BYTE tempHead = IsrKeyStruct.keyHead;
      for(i=0;i<2;i++)
      {
         tempHead--;
         if(tempHead >= sizeof(IsrKeyStruct.keyArray))
            tempHead = sizeof(IsrKeyStruct.keyArray) - 1;

         if(B_KeyCode != IsrKeyStruct.keyArray[tempHead])
            break;
      }
      if(i>=2)
      {// return so long as tail hasn't caught up.
         if(abs(IsrKeyStruct.keyTail - IsrKeyStruct.keyHead) > 2)
            return B_KeyCode;
      }
      IsrKeyStruct.keyArray[IsrKeyStruct.keyHead] = B_KeyCode;
      IsrKeyStruct.keyHead++;
      if(IsrKeyStruct.keyHead >= sizeof(IsrKeyStruct.keyArray))
         IsrKeyStruct.keyHead = 0;
   }
#endif
   return B_KeyCode;
}

#if USE_GETKEY_TIMER_ISR

gmt_KEY_INDEX far GetKey(void)
{
   BYTE key = Key_None;
   
   if(IsrKeyStruct.keyHead != IsrKeyStruct.keyTail)
   {
      key = IsrKeyStruct.keyArray[IsrKeyStruct.keyTail];

      IsrKeyStruct.keyTail++;
      if(IsrKeyStruct.keyTail >= sizeof(IsrKeyStruct.keyArray))
         IsrKeyStruct.keyTail = 0;
   }
   else if((IsrKeyStruct.useIsr == gmd_FALSE))
      key = ReadKey();

   return key;
}
//******************************************************************
// FUNCTION       :  StartGetKeyISR/StopGetKeyISR
// DESCRIPTION    :  Functions set up an interrupt and chain it to
//    the system timer which already gives us a 1ms tick.  Upon the
//    GETKEY_TIME_MS time in the ISR, ReadKey() is called to
//    read all the keypad devices and store the scan key code into
//    IsrKeyStruct.keyArray[]
//******************************************************************
void far interrupt (*OldTimerIsr)(void);
void far interrupt GetKeyISR(void)
{
   static WORD i=0;

#if (GET_KEY_TIMER_ISR == TIMER2_VECTOR)
   if(i++ >= GETKEY_TIME_MS)
   {
      ReadKey();
      i = 0;
   }
   OldTimerIsr();
#elif (GET_KEY_TIMER_ISR == TIMER1_VECTOR)
   if(i++ >= (GETKEY_TIME_MS / 2) - 1) // timer0 runs at half the speed.
   {
      ReadKey();
      i = 0;
   }
   CLEAR_PCB_REG_BITS(T1CON, MC);
   WRITE_PCB_REG(EOI, TIMER1_VTYPE);
#elif (GET_KEY_TIMER_ISR == TIMER0_VECTOR)
   if(i++ >= (GETKEY_TIME_MS / 2) - 1) // timer0 runs at half the speed.
   {
      ReadKey();
      i = 0;
   }
   CLEAR_PCB_REG_BITS(T0CON, MC);
   WRITE_PCB_REG(EOI, TIMER0_VTYPE);
#endif

}

void StartGetKeyISR(void)
{
#if (GET_KEY_TIMER_ISR != TIMER2_VECTOR)
   WORD W_Tmo = READ_PCB_REG(T2CMPA);
#endif
   IsrKeyStruct.keyHead = 0;
   IsrKeyStruct.keyTail = 0;
   IsrKeyStruct.useIsr = gmd_TRUE;
   msg("** Start GetKeyISR **",0);
   gm_DisableInterrupts();
#if (GET_KEY_TIMER_ISR == TIMER2_VECTOR)
   if((void far interrupt (*)(void))GET_VECTOR(TIMER2_VECTOR) != GetKeyISR)
   {
      OldTimerIsr = (void far interrupt (*)(void))GET_VECTOR(TIMER2_VECTOR);
      SET_VECTOR(TIMER2_VECTOR, GetKeyISR);
   }
#elif (GET_KEY_TIMER_ISR == TIMER1_VECTOR)
   // Timer2 is used as 1ms. interrupt.  Just read Timer2 compare
   // register and multiply by GETKEY_TIME_MS to get desired Timer1
   // compare value.  Run T1 at half the speed.
   WRITE_PCB_REG(T1CMPA, (W_Tmo * 2));   // Configure timer1 value
   WRITE_PCB_REG(T1CNT, 0);              // Clear counter
   SET_VECTOR(TIMER1_VECTOR, GetKeyISR);
   WRITE_PCB_REG(T1CON, (EN|INH|INT|CONT));
#elif (GET_KEY_TIMER_ISR == TIMER0_VECTOR)
   // Timer2 is used as 1ms. interrupt.  Just read Timer2 compare
   // register and multiply by GETKEY_TIME_MS to get desired Timer0
   // compare value.  Run T0 at half the speed.
   WRITE_PCB_REG(T0CMPA, (W_Tmo * 2));   // Configure timer0 value
   WRITE_PCB_REG(T0CNT, 0);              // Clear counter
   SET_VECTOR(TIMER0_VECTOR, GetKeyISR);
   WRITE_PCB_REG(T0CON, (EN|INH|INT|CONT));
#endif

   asm{ STI };
}
void StopGetKeyISR(void)
{
   msg("** Stop GetKeyISR **",0);
#if (GET_KEY_TIMER_ISR == TIMER2_VECTOR)
   gm_DisableInterrupts();
   SET_VECTOR(TIMER2_VECTOR,OldTimerIsr);
   asm{ STI };
#elif (GET_KEY_TIMER_ISR == TIMER1_VECTOR)
   // stop timer.
   WRITE_PCB_REG(T1CON, (INH|INT|CONT));
#elif (GET_KEY_TIMER_ISR == TIMER0_VECTOR)
   // stop timer.
   WRITE_PCB_REG(T0CON, (INH|INT|CONT));
#endif
   IsrKeyStruct.useIsr = gmd_FALSE;
}
#endif


#endif

#undef __KEYPAD_C__

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -