旋钮的处理方式
- 正交解码(原理是相位差):适合精度要求高的场合,测速;
- IO读取相位差的高低电平(原理是相位差):比较浪费资源,精度不是最高;
- 硬件配置A、B相高低不同有序电平,读取AD值(不同旋转方向有序电平):精度差,适合对精度要求不高的场合。
/******************** (C) COPYRIGHT 2011 APTENON ********************
* File Name : key.c
* Author : edwin kang
* Version : V0.0
* Date : 11/30/2011
* Description : key file.
*******************************************************************************/
#define _KEY_C_
#include "includes.h"
#define KEY_NULL 0xFF
/*********************************************
Function: Key_Null
Description:
Write/Modify: edwin
Time: 2011-12-8
*********************************************/
static void Key_Null(BYTE uAction)
{
uAction = uAction;
}
/**************************************************************************/
/**************************************************************************/
static void Key_DVD_Reject(BYTE uAction)
{
if (uAction == 0)
{
}
else if (uAction == 1)
{
}
else if (uAction == 2)
{
}
}
void KEY_MAP(BYTE uAction)
{
if (uAction == 0)
{
}
else if (uAction == 1)
{
}
else if (uAction == 2)
{
}
}
void KEY_Media(BYTE uAction)
{
if (uAction == 0)
{
}
else if (uAction == 1)
{
}
else if (uAction == 2)
{
}
}
void KEY_TEL(BYTE uAction)
{
if (uAction == 0)
{
}
else if (uAction == 1)
{
}
else if (uAction == 2)
{
}
}
void KEY_Menu(BYTE uAction)
{
if (uAction == 0)
{
}
else if (uAction == 1)
{
}
else if (uAction == 2)
{
LF_CanBus_SendControlCmd(key_menu);
}
}
const BYTE SRC_Mode[6] =
{
SYSTEM_MODE_IN_CAR_MEDIA,
SYSTEM_MODE_IN_DVD,
SYSTEM_MODE_IN_mp5_music,
SYSTEM_MODE_IN_AUX,
SYSTEM_MODE_IN_TV,
SYSTEM_MODE_IN_CARREC,
};
void KEY_Radio(BYTE uAction)
{
if (uAction == 0)
{
}
else if (uAction == 1)
{
}
else if (uAction == 2)
{
}
}
void KEY_Enter(BYTE uAction)
{
if (uAction == 0)
{
}
else if (uAction == 1)
{
}
else if (uAction == 2)
{
LF_CanBus_SendControlCmd(key_enter);
}
}
void KEY_Back(BYTE uAction)
{
if (uAction == 0)
{
}
else if (uAction == 1)
{
}
else if (uAction == 2)
{
LF_CanBus_SendControlCmd(key_back);
}
}
void KEY_Option(BYTE uAction)
{
if (uAction == 0)
{
}
else if (uAction == 1)
{
}
else if (uAction == 2)
{
}
}
/**************************************************************************/
/**************************************************************************/
void KEY_Up(BYTE uAction)
{
if (uAction == 0)
{
}
else if (uAction == 1)
{
}
else if (uAction == 2)
{
LF_CanBus_SendControlCmd(key_up);
}
}
void KEY_Dn(BYTE uAction)
{
if (uAction == 0)
{
}
else if (uAction == 1)
{
}
else if (uAction == 2)
{
LF_CanBus_SendControlCmd(key_down);
}
}
void KEY_Left(BYTE uAction)
{
if (uAction == 0)
{
}
else if (uAction == 1)
{
}
else if (uAction == 2)
{
LF_CanBus_SendControlCmd(key_left);
}
}
void KEY_Right(BYTE uAction)
{
if (uAction == 0)
{
}
else if (uAction == 1)
{
}
else if (uAction == 2)
{
LF_CanBus_SendControlCmd(key_right);
}
}
#if 0
static const KEY_DEFINE KEY_TAB[4][5] =
{
{
{
0, 100, Key_DVD_Reject
}
,
{
0, 0, Key_Null
}
,
{
0, 0, Key_Null
}
,
{
0, 0, Key_Null
}
,
{
3300, 3300, Key_Null
}
,
}
,
{
{
0, 0, Key_Null
}
,
{
0, 0, Key_Null
}
,
{
0, 0, Key_Null
}
,
{
0, 0, Key_Null
}
,
{
3300, 3300, Key_Null
}
,
}
,
{
{
0, 0, Key_Null
}
,
{
0, 0, Key_Null
}
,
{
0, 0, Key_Null
}
,
{
0, 0, Key_Null
}
,
{
3300, 3300, Key_Null
}
,
}
,
{
{
0, 0, Key_Null
}
,
{
0, 0, Key_Null
}
,
{
0, 0, Key_Null
}
,
{
0, 0, Key_Null
}
,
{
3300, 3300, Key_Null
}
,
}
,
};
#else
#define VoltageDeta 100
static const KEY_DEFINE KEY_TAB[4][8] =
{
{
{
329-VoltageDeta, 329+VoltageDeta, KEY_Up
}
,
{
1716-VoltageDeta, 1716+VoltageDeta, KEY_Dn
}
,
{
1043-VoltageDeta, 1043+VoltageDeta, KEY_Left
}
,
{
2500-VoltageDeta, 2500+VoltageDeta, KEY_Right
}
,
{
2983-VoltageDeta, 2983+VoltageDeta, KEY_Enter
}
,
{
666-VoltageDeta, 666+VoltageDeta, KEY_Menu
}
,
{
2144-VoltageDeta, 2144+VoltageDeta, KEY_Back
}
,
{
3300, 3300, Key_Null
}
,
}
,
{
{
0, 0, Key_Null
}
,
{
0, 0, Key_Null
}
,
{
0, 0, Key_Null
}
,
{
0, 0, Key_Null
}
,
{
3300, 3300, Key_Null
}
,
}
,
{
{
0, 0, Key_Null
}
,
{
0, 0, Key_Null
}
,
{
0, 0, Key_Null
}
,
{
0, 0, Key_Null
}
,
{
3300, 3300, Key_Null
}
,
}
,
{
{
0, 0, Key_Null
}
,
{
0, 0, Key_Null
}
,
{
0, 0, Key_Null
}
,
{
0, 0, Key_Null
}
,
{
3300, 3300, Key_Null
}
,
}
,
};
#endif
static u8 GetKeyPos(u16 keyVoltage, u8 uKeyGroup);
/***************************************KEY START ***********************************/
/*********************************************
Function: Key_Dispatch
Description: read opration code
Write/Modify: edwin
Time: 2011-12-8
*********************************************/
u16 GetVotFromAD(u16 u16AD)
{
u16 temp;
temp = u16AD;
temp = (u16)((((u32)temp) * 3300) >> 12);
return temp;
}
/**************************************************************************/
/**************************************************************************/
static u8 GetKeyPos(u16 keyVoltage, u8 uKeyGroup)
{
u8 i;
for (i = 0; KEY_TAB[uKeyGroup][i].keyVoltage_high != 3300 &&
KEY_TAB[uKeyGroup][i].keyVoltage_low != 3300; i++)
{
if (keyVoltage >= KEY_TAB[uKeyGroup][i].keyVoltage_low && keyVoltage <=
KEY_TAB[uKeyGroup][i].keyVoltage_high)
{
return i;
}
}
return KEY_NULL;
}
/**************************************************************************/
/**************************************************************************/
void Key_Dispatch(void)
{
u8 u8Key1Pos, u8Key2Pos, u8Key3Pos;
u8 u8Key0Pos;
g_stuKEY.KeyAD[2] = 0xFF;
g_stuKEY.KeyAD[3] = 0xFF;
switch (g_stuKEY.KeyScanProgress)
{
case E_KEY_READ_FIRSR:
g_stuKEY.keytest = GetVotFromAD(g_stuKEY.KeyAD[0]);
#if 1
u8Key0Pos = GetKeyPos(GetVotFromAD(g_stuKEY.KeyAD[0]), 0);
u8Key1Pos =KEY_NULL;
u8Key2Pos = GetKeyPos(GetVotFromAD(g_stuKEY.KeyAD[2]), 2);
u8Key3Pos = GetKeyPos(GetVotFromAD(g_stuKEY.KeyAD[3]), 3);
#else
u8Key0Pos = GetKeyPos(g_stuKEY.KeyAD[0], 0);
u8Key1Pos = GetKeyPos(g_stuKEY.KeyAD[1], 1);
u8Key2Pos = GetKeyPos(g_stuKEY.KeyAD[2], 2);
u8Key3Pos = GetKeyPos(g_stuKEY.KeyAD[3], 3);
#endif
if (u8Key0Pos != KEY_NULL)
{
g_stuKEY.KeyScanProgress = E_KEY_READ_DELAY;
g_stuKEY.key0Pos = u8Key0Pos;
}
if (u8Key1Pos != KEY_NULL)
{
g_stuKEY.KeyScanProgress = E_KEY_READ_DELAY;
g_stuKEY.key1Pos = u8Key1Pos;
}
if (u8Key2Pos != KEY_NULL)
{
g_stuKEY.KeyScanProgress = E_KEY_READ_DELAY;
g_stuKEY.key2Pos = u8Key2Pos;
}
if (u8Key3Pos != KEY_NULL)
{
g_stuKEY.KeyScanProgress = E_KEY_READ_DELAY;
g_stuKEY.key3Pos = u8Key3Pos;
}
break;
case E_KEY_READ_DELAY:
#if 1
u8Key0Pos = GetKeyPos(GetVotFromAD(g_stuKEY.KeyAD[0]), 0);
u8Key1Pos =KEY_NULL;
u8Key2Pos = GetKeyPos(GetVotFromAD(g_stuKEY.KeyAD[2]), 2);
u8Key3Pos = GetKeyPos(GetVotFromAD(g_stuKEY.KeyAD[3]), 3);
#else
u8Key0Pos = GetKeyPos(g_stuKEY.KeyAD[0], 0);
u8Key1Pos = GetKeyPos(g_stuKEY.KeyAD[1], 1);
u8Key2Pos = GetKeyPos(g_stuKEY.KeyAD[2], 2);
u8Key3Pos = GetKeyPos(g_stuKEY.KeyAD[3], 3);
#endif
if (g_stuKEY.key0Pos != KEY_NULL && g_stuKEY.key0Pos == u8Key0Pos)
{
KEY_TAB[0][g_stuKEY.key0Pos].keyfun(0);
g_stuKEY.KeyScanProgress = E_KEY_KEEP_DELAY;
g_stuKEY.wKeyKeepDelay = 200;
}
else if (g_stuKEY.key1Pos != KEY_NULL && g_stuKEY.key1Pos == u8Key1Pos)
{
KEY_TAB[1][g_stuKEY.key2Pos].keyfun(0);
g_stuKEY.KeyScanProgress = E_KEY_KEEP_DELAY;
g_stuKEY.wKeyKeepDelay = 200;
}
else if (g_stuKEY.key2Pos != KEY_NULL && g_stuKEY.key2Pos == u8Key2Pos)
{
KEY_TAB[2][g_stuKEY.key2Pos].keyfun(0);
g_stuKEY.KeyScanProgress = E_KEY_KEEP_DELAY;
g_stuKEY.wKeyKeepDelay = 200;
}
else if (g_stuKEY.key3Pos != KEY_NULL && g_stuKEY.key3Pos == u8Key3Pos)
{
KEY_TAB[3][g_stuKEY.key3Pos].keyfun(0);
g_stuKEY.KeyScanProgress = E_KEY_KEEP_DELAY;
g_stuKEY.wKeyKeepDelay = 200;
}
else
{
g_stuKEY.key0Pos = KEY_NULL;
g_stuKEY.key1Pos = KEY_NULL;
g_stuKEY.key2Pos = KEY_NULL;
g_stuKEY.key3Pos = KEY_NULL;
g_stuKEY.KeyScanProgress = E_KEY_READ_FIRSR;
}
break;
case E_KEY_KEEP_DELAY:
if (DecWordToZero(&g_stuKEY.wKeyKeepDelay))
{
g_stuKEY.KeyScanProgress = E_KEY_KEEP;
g_stuKEY.wKeyKeepDelay = KEY_LONGPRESS_BREAK;
}
else
{
#if 1
u8Key0Pos = GetKeyPos(GetVotFromAD(g_stuKEY.KeyAD[0]), 0);
u8Key1Pos =KEY_NULL;
u8Key2Pos = GetKeyPos(GetVotFromAD(g_stuKEY.KeyAD[2]), 2);
u8Key3Pos = GetKeyPos(GetVotFromAD(g_stuKEY.KeyAD[3]), 3);
#else
u8Key0Pos = GetKeyPos(g_stuKEY.KeyAD[0], 0);
u8Key1Pos = GetKeyPos(g_stuKEY.KeyAD[1], 1);
u8Key2Pos = GetKeyPos(g_stuKEY.KeyAD[2], 2);
u8Key3Pos = GetKeyPos(g_stuKEY.KeyAD[3], 3);
#endif
if (g_stuKEY.key0Pos != KEY_NULL && g_stuKEY.key0Pos == u8Key0Pos)
{
}
else if (g_stuKEY.key1Pos != KEY_NULL && g_stuKEY.key1Pos == u8Key1Pos)
{
}
else if (g_stuKEY.key2Pos != KEY_NULL && g_stuKEY.key2Pos == u8Key2Pos)
{
}
else if (g_stuKEY.key3Pos != KEY_NULL && g_stuKEY.key3Pos == u8Key3Pos)
{
}
else
{
g_stuKEY.KeyScanProgress = E_KEY_BOUNCE;
}
}
break;
case E_KEY_KEEP:
#if 1
u8Key0Pos = GetKeyPos(GetVotFromAD(g_stuKEY.KeyAD[0]), 0);
u8Key1Pos =KEY_NULL;
u8Key2Pos = GetKeyPos(GetVotFromAD(g_stuKEY.KeyAD[2]), 2);
u8Key3Pos = GetKeyPos(GetVotFromAD(g_stuKEY.KeyAD[3]), 3);
#else
u8Key0Pos = GetKeyPos(g_stuKEY.KeyAD[0], 0);
u8Key1Pos = GetKeyPos(g_stuKEY.KeyAD[1], 1);
u8Key2Pos = GetKeyPos(g_stuKEY.KeyAD[2], 2);
u8Key3Pos = GetKeyPos(g_stuKEY.KeyAD[3], 3);
#endif
if (g_stuKEY.key0Pos != KEY_NULL && g_stuKEY.key0Pos == u8Key0Pos)
{
if (DecWordToZero(&g_stuKEY.wKeyKeepDelay))
{
g_stuKEY.wKeyKeepDelay = KEY_LONGPRESS_BREAK;
KEY_TAB[0][g_stuKEY.key0Pos].keyfun(1);
}
}
else if (g_stuKEY.key1Pos != KEY_NULL && g_stuKEY.key1Pos == u8Key1Pos)
{
if (DecWordToZero(&g_stuKEY.wKeyKeepDelay))
{
g_stuKEY.wKeyKeepDelay = KEY_LONGPRESS_BREAK;
KEY_TAB[1][g_stuKEY.key1Pos].keyfun(1);
}
}
else if (g_stuKEY.key2Pos != KEY_NULL && g_stuKEY.key2Pos == u8Key2Pos)
{
if (DecWordToZero(&g_stuKEY.wKeyKeepDelay))
{
g_stuKEY.wKeyKeepDelay = KEY_LONGPRESS_BREAK;
KEY_TAB[2][g_stuKEY.key2Pos].keyfun(1);
}
}
else if (g_stuKEY.key3Pos != KEY_NULL && g_stuKEY.key3Pos == u8Key3Pos)
{
if (DecWordToZero(&g_stuKEY.wKeyKeepDelay))
{
g_stuKEY.wKeyKeepDelay = KEY_LONGPRESS_BREAK;
KEY_TAB[3][g_stuKEY.key3Pos].keyfun(1);
}
}
else
{
g_stuKEY.KeyScanProgress = E_KEY_BOUNCE;
}
break;
case E_KEY_BOUNCE:
if (g_stuKEY.key0Pos != KEY_NULL)
{
KEY_TAB[0][g_stuKEY.key0Pos].keyfun(2);
}
else if (g_stuKEY.key1Pos != KEY_NULL)
{
KEY_TAB[1][g_stuKEY.key1Pos].keyfun(2);
}
else if (g_stuKEY.key2Pos != KEY_NULL)
{
KEY_TAB[2][g_stuKEY.key2Pos].keyfun(2);
}
else if (g_stuKEY.key3Pos != KEY_NULL)
{
KEY_TAB[3][g_stuKEY.key3Pos].keyfun(2);
}
g_stuKEY.KeyScanProgress = E_KEY_READ_FIRSR;
g_stuKEY.key0Pos = KEY_NULL;
g_stuKEY.key1Pos = KEY_NULL;
g_stuKEY.key2Pos = KEY_NULL;
g_stuKEY.key3Pos = KEY_NULL;
break;
}
}
void KeyTask(void)
{
if (!wKeyScanTimer)
{
Key_Dispatch();
wKeyScanTimer = 20;
}
}
BYTE encoderA;
BYTE encoderB;
BYTE gEncoder_A_end;
BYTE gEncoder_B_end;
void Init_Encoder(void)
{
}
#define changed_value 200
#define press_low 0
#define press_mid 1
#define press_hig 2
void EncoderProcess(void)
{
static BYTE press_statu_count=0;
static BYTE press_statu=0xff;
if(g_stuKEY.KeyAD[1]>=(2000-changed_value)&&g_stuKEY.KeyAD[1]<=(2000+200))
{
if(press_statu_count<=1)
{
press_statu_count++;
}
if(press_statu_count>=2)
{
press_statu=press_mid;
}
}
else
press_statu_count=0;
if(g_stuKEY.KeyAD[1]>=(300-changed_value)&&g_stuKEY.KeyAD[1]<=(300+200))
{
if(press_statu==press_mid)
{
LF_CanBus_SendControlCmd(key_dec);
}
else if(press_statu==press_hig)
{
LF_CanBus_SendControlCmd(key_inc);
}
press_statu=press_low;
}
if(g_stuKEY.KeyAD[1]>=(4000-changed_value)&&g_stuKEY.KeyAD[1]<=(4000+200))
{
if(press_statu==press_mid)
{
LF_CanBus_SendControlCmd(key_inc);
}
else if(press_statu==press_low)
{
LF_CanBus_SendControlCmd(key_dec);
}
press_statu=press_hig;
}
#if 0
BYTE temp_A;
BYTE temp_B;
temp_A = GPIO_ReadInputDataBit(KnobENC_ENDA_PORT,KnobENC_ENDA_PIN);
temp_B = GPIO_ReadInputDataBit(KnobENC_ENDB_PORT,KnobENC_ENDB_PIN);
if(temp_A != temp_B )
{
if(temp_A != gEncoder_A_end)
{
gRemVal_CMD = 1;
if(g_stuSYSINFO.uOSDMainMode!=MAIN_OSD_MODE_IN_NAVI)
LF_CanBus_SendControlCmd(BENZE_CMD_KNOB_TUNEDEC_PRESSED);
}
else if(temp_B != gEncoder_B_end)
{
gRemVal_CMD = 0;
if(g_stuSYSINFO.uOSDMainMode!=MAIN_OSD_MODE_IN_NAVI)
LF_CanBus_SendControlCmd(BENZE_CMD_KNOB_TUNEINC_PRESSED);
}
}
gEncoder_A_end = temp_A;
gEncoder_B_end = temp_B;
#endif
}
/***************************************KEY END ***********************************/
#undef _KEY_C_
#ifndef _KEY_H_
#define _KEY_H_
#ifdef _KEY_C_
#define _KEY_EXT_
#else
#define _KEY_EXT_ extern
#endif
#define KEY_LONGPRESS_DELAY_TIMR 50 //10ms
#define KEY_LONGPRESS_BREAK 10 //10ms
#define I2C_KEY_SCAN_FIRST_TIMER 20// 1 ms
#define I2C_KEY_SCAN_SECOND_TIMER 20// 1 ms
#define I2C_KEY_SCAN_ACTION_TIMER 20// 1 ms
typedef enum
{
E_KEY_READ_FIRSR, E_KEY_READ_DELAY, E_KEY_KEEP_DELAY, E_KEY_KEEP,
E_KEY_BOUNCE
} E_KEY_SCAN_STATUS;
typedef void(*KeyCallBack)(BYTE);
typedef struct
{
u16 KeyAD[4];
E_KEY_SCAN_STATUS KeyScanProgress;
u16 wKeyKeepDelay;
u8 key0Pos;
u8 key1Pos;
u8 key2Pos;
u8 key3Pos;
u16 keytest;
} KEY;
typedef struct
{
u16 keyVoltage_low;
u16 keyVoltage_high;
KeyCallBack keyfun;
} KEY_DEFINE;
_KEY_EXT_ KEY g_stuKEY;
_KEY_EXT_ vu16 wKeyScanTimer;
_KEY_EXT_ BYTE gModeIndex;
_KEY_EXT_ void Key_Dispatch(void);
_KEY_EXT_ void KeyTask(void);
_KEY_EXT_ u16 GetVotFromAD(u16 u16AD);
_KEY_EXT_ void Key_Q3_KeyBoardScan_Task(void);
_KEY_EXT_ void Init_Encoder(void);
_KEY_EXT_ void EncoderProcess(void);
#endif