2012年3月24日 星期六

實用技巧 -- 使用一個ADC Port來實現多顆按鍵的判別


在之前的文章有稍微提到可利用一個ADC port來實現16個按鍵的判別, 這個技術被廣泛的應用在各類的3C或家電產品,

電路的接法請看下圖


它的動作原理是當沒有任何按鍵被按下時, Adc_Key這個loop沒有任何的電壓, 所以經由ADC讀到的值為0(R17和C16構成RC filter, 這很重要, 不然ADC的值也許會因為noise voltage而跳來跳去, 造成不穩定的adc value), 假設現在SW3被按下, Adc_key的電壓=R18/(R10+R18)*5=4.545V , 轉成8bit的ADC值=(4.545/5)*256=232左右, 轉成10bit的ADC值=(4.545/5)*1024=930左右, 這是理論值, 如果實際得到的值小於這個數字, 代表你的ADC module裡的Chold電容並沒有被充飽就啟動了ADC轉換, 才會得到實際數字小於理論數字, 更改一下ADC轉換的clock, 或delay一下, 應該就可以解決, 當然也有可能是因為layout或noise造成這種現象, 但是這種現象並不會影嚮按鍵判斷的功能, 而其它的按鍵以此類推 ...

有了硬體, 再會就是軟體了, 這也是很重要的一環, 底下是一個應用的例子, 先看一下主程式部份

void main()
{
   int1 Adc_Read=0;
   unsigned long CH1_ADC_Value=0;

   setup_adc_ports(AN0);                         //指定AN0為ADC port
   setup_adc(ADC_CLOCK_INTERNAL);      //設定ADC轉換的時間
   set_adc_channel(0);                              //啟動AN0的ADC function

  do{
      delay_ms(10);
      CH1_ADC_Value=read_adc();
      if ( (CH1_ADC_Value >=100) && (Adc_Read==0) )  //以Adc_Read來代表已讀取Adc Value
         {
         Adc_Read=1;
         AdcKeyCheck(CH1_ADC_Value);
         }
      else if( (CH1_ADC_Value <=100) && (Adc_Read==1))
         Adc_Read=0;     //沒按鍵時, 清除adc_read指標
       } while(True);

}

現來看一下當讀取到adc的值時, 呼叫AdcKeyCheck這個副函式來判別到底是那一個鍵被按下

void AdcKeyCheck(unsigned long AdcValue)
{
  
      printf("\n\rADC Value=%Lu",AdcValue);
    
      if ((AdcValue <= 835) & (AdcValue >= 735))
         printf("\n\r You Press UP Key!!! ADC Value=%Lu",AdcValue);
      else if ((AdcValue <= 206) & (AdcValue >= 106))
         printf("\n\r You Press Down Key!!! ADC Value=%Lu",AdcValue);
      else if ((AdcValue <= 650) & (AdcValue >= 550))
         printf("\n\r You Press Left Key!!! ADC Value=%Lu",AdcValue);
      else if ((AdcValue <= 349) & (AdcValue >= 249))
         printf("\n\r You Press Right Key!!! ADC Value=%Lu",AdcValue);
      else if ((AdcValue <= 492) & (AdcValue >= 392))
         printf("\n\r You Press Enter Key!!! ADC Value=%Lu",AdcValue);

}

如果以上的AdcValue跟你實際看到的不同, 也不用緊張, 改成你看到的實際值並不會影嚮到按鍵檢查的功能, 我目前是設定

AdcValue的中心值+/- 50, 這是我個人的慣用值, 目前使用起來並沒有遇到按鍵失靈的問題, 和大家分享這個實用的小技巧

3 則留言:

  1. 如果有2顆按鍵同時按下的話會造成誤判耶

    有辦法按鍵1按下值為512;按鍵2按下為256;2顆同時按下變768嗎?

    回覆刪除
    回覆
    1. 你可以算一下歐姆定律,兩顆同時按下等於是並聯電阻

      刪除
  2. 複合按鍵用ADC的方法較難, 請改用HC74165, 並列輸入序列輸出, 用這個方法, 單按複合按鍵都很簡單, 你可以試看看

    回覆刪除

歡迎大家來討論交流一下~~~