打印

哈哈,还是老X的那工具**,再出一个思考题

[复制链接]
12109|54
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
古道热肠|  楼主 | 2008-12-12 11:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
//古道热肠U盘开发板--AD驱动//主办单位:www.21ic.com//项目负责人:古道热肠//作者邮箱:xg_2004_sy@126.com//Blog    : http://blog.21ic.com/user1/4538/index.html//完成日期:2008-12-02//备注:  开发板上AD4-AD7为有效AD入口#include <AT91SAM7S64.H>                    /* AT91SAM7S64 definitions */#include <lib_AT91SAM7s64.h>#include <string.h>#include <stdio.h>#include "..Board.h"#include "DriverLCD_Nokia5110.h"#include "DriverBeep.h"#include "DriverTwi.h"#include "DriverTimer.h"#include "Serial.h"#include "APIComm.h"//初始化硬件为AD模块服务void  ADC_Init(){            AT91F_ADC_SoftReset(AT91C_BASE_ADC);      //Hradware triggers are disabled. Starting a conversion is only possible by software      //8-bit ,set adc clock,the startup time,sample and holding time.      AT91F_ADC_CfgModeReg(AT91C_BASE_ADC,AT91C_ADC_TRGEN_DIS | AT91C_ADC_LOWRES_10_BIT | AT91C_ADC_SLEEP_NORMAL_MODE                              | AT91C_ADC_PRESCAL | AT91C_ADC_STARTUP | AT91C_ADC_SHTIM);      AT91F_ADC_EnableChannel(AT91C_BASE_ADC,AT91C_ADC_CH4 | AT91C_ADC_CH5 | AT91C_ADC_CH6 | AT91C_ADC_CH7);//      AT91F_ADC_StartConversion(AT91C_BASE_ADC);         `}//等待AD转换结束//返回:true 表示读取到转换结束标志符,属转换正常结束//     false 表示超时退出,功能出错//备注:根据文档介绍:转换时间最大值为2usbool ADC_WaitEnd(void){      uint uiReadValue;      uint uiDelayCount;            //10uS计数值的倍数      bool bReturnValue;      bReturnValue = false;      uiDelayCount = 0;      Timer_Start();            //开启定时器      while(uiDelayCount<2)      {            uiDelayCount = GetTimerCount();            uiReadValue = AT91F_ADC_GetStatus(AT91C_BASE_ADC);            if((uiReadValue & 0x000000f0) == 0x000000f0)   //仅启用了CH4-CH7通道            {                  bReturnValue = true;                  break;            }      }      return(bReturnValue);}void ADC_Start(void){       AT91F_ADC_StartConversion(AT91C_BASE_ADC);}//读取AD转换通道的值,入口参数,AD通道号索引,返回与通道号对应的AD值uint ADC_ReadValue(uchar ucChannelIndex){      uint uiReadValue;      switch(ucChannelIndex)      {            case AT91C_ADC_CH4:                  uiReadValue =  AT91F_ADC_GetConvertedDataCH4(AT91C_BASE_ADC);                  break;            case AT91C_ADC_CH5:                  uiReadValue =  AT91F_ADC_GetConvertedDataCH5(AT91C_BASE_ADC);                  break;            case AT91C_ADC_CH6:                  uiReadValue =  AT91F_ADC_GetConvertedDataCH6(AT91C_BASE_ADC);                  break;            case AT91C_ADC_CH7:                  uiReadValue =  AT91F_ADC_GetConvertedDataCH7(AT91C_BASE_ADC);                  break;            default:                  uiReadValue = 0;                  break;      }      return(uiReadValue);}void TestAD(void){      uint uiReadADValue;      uchar ucDispDataBuff[16];      LCD_Clear();      LCD_ShowString(0,0,"  Test AD");      ADC_Init();      while(1)      {            ComShowString(c_COM1,"Start AD Convert");            ADC_Start();            ADC_WaitEnd();             ComShowString(c_COM1,"AD Convert Complete");            uiReadADValue =  ADC_ReadValue(AT91C_ADC_CH4);            sprintf(ucDispDataBuff,"CH4 AD Value is:%4d",uiReadADValue);            ComShowString(c_COM1,ucDispDataBuff);            LCD_ShowString(0,1,ucDispDataBuff);            uiReadADValue =  ADC_ReadValue(AT91C_ADC_CH5);            sprintf(ucDispDataBuff,"CH5 AD Value is:%4d",uiReadADValue);            ComShowString(c_COM1,ucDispDataBuff);//            LCD_ShowString(0,1,ucDispDataBuff);            uiReadADValue =  ADC_ReadValue(AT91C_ADC_CH6);            sprintf(ucDispDataBuff,"CH6 AD Value is:%4d",uiReadADValue);            ComShowString(c_COM1,ucDispDataBuff);//            LCD_ShowString(0,1,ucDispDataBuff);            uiReadADValue =  ADC_ReadValue(AT91C_ADC_CH7);            sprintf(ucDispDataBuff,"CH7 AD Value is:%4d",uiReadADValue);            ComShowString(c_COM1,ucDispDataBuff);            LCD_ShowString(0,3,ucDispDataBuff);                        Delay(1);      }}enum KeyV {                  KEY_LEFT,                   KEY_DOWN,                    KEY_RIGHT,                  KEY_NONE,                   KEY_ESC,                   KEY_UP,                   KEY_OK                  };const enum KeyV Ktab[] = {KEY_LEFT, KEY_DOWN,  KEY_RIGHT, KEY_NONE, KEY_ESC, KEY_UP,KEY_OK};enum KeyV  Read_KeyValue(void)                          {      uchar uci;      uint uiReadADCValue;      enum KeyV enuKeyReturnValue;      const unsigned short KeyTable[] ={ 0, 100, 260, 390, 470, 560, 690, 1023};//      ADC_Start();      //由于上一次读取结束时启动了AD转换,所以直接等转换结束后读AD值即可      if(ADC_WaitEnd())      {             uiReadADCValue = ADC_ReadValue(AT91C_ADC_CH4);            for(uci=0;uci<7;uci++)             {                  if(( KeyTable[uci] <= uiReadADCValue) &&                      (uiReadADCValue < KeyTable[uci+1] ) )                  {                        enuKeyReturnValue = Ktab[uci];                        break;                  }            }      }      else      {            enuKeyReturnValue = KEY_NONE;            }      //读取完当前的AD值后,再次启动转换过程      ADC_Start();      return enuKeyReturnValue;}enum KeyV ReadKey(void) {      static int KeyCount=0;                              static enum KeyV preKey=KEY_NONE;      //存放前一次按键的值      enum KeyV CurrentKeyValue;            CurrentKeyValue = Read_KeyValue();      if(CurrentKeyValue == preKey)       {            KeyCount++;        //防抖动处理            if(KeyCount > 10)             //重复检查次数为10次,完全相符,认为按键有效            {                  KeyCount=0;                  return CurrentKeyValue;                  }      }      else       {            KeyCount=0;      }      preKey = CurrentKeyValue;      return KEY_NONE;}bool KbHit(void){      enum KeyV ucReadKeyValue;      ucReadKeyValue = Read_KeyValue();      if(ucReadKeyValue != KEY_NONE)      {            return(true);      }      else      {            return(false);      }}//读取按键值,无阻塞,读完后没有等待按键释放就返回主调函数enum KeyV KbGet(void){      enum KeyV ucKeyValue;      uchar ucCount;      ucCount= 30;      while(ucCount--)      {            ucKeyValue = ReadKey();            if(ucKeyValue != KEY_NONE)            {                  break;            }            Delay(1);      }      return ucKeyValue;}void TestAD_KeyBoard(void){      uchar uci;      enum KeyV ucKeyValue;//       init_timer();      LCD_Clear();      LCD_ShowString(0,0,"Test AD KBD");      ADC_Init();               //初始化AD是必须执行的操作      //启动一次转换过程,初始化AD模块的读取、启动的循环。      ADC_Start();      Delay(1);      while(1)      {            if(KbHit())            {                  ComShowString(c_COM1,"Find Key Press");                   ucKeyValue = KbGet();                   switch(ucKeyValue)                   {                         case KEY_ESC:                              LCD_ShowString(0,2,"Esc Press");                              break;                         case KEY_UP:                              LCD_ShowString(0,2,"UP Press");                              break;                         case KEY_OK:                              LCD_ShowString(0,2,"OK Press");                              break;                         case KEY_LEFT:                              LCD_ShowString(0,2,"LEFT Press");                              break;                         case KEY_DOWN:                              LCD_ShowString(0,2,"Down Press");                              break;                          case KEY_RIGHT:                              LCD_ShowString(0,2,"Right Press");                              break;                        default:                              LCD_ShowString(0,2,"Err!");                                 break;                   }                   //等待按键释放。                   while(KbHit())                   {      //                   BeepShort();                        Delay(1);                   }            }            Delay(1);      }}

相关帖子

来自 2楼
古道热肠|  楼主 | 2008-12-12 11:27 | 只看该作者

哈哈,语法加亮工具用不起来了.再贴一份不亮的

//古道热肠U盘开发板--AD驱动
//主办单位:www.21ic.com
//项目负责人:古道热肠
//作者邮箱:xg_2004_sy@126.com
//Blog    : http://blog.21ic.com/user1/4538/index.html

//完成日期:2008-12-02
//备注:  开发板上AD4-AD7为有效AD入口

#include <AT91SAM7S64.H>                    /* AT91SAM7S64 definitions */
#include <lib_AT91SAM7s64.h>
#include <string.h>
#include <stdio.h>

#include "..Board.h"

#include "DriverLCD_Nokia5110.h"
#include "DriverBeep.h"
#include "DriverTwi.h"
#include "DriverTimer.h"
#include "Serial.h"
#include "APIComm.h"

//初始化硬件为AD模块服务
void  ADC_Init()
{    
    AT91F_ADC_SoftReset(AT91C_BASE_ADC);
    //Hradware triggers are disabled. Starting a conversion is only possible by software
    //8-bit ,set adc clock,the startup time,sample and holding time.
    AT91F_ADC_CfgModeReg(AT91C_BASE_ADC,AT91C_ADC_TRGEN_DIS | AT91C_ADC_LOWRES_10_BIT | AT91C_ADC_SLEEP_NORMAL_MODE
                    | AT91C_ADC_PRESCAL | AT91C_ADC_STARTUP | AT91C_ADC_SHTIM);
    AT91F_ADC_EnableChannel(AT91C_BASE_ADC,AT91C_ADC_CH4 | AT91C_ADC_CH5 | AT91C_ADC_CH6 | AT91C_ADC_CH7);
//    AT91F_ADC_StartConversion(AT91C_BASE_ADC);       `
}

//等待AD转换结束
//返回:true 表示读取到转换结束标志符,属转换正常结束
//     false 表示超时退出,功能出错
//备注:根据文档介绍:转换时间最大值为2us
bool ADC_WaitEnd(void)
{
    uint uiReadValue;
    uint uiDelayCount;        //10uS计数值的倍数
    bool bReturnValue;

    bReturnValue = false;
    uiDelayCount = 0;
    Timer_Start();        //开启定时器
    while(uiDelayCount<2)
    {
        uiDelayCount = GetTimerCount();

        uiReadValue = AT91F_ADC_GetStatus(AT91C_BASE_ADC);
        if((uiReadValue & 0x000000f0) == 0x000000f0)   //仅启用了CH4-CH7通道
        {
            bReturnValue = true;
            break;
        }
    }
    return(bReturnValue);
}

void ADC_Start(void)
{
     AT91F_ADC_StartConversion(AT91C_BASE_ADC);
}

//读取AD转换通道的值,入口参数,AD通道号索引,返回与通道号对应的AD值
uint ADC_ReadValue(uchar ucChannelIndex)
{
    uint uiReadValue;

    switch(ucChannelIndex)
    {
        case AT91C_ADC_CH4:
            uiReadValue =  AT91F_ADC_GetConvertedDataCH4(AT91C_BASE_ADC);
            break;
        case AT91C_ADC_CH5:
            uiReadValue =  AT91F_ADC_GetConvertedDataCH5(AT91C_BASE_ADC);
            break;
        case AT91C_ADC_CH6:
            uiReadValue =  AT91F_ADC_GetConvertedDataCH6(AT91C_BASE_ADC);
            break;
        case AT91C_ADC_CH7:
            uiReadValue =  AT91F_ADC_GetConvertedDataCH7(AT91C_BASE_ADC);
            break;
        default:
            uiReadValue = 0;
            break;
    }
    return(uiReadValue);
}

void TestAD(void)
{
    uint uiReadADValue;
    uchar ucDispDataBuff[16];

    LCD_Clear();
    LCD_ShowString(0,0,"  Test AD");
    ADC_Init();
    while(1)
    {
        ComShowString(c_COM1,"Start AD Convert");
        ADC_Start();
        ADC_WaitEnd();
         ComShowString(c_COM1,"AD Convert Complete");

        uiReadADValue =  ADC_ReadValue(AT91C_ADC_CH4);
        sprintf(ucDispDataBuff,"CH4 AD Value is:%4d",uiReadADValue);
        ComShowString(c_COM1,ucDispDataBuff);
        LCD_ShowString(0,1,ucDispDataBuff);

        uiReadADValue =  ADC_ReadValue(AT91C_ADC_CH5);
        sprintf(ucDispDataBuff,"CH5 AD Value is:%4d",uiReadADValue);
        ComShowString(c_COM1,ucDispDataBuff);
//        LCD_ShowString(0,1,ucDispDataBuff);

        uiReadADValue =  ADC_ReadValue(AT91C_ADC_CH6);
        sprintf(ucDispDataBuff,"CH6 AD Value is:%4d",uiReadADValue);
        ComShowString(c_COM1,ucDispDataBuff);
//        LCD_ShowString(0,1,ucDispDataBuff);

        uiReadADValue =  ADC_ReadValue(AT91C_ADC_CH7);
        sprintf(ucDispDataBuff,"CH7 AD Value is:%4d",uiReadADValue);
        ComShowString(c_COM1,ucDispDataBuff);
        LCD_ShowString(0,3,ucDispDataBuff);
        
        Delay(1);

    }
}

enum KeyV {
            KEY_LEFT, 
            KEY_DOWN, 
             KEY_RIGHT,
            KEY_NONE, 
            KEY_ESC, 
            KEY_UP, 
            KEY_OK
            };

const enum KeyV Ktab[] = {KEY_LEFT, KEY_DOWN,  KEY_RIGHT, KEY_NONE, KEY_ESC, KEY_UP,KEY_OK};
enum KeyV  Read_KeyValue(void)                  
{
    uchar uci;
    uint uiReadADCValue;
    enum KeyV enuKeyReturnValue;

    const unsigned short KeyTable[] ={ 0, 100, 260, 390, 470, 560, 690, 1023};


//    ADC_Start();
    //由于上一次读取结束时启动了AD转换,所以直接等转换结束后读AD值即可
    if(ADC_WaitEnd())
    {
         uiReadADCValue = ADC_ReadValue(AT91C_ADC_CH4);
        for(uci=0;uci<7;uci++) 
        {
            if(( KeyTable[uci] <= uiReadADCValue) && 
               (uiReadADCValue < KeyTable[uci+1] ) )
            {
                enuKeyReturnValue = Ktab[uci];
                break;
            }
        }
    }
    else
    {
        enuKeyReturnValue = KEY_NONE;    
    }

    //读取完当前的AD值后,再次启动转换过程
    ADC_Start();

    return enuKeyReturnValue;
}


enum KeyV ReadKey(void) 
{
    static int KeyCount=0;                
    static enum KeyV preKey=KEY_NONE;    //存放前一次按键的值

    enum KeyV CurrentKeyValue;
    
    CurrentKeyValue = Read_KeyValue();
    if(CurrentKeyValue == preKey) 
    {
        KeyCount++;      //防抖动处理
        if(KeyCount > 10)         //重复检查次数为10次,完全相符,认为按键有效
        {
            KeyCount=0;
            return CurrentKeyValue;    
        }
    }
    else 
    {
        KeyCount=0;
    }

    preKey = CurrentKeyValue;
    return KEY_NONE;
}

bool KbHit(void)
{
    enum KeyV ucReadKeyValue;

    ucReadKeyValue = Read_KeyValue();
    if(ucReadKeyValue != KEY_NONE)
    {
        return(true);
    }
    else
    {
        return(false);
    }
}

//读取按键值,无阻塞,读完后没有等待按键释放就返回主调函数
enum KeyV KbGet(void)
{
    enum KeyV ucKeyValue;
    uchar ucCount;

    ucCount= 30;

    while(ucCount--)
    {
        ucKeyValue = ReadKey();
        if(ucKeyValue != KEY_NONE)
        {
            break;
        }
        Delay(1);
    }

    return ucKeyValue;
}

void TestAD_KeyBoard(void)
{
    uchar uci;
    enum KeyV ucKeyValue;

//     init_timer();

    LCD_Clear();
    LCD_ShowString(0,0,"Test AD KBD");
    ADC_Init();           //初始化AD是必须执行的操作

    //启动一次转换过程,初始化AD模块的读取、启动的循环。
    ADC_Start();
    Delay(1);
    while(1)
    {
        if(KbHit())
        {
            ComShowString(c_COM1,"Find Key Press");
             ucKeyValue = KbGet();
             switch(ucKeyValue)
             {
                 case KEY_ESC:
                    LCD_ShowString(0,2,"Esc Press");
                    break;
                 case KEY_UP:
                    LCD_ShowString(0,2,"UP Press");
                    break;
                 case KEY_OK:
                    LCD_ShowString(0,2,"OK Press");
                    break;
                 case KEY_LEFT:
                    LCD_ShowString(0,2,"LEFT Press");
                    break;
                 case KEY_DOWN:
                    LCD_ShowString(0,2,"Down Press");
                    break;
                  case KEY_RIGHT:
                    LCD_ShowString(0,2,"Right Press");
                    break;
                default:
                    LCD_ShowString(0,2,"Err!");
                       break;

             }
             //等待按键释放。
             while(KbHit())
             {
    //             BeepShort();
                Delay(1);
             }
        }
        Delay(1);

    }
}

使用特权

评论回复
板凳
xwj| | 2008-12-12 11:33 | 只看该作者

偶也来试试看

//古道热肠U盘开发板--AD驱动
//主办单位:www.21ic.com
//项目负责人:古道热肠
//作者邮箱:xg_2004_sy@126.com
//Blog    : http://blog.21ic.com/user1/4538/index.html

//完成日期:2008-12-02
//备注:  开发板上AD4-AD7为有效AD入口

#include <AT91SAM7S64.H>                    /* AT91SAM7S64 definitions */
#include <lib_AT91SAM7s64.h>
#include <string.h>
#include <stdio.h>

#include "..Board.h"

#include "DriverLCD_Nokia5110.h"
#include "DriverBeep.h"
#include "DriverTwi.h"
#include "DriverTimer.h"
#include "Serial.h"
#include "APIComm.h"

//初始化硬件为AD模块服务
void  ADC_Init()
{    
    AT91F_ADC_SoftReset(AT91C_BASE_ADC);
    //Hradware triggers are disabled. Starting a conversion is only possible by software
    //8-bit ,set adc clock,the startup time,sample and holding time.
    AT91F_ADC_CfgModeReg(AT91C_BASE_ADC,AT91C_ADC_TRGEN_DIS | AT91C_ADC_LOWRES_10_BIT | AT91C_ADC_SLEEP_NORMAL_MODE
                    | AT91C_ADC_PRESCAL | AT91C_ADC_STARTUP | AT91C_ADC_SHTIM);
    AT91F_ADC_EnableChannel(AT91C_BASE_ADC,AT91C_ADC_CH4 | AT91C_ADC_CH5 | AT91C_ADC_CH6 | AT91C_ADC_CH7);
//    AT91F_ADC_StartConversion(AT91C_BASE_ADC);       `
}

//等待AD转换结束
//返回:true 表示读取到转换结束标志符,属转换正常结束
//     false 表示超时退出,功能出错
//备注:根据文档介绍:转换时间最大值为2us
bool ADC_WaitEnd(void)
{
    uint uiReadValue;
    uint uiDelayCount;        //10uS计数值的倍数
    bool bReturnValue;

    bReturnValue = false;
    uiDelayCount = 0;
    Timer_Start();        //开启定时器
    while(uiDelayCount<2)
    {
        uiDelayCount = GetTimerCount();

        uiReadValue = AT91F_ADC_GetStatus(AT91C_BASE_ADC);
        if((uiReadValue & 0x000000f0) == 0x000000f0)   //仅启用了CH4-CH7通道
        {
            bReturnValue = true;
            break;
        }
    }
    return(bReturnValue);
}

void ADC_Start(void)
{
     AT91F_ADC_StartConversion(AT91C_BASE_ADC);
}

//读取AD转换通道的值,入口参数,AD通道号索引,返回与通道号对应的AD值
uint ADC_ReadValue(uchar ucChannelIndex)
{
    uint uiReadValue;

    switch(ucChannelIndex)
    {
        case AT91C_ADC_CH4:
            uiReadValue =  AT91F_ADC_GetConvertedDataCH4(AT91C_BASE_ADC);
            break;
        case AT91C_ADC_CH5:
            uiReadValue =  AT91F_ADC_GetConvertedDataCH5(AT91C_BASE_ADC);
            break;
        case AT91C_ADC_CH6:
            uiReadValue =  AT91F_ADC_GetConvertedDataCH6(AT91C_BASE_ADC);
            break;
        case AT91C_ADC_CH7:
            uiReadValue =  AT91F_ADC_GetConvertedDataCH7(AT91C_BASE_ADC);
            break;
        default:
            uiReadValue = 0;
            break;
    }
    return(uiReadValue);
}

void TestAD(void)
{
    uint uiReadADValue;
    uchar ucDispDataBuff[16];

    LCD_Clear();
    LCD_ShowString(0,0,"  Test AD");
    ADC_Init();
    while(1)
    {
        ComShowString(c_COM1,"Start AD Convert");
        ADC_Start();
        ADC_WaitEnd();
         ComShowString(c_COM1,"AD Convert Complete");

        uiReadADValue =  ADC_ReadValue(AT91C_ADC_CH4);
        sprintf(ucDispDataBuff,"CH4 AD Value is:%4d",uiReadADValue);
        ComShowString(c_COM1,ucDispDataBuff);
        LCD_ShowString(0,1,ucDispDataBuff);

        uiReadADValue =  ADC_ReadValue(AT91C_ADC_CH5);
        sprintf(ucDispDataBuff,"CH5 AD Value is:%4d",uiReadADValue);
        ComShowString(c_COM1,ucDispDataBuff);
//        LCD_ShowString(0,1,ucDispDataBuff);

        uiReadADValue =  ADC_ReadValue(AT91C_ADC_CH6);
        sprintf(ucDispDataBuff,"CH6 AD Value is:%4d",uiReadADValue);
        ComShowString(c_COM1,ucDispDataBuff);
//        LCD_ShowString(0,1,ucDispDataBuff);

        uiReadADValue =  ADC_ReadValue(AT91C_ADC_CH7);
        sprintf(ucDispDataBuff,"CH7 AD Value is:%4d",uiReadADValue);
        ComShowString(c_COM1,ucDispDataBuff);
        LCD_ShowString(0,3,ucDispDataBuff);
        
        Delay(1);

    }
}

enum KeyV {
            KEY_LEFT, 
            KEY_DOWN, 
             KEY_RIGHT,
            KEY_NONE, 
            KEY_ESC, 
            KEY_UP, 
            KEY_OK
            };

const enum KeyV Ktab[] = {KEY_LEFT, KEY_DOWN,  KEY_RIGHT, KEY_NONE, KEY_ESC, KEY_UP,KEY_OK};
enum KeyV  Read_KeyValue(void)                  
{
    uchar uci;
    uint uiReadADCValue;
    enum KeyV enuKeyReturnValue;

    const unsigned short KeyTable[] ={ 0, 100, 260, 390, 470, 560, 690, 1023};


//    ADC_Start();
    //由于上一次读取结束时启动了AD转换,所以直接等转换结束后读AD值即可
    if(ADC_WaitEnd())
    {
         uiReadADCValue = ADC_ReadValue(AT91C_ADC_CH4);
        for(uci=0;uci<7;uci++) 
        {
            if(( KeyTable[uci] <= uiReadADCValue) && 
               (uiReadADCValue < KeyTable[uci+1] ) )
            {
                enuKeyReturnValue = Ktab[uci];
                break;
            }
        }
    }
    else
    {
        enuKeyReturnValue = KEY_NONE;    
    }

    //读取完当前的AD值后,再次启动转换过程
    ADC_Start();

    return enuKeyReturnValue;
}


enum KeyV ReadKey(void
{
    static int KeyCount=0;                
    static enum KeyV preKey=KEY_NONE;    //存放前一次按键的值

    enum KeyV CurrentKeyValue;
    
    CurrentKeyValue = Read_KeyValue();
    if(CurrentKeyValue == preKey) 
    {
        KeyCount++;      //防抖动处理
        if(KeyCount > 10)         //重复检查次数为10次,完全相符,认为按键有效
        {
            KeyCount=0;
            return CurrentKeyValue;    
        }
    }
    else 
    {
        KeyCount=0;
    }

    preKey = CurrentKeyValue;
    return KEY_NONE;
}

bool KbHit(void)
{
    enum KeyV ucReadKeyValue;

    ucReadKeyValue = Read_KeyValue();
    if(ucReadKeyValue != KEY_NONE)
    {
        return(true);
    }
    else
    {
        return(false);
    }
}

//读取按键值,无阻塞,读完后没有等待按键释放就返回主调函数
enum KeyV KbGet(void)
{
    enum KeyV ucKeyValue;
    uchar ucCount;

    ucCount= 30;

    while(ucCount--)
    {
        ucKeyValue = ReadKey();
        if(ucKeyValue != KEY_NONE)
        {
            break;
        }
        Delay(1);
    }

    return ucKeyValue;
}

void TestAD_KeyBoard(void)
{
    uchar uci;
    enum KeyV ucKeyValue;

//     init_timer();

    LCD_Clear();
    LCD_ShowString(0,0,"Test AD KBD");
    ADC_Init();           //初始化AD是必须执行的操作

    //启动一次转换过程,初始化AD模块的读取、启动的循环。
    ADC_Start();
    Delay(1);
    while(1)
    {
        if(KbHit())
        {
            ComShowString(c_COM1,"Find Key Press");
             ucKeyValue = KbGet();
             switch(ucKeyValue)
             {
                 case KEY_ESC:
                    LCD_ShowString(0,2,"Esc Press");
                    break;
                 case KEY_UP:
                    LCD_ShowString(0,2,"UP Press");
                    break;
                 case KEY_OK:
                    LCD_ShowString(0,2,"OK Press");
                    break;
                 case KEY_LEFT:
                    LCD_ShowString(0,2,"LEFT Press");
                    break;
                 case KEY_DOWN:
                    LCD_ShowString(0,2,"Down Press");
                    break;
                  case KEY_RIGHT:
                    LCD_ShowString(0,2,"Right Press");
                    break;
                default:
                    LCD_ShowString(0,2,"Err!");
                       break;

             }
             //等待按键释放。
             while(KbHit())
             {
    //             BeepShort();
                Delay(1);
             }
        }
        Delay(1);

    }
}


//本程序由xwj设计的UltraEdit脚本加亮显示,如需要脚本访问我的Blog 或发送邮件至:xwjfile@21cn.com


使用特权

评论回复
地板
古道热肠|  楼主 | 2008-12-12 11:37 | 只看该作者

贴上相关的原理图部分,更有实用价值

AD键盘最大的好处是节省IO线.布线也较方便.在消费类电子产品应用较广泛.

使用特权

评论回复
5
古道热肠|  楼主 | 2008-12-12 11:43 | 只看该作者

出个思考题

驱动程序中
 const unsigned short KeyTable[] ={ 0, 100, 260, 390, 470, 560, 690, 1023};
这些值是如何得到的呢?理论值该取多少最为合适,如果你能自己计算出这个查找表,您的脑子又得到一次锻炼.

哈哈,有人说"脑越用越活",长期不用会反应慢的.

使用特权

评论回复
6
古道热肠|  楼主 | 2008-12-12 11:50 | 只看该作者

哈哈,还是老X的那工具**,再出一个思考题

在使用RealView作为编译器的MDK开发环境中,定义如下变量
unsigned int uii,uii最大值是多少,占用几个字节

小提示:如果是65535,占用两字节
为何代码中出现了 unsigned short,
这个在C51中可没有的哟.

使用特权

评论回复
7
lyjian| | 2008-12-12 12:47 | 只看该作者

键盘接口图错的

使用特权

评论回复
8
sz_kd| | 2008-12-12 13:06 | 只看该作者

路过 ,顶

使用特权

评论回复
9
古道热肠|  楼主 | 2008-12-12 15:29 | 只看该作者

回7楼,你下结论未免太凭感觉了吧

您仔细分析过电路在每个按键按下时,输出到AD口的电压是多少吗?
如果这电路用不起来,我那DIY板还能玩到现在,早去改版了.

使用特权

评论回复
10
icbug| | 2008-12-12 15:32 | 只看该作者

不错不错

有想法的,不错,不错!AD口扩展键盘,没有这么想过。是个思路

使用特权

评论回复
11
dspjs| | 2008-12-12 15:33 | 只看该作者

re

热火朝天,顶!

使用特权

评论回复
12
红心j| | 2008-12-12 16:46 | 只看该作者

世上本无事。。。。。。

使用特权

评论回复
13
ljm810010| | 2008-12-12 17:16 | 只看该作者

看不出这样的按键结构有何好处,复合键?

应该是复合键,任意两个按下产生的电压都和其它不同组合产生的电压保持较大的差距,猜猜而矣,不知对不对

再看看又不对呀,这样结构检测不到复合键,不知肠兄的葫芦买什么药?

使用特权

评论回复
14
ayb_ice| | 2008-12-12 21:01 | 只看该作者

AD扫键本身不难

只是获取哪个键按下和普通的扫键不同,其它的完全可以相同。
如果按键松开时再处理则有点**,因为AD可能是个中间的某个任意值,处理不好会串键,不过也是可以解决的。

使用特权

评论回复
15
lyjian| | 2008-12-12 21:18 | 只看该作者

不好意思看漏眼了

个人感觉没什么太大意义
比常规的AD按键方案浪费成本

使用特权

评论回复
16
呆板书生| | 2008-12-13 06:21 | 只看该作者

键盘图不是错

设计是否可以改进,

如果加一只51K电阻做上拉,那个AD键值表是否更好写一些?

使用特权

评论回复
17
t.jm| | 2008-12-13 08:36 | 只看该作者

给点建议:

AD健的分布不要等距,而要等倍!如按1.4倍间隔:
0 ,50, 70 ,100, 140, 200 280 ,400 ,560, 800, 1023
这样每个按健都是同样可靠的,AD分辨出50, 70不比 800 ,1023
要难,可以固定上拉为20K 1%的精密电阻,下拉为5%的普通电阻!
只有等倍分布才是考虑了误差产生的原因后的数学最优分布!

使用特权

评论回复
18
ayb_ice| | 2008-12-13 10:57 | 只看该作者

我认为还是等分要好些

这样算法很简单,解决误差最好的方法我认为是能随时校准最好。
比如:类似于有些触摸屏的校准,比如通过特定方法进入校准模式,然后提示按某键时就按某键,MCU将AD值存在EEPROM中,做为按键按下依据,当然要考虑在此AD值附近都是这个按键按下,这样可以最大程度限制误差,非常灵活。。。。
我以前就是这样做的。

使用特权

评论回复
19
xwj| | 2008-12-13 11:10 | 只看该作者

当然是等分更好些,显著降低AD转换的精度要求,

容差范围更大

使用特权

评论回复
20
古道热肠|  楼主 | 2008-12-13 11:16 | 只看该作者

到底倍分好,还是等分好呢?论据似乎都不充分

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

284

主题

6411

帖子

16

粉丝