因为最近做一个程序要使用到四路的ad转换,但友善给的AD驱动都是一个通道的,所以没办法要些一个多通道的驱动程序,先前用来一个比较笨的方法来做,虽然可以实现,但是自我感觉比较别扭,在论坛上看了关于AD转换的帖子,发现很少给出多通道的实现方法,下面我就把我的实现方法贴出来,一方面是总结,一方面希望给大家一点点帮助.
其实很简单,在友善提供的MINI2440_ADC.C中,只需略改一些即可,
ad一共有三个寄存器,具体我就不说兰,pdf上有,首先要AD工作,必须开通道,在函数s3c2410_adc_open中实现,所以我们要开多个通道,如下:
static int (struct inode *inode, struct file *filp)
{
init_waitqueue_head(&(adcdev.wait));
static int channel_count;
for(channel_count=0;channel_count<4;channel_count++) //连续开四个通道
{
adcdev.channel=channel_count;
adcdev.prescale=0xff;
}
DPRINTK( "adc opened\n");
return 0;
}
因为驱动程序中设置的是ENABLE_START位,所以在转换结束后,要再次设置此位来启动AD转换,这个主要在函数s3c2410_adc_read中实现,如下:
static ssize_t (struct file *filp, char *buffer, size_t count, loff_t *ppos)
{
char str[20];
int value;
size_t len;
if (down_trylock(&ADC_LOCK) == 0) {
OwnADC = 1;
START_ADC_AIN(adcdev.channel, adcdev.prescale);
wait_event_interruptible(adcdev.wait, ev_adc);
ev_adc = 0;
DPRINTK("AIN[%d] = 0x%04x, %d\n", adcdev.channel, adc_data, ADCCON & 0x80 ? 1:0);
value = adc_data;
sprintf(str,"%5d", adc_data);
copy_to_user(buffer, (char *)&adc_data, sizeof(adc_data));
OwnADC = 0;
up(&ADC_LOCK);
} else {
value = -1;
}
if(converter_channel==3) //通道选择,
{
converter_channel=0;
}
else converter_channel++;
adcdev.channel=converter_channel;
len = sprintf(str, "%d\n", value);
if (count >= len) {
int r = copy_to_user(buffer, str, len);
return r ? r : len;
} else {
return -EINVAL;
}
}
在fedora终端中输入cat /dev/adc,输出如下
1023
325
303
305
1023
297
328
284
1023
328
303
306
其中1023是0通道,旋转滑动变阻器可以改变其值,如下:41为0通道的值
41
302
289
312
42
293
315
266
41
285
261
287
其他通道的友善没有引出,也不好测试,理论上应该没什么问题,呵呵,有条件的朋友可以测试以下,顺便把测试结果告诉我,谢谢~~~