|
楼主 |
发表于 2007-9-26 21:16:11
|
显示全部楼层
补充!!!
经过半个多小时的分析得出:
ADC的参考电压和VCC共用3.3V
采用如下电阻
R = 1000;
Rn = [68,75,82,100,120,150,180,220,300,360,510,820,1200,2800,8200];
构成16个开关,ADC值 = n/16 * 1024。
如果,不考虑电阻误差和ADC转换误差,只考虑电阻值离散性导致的误差,最大误差 = 0.32%
如果,考虑电阻值误差+-5%,这点所导致的最大误差等于 +/-5%
总体来说由外部电阻所导致的误差约 = +/-52LSB,再加上ADC转换误差+/-2LSB,得+/-54LSB
而每个按键按下所对应的ADC值的间距 = 1024/16 = 64LSB
看来用一般的电阻还不得行。得用 1% 的电阻
呵呵,可能理论学得还不到家,可能有错。
有注释的代码:
void timerIRP(void) /* 定时器中断 */
{
unsigned char i;
unsigned char key;
static unsigned char key_last;
static unsigned char key_val;
static unsigned char key_dm_ctr = 0; /* 计时按键按下的持续时间 */
i = adcRead(); /*直接读取ADC值,因为定时器周期远大于ADC转换时间*/
/* 根据ADC值,对按键编号 */
if (i < 128)
key = 1;
else if (i < 388)
key = 2;
else if (i < 683)
key = 3;
else if (i < 995)
key = 4;
else
key = 0;
adcStart(ADC_CH_KEY); /* 启动下一次AD转换 */
if (key_last == key) /* 两次检测到的值一样,以消抖动 */
{
if (key != 0)
{
if (key_dm_ctr == 0)
{
key_val = key;
/* key_val 按键按下 */
switch(key_val)
{
/*根据按键处理*/
}
}
if (key_dm_ctr != 0xff)
key_dm_ctr++;
if (key_dm_ctr == 100)
{
/* 长压 */
switch(key_val)
{
/*根据按键处理*/
}
}
}
else
{
if (key_val)
{
if (key_dm_ctr < 100)
{
/* key_val 单击后按键放开 */
switch(key_val)
{
/*根据按键处理*/
}
}
key_val = 0;
}
key_dm_ctr = 0;
}
}
}
key_last = key;
} |
|