ShawnLinson 发表于 2011-11-5 14:17:58

RM970+,RT-Thread演示【修改按键】有图有码有真相!!

感谢zzm24 大侠提供RM970+,RT-Thread 演示代码,
原有链接请参考:
http://www.ourdev.cn/bbs/issue_new_topic.jsp?bbs_id=3081
手里有个RM970+,实测后发现原有按键不能使用。
拆机后发现它的键盘居然是ADC作为输入的!?我了个去。。。。
于是把电路图给描出来了:)
http://cache.amobbs.com/bbs_upload782111/files_47/ourdev_692155R80MSW.png
(原文件名:ShawnLinson_RM970+_Key.png)

--------------------------------
以下代码是针对 RM970+ 所作的修改【key.c】
手里的RM970+的按键除了PLAY和RESET以外,另外5个按键是使用AD1采样。
完整真相工程包:
点击此处下载 ourdev_692157SM4ENK.rar(文件大小:1.57M) (原文件名:mdk_rtt_rk2706.rar)

--------------------------------


#define SW1       (1<<1)          //PC1

//AD采样的值
#define ADC_NEXT 0x19D//下一曲
#define ADC_MODE 0x0FD//Mode
#define ADC_BACK 0x310//上一曲
#define ADC_VOL0x260//VOL
#define ADC_ESC0x035//ESC、Hold
#define ADC_MAX0x3FF//


typedef enum KEY_ENUM
{
    SW_NULL = 0,    //播放
    SW_PLAY = 1,    //播放
    SW_NEXT = 2,    //下一曲
    SW_MODE = 3,    //模式
    SW_BACK = 4,    //上一曲
    SW_VOL= 5,    //VOL
    SW_ESC= 6   //ESC、Hold       
}eKeyVal;

eKeyVal keyVal;

//ADC_STAS
#define ADC_STOP   0x01

//ADC_CTRL
#define ADC_INT   (1<<6)
#define ADC_INT_EN(1<<5)
#define ADC_SOC   (1<<4)
#define ADC_EN   (1<<3)
#define ADC_CHN_MASK (7)

#define ADC_CHN   (1) //ADC通道
rt_uint32_t get_key_value(void)
{
    rt_uint32_t temp=0;
    rt_uint32_t i=0,j=0;
        temp = GPIO_PCDR&SW1;
        if( temp&(SW1) ) //SW1有按下
        {
      keyVal = SW_PLAY;
          return keyVal;               
        }
    else
    {
      for (i = 100;i > 0;i--)// wait for last ADC convert finished,
      {
            if (ADC_STAT) //
            {
                for (j = 10000;j > 0;j--);
            }
            else
            {
                break;
            }
      }

      ADC_CTRL =(ADC_SOC | ADC_EN | ADC_CHN); //Start of Conversion, ADC power up and reset, ADC input source selection.
      for (j = 10000;j > 0;j--);

      //读ADC 转换后的数据
      for (i = 100;i > 0;i--)// wait for last ADC convert finished,
      {
            if (ADC_STAT) //
            {
                for (j = 10000;j > 0;j--);
            }
            else
            {
                temp = (ADC_DATA & 0x3FF);
                if (temp > (ADC_MAX - 0x10)) {                        //
                  keyVal = SW_NULL;
                }
                else if ((temp > (ADC_NEXT - 0x10)) && (temp < (ADC_NEXT + 0x10))) //
                {
                  keyVal = SW_NEXT;
                }
                else if ((temp > (ADC_MODE - 0x10)) && (temp < (ADC_MODE + 0x10))) //
                {
                  keyVal = SW_MODE;
                }
                else if ((temp > (ADC_BACK - 0x10)) && (temp < (ADC_BACK + 0x10))) //
                {
                  keyVal = SW_BACK;
                }
                else if ((temp > (ADC_VOL - 0x10)) && (temp < (ADC_VOL + 0x10))) //
                {
                  keyVal = SW_VOL;
                }
                else if ((temp > (ADC_ESC - 0x10)) && (temp < (ADC_ESC + 0x10))) //
                {
                  keyVal = SW_ESC;
                }
                else
                {
                  keyVal = SW_NULL;
                }
               
                return keyVal;
            }
      }
    }
}


void GPIO_Configuration(void)
{
    rt_uint32_t i=0;
    rt_uint32_t j=0;
   
   
    SCU_IOMUXB_CON &= ~(1<<SW1);    // PC1 as GPIO
    GPIO_PCCON &= ~(1<<SW1);      // PC1 input

    //根据apb 频率设置ADC 转换速率
//    SCU_DIVCON &= ~(0xFF << 10); // ADC_CLKDIV_MASK
//    SCU_DIVCON |=(ladcclk_sel << 10);   //ladcclk = pclk/(ladcclk_sel+1)

    //ADC 初始化
    SCU_CLKCFG &= ~(1 << 23);//Scu_ClockEnable(LSADC_CLOCK);为0使能
    SCU_CLKCFG &= ~(1 << 24);//Scu_ClockEnable(LSADC_PCLOCK); 为0使能
    for (j = 10000;j > 0;j--);
    ADC_CTRL =ADC_EN;
}

static void key_thread_entry(void *parameter)
{
    rt_time_t next_delay;
    struct rtgui_event_kbd kbd_event;
    rt_uint32_t i,temp;
    GPIO_Configuration();

    /* init keyboard event */
    RTGUI_EVENT_KBD_INIT(&kbd_event);
    kbd_event.mod= RTGUI_KMOD_NONE;
    kbd_event.unicode = 0;

    //Linson Added
    next_delay = RT_TICK_PER_SECOND/10;
    while (1)
    {
      next_delay = RT_TICK_PER_SECOND/10;
      kbd_event.key = RTGUIK_UNKNOWN;
      kbd_event.type = RTGUI_KEYDOWN;


      temp = get_key_value();

      #define key_enter_GETVALUE()!(temp&SW_MODE)
      #define key_down_GETVALUE()   !(temp&SW_VOL)
      #define key_up_GETVALUE()   !(temp&SW_ESC)
      #define key_right_GETVALUE()!(temp&SW_NEXT)
      #define key_left_GETVALUE()   !(temp&SW_BACK)
      //以下为原来的代码
      //...
      //...
      rt_thread_delay(next_delay);
    }
}

ShawnLinson 发表于 2011-11-5 14:23:13

RST连到哪里去测不出来,
Play连接到【PC1/LCD_DEN】,也就是 第69脚
剩下的几个按键都是连到【LADC_AIN1】,也就是 第87脚

maxwell_lee 发表于 2011-11-5 14:51:57

哥,顶你。
页: [1]
查看完整版本: RM970+,RT-Thread演示【修改按键】有图有码有真相!!