|
感谢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_VOL 0x260 //VOL
#define ADC_ESC 0x035 //ESC、Hold
#define ADC_MAX 0x3FF //
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) // [0: ADC stop; 1: Conversion in progress]
{
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) // [0: ADC stop; 1: Conversion in progress]
{
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); // [17: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);
}
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|