ADC按键驱动
Adc键盘原理图如下,将串联电阻之间分别用按键引出来与地相连,当按键按下时端电压会发生改变。基本思想是在ADC驱动基础上,对采样电压进行判断,检测是哪一个按键按下。
1. ADC驱动分析
在init()函数中,首先获取adc的时钟,并用clk_enable进行使能,然后使用ioremap将ADC寄存器地址映射到kernel中(内核中对ADC只能使用虚拟地址进行访问),之后调用probe()函数完成定时器的初始化和ADC寄存器的初始化。
/
内核定时器使用步骤:
<1>使用static struct timer_list adc_key_timer定义一个名字为adc_key_time的定时器。
<2>adc_key_time.function =adc_key_timer_fun 定义一个定时器中断服务函数。
<3>add_time(&adc_key_timer)将定时器在kernel 中注册
<4>mod_timer(&adc_key_timer,jiffies+HZ)最后激活定时器开始计时,时间由jiffies+HZ设定。
调试方法:
<1>寄存器初始化一般放在probe函数中,可以使用prink来反映寄存器(特别是中断)是否配置成功
<2>在单板下使用如下命令:
cd /proc/gcore
echo RD fe005400 7 > regs ///fe005400为寄存器地址 7为读取寄存器个数
来读取寄存器内是否被设置成功
/
接下来使用request_irq函数完成ADC中断的注册,需要注意的是在该函数中,ADC的中断号需要加一,并且中断标志位设置成为IRQF_SHARED。在初始化最后部分使用misc_register将ADC当做misc设备完成注册。
2. 在file_operations结构体中主要定义了三个函数,其中adc_key_open是完成设备打开、adc_key_release是设备关闭,adc_key_read()是完成设备的读取。在adc_key_read()函数中,首先定义一个全局变量ev_adc作为按键按下的标志位,当按键没有按下时,使用wait_enent_interruptible进入等待队列,当按键按下触发中断后,使用wake_up_interruptible唤醒等待队列,然后在read函数中将按键标志位ev_adc清零,使用copy_to_user()函数将kernel中的数据传递到应用层,供用户使用。然后使用mod_timer()触发定时器,跳入定时器中断服务程序中去。