最近用AVR的M48作一个东西,这一个口那一个口突然发现IO口不够用了。用扩展芯片是没问题,但是感觉太浪费了,恰巧AVR有ADC功能,我看到好多人用ADC功能做按键一个IO口实现24按键,我就4个按键做起来应该不是很难。看完datasheet的ADC和参考网上资料,程序写完以后运行效果还不错,下面是电路图和源程序:
 - /*
- *************************************************************************
- *名称: unsigned int GetADCValue(unsigned char uchADCChannel) *
- *功能: 获取按键ADC值 *
- *参数: 无 *
- *返回: 按键ADC值 *
- *************************************************************************
- */
- unsigned int GetADCValue(unsigned char uchADCChannel)
- {
- unsigned char i;
- unsigned int uiADCValue = 0;
-
- ADMUX = _BV(REFS0)|uchADCChannel; // 参考电压AVCC选择
- for (i=0; i<4; i++) // 连续转换4次
- {
- ADCSRA |= (1< ADCSRA |= (1< loop_until_bit_is_set(ADCSRA, ADIF); // 等待ADC转换结束
- ADCSRA |= (1 << ADIF); // 写1清除标志位
- uiADCValue =uiADCValue + ADC;
-
- }
-
- uiADCValue /= 4; // 取平均值
- return uiADCValue;
- }
- /*
- *************************************************************************
- *名称: unsigned char GetKeyValue(void) *
- *功能: 获取按键值 *
- *参数: 无 *
- *返回: 按键值 *
- *************************************************************************
- */
- unsigned char GetKeyValue(void)
- {
- // 5.24V下按键与对应ADC值如下
- // KEY NO KEY0 KEY1 KEY2 KEY3
- // ADC 1023 0012 390 565 669
- unsigned char uchKeyValue = NOKEY; // 按键码
- unsigned int uiKeyADC = 0; // 按键ADC值
- uiKeyADC = GetADCValue(ADC_CHANNEL);
- if(uiKeyADC<1000) // 如果有键按下
- {
- DelayNms(10); // 延时10ms消抖
- uiKeyADC = GetADCValue(ADC_CHANNEL);
- if(uiKeyADC < 32) // KEY0
- {
- uchKeyValue = KEY0;
- }
- else if(uiKeyADC < 410) // KEY1
- {
- uchKeyValue = KEY1;
- }
- else if(uiKeyADC < 585) // KEY2
- {
- uchKeyValue = KEY2;
- }
- else if(uiKeyADC < 689) // KEY3
- {
- uchKeyValue = KEY3;
- }
- }
- return uchKeyValue;
- }
|