5076|12

43

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

嵌入式LINUX学习分享————ADC [复制链接]

本帖最后由 kctime 于 2014-8-9 22:35 编辑

这迟到的分享,,在这里和各位坛友和boss说声抱歉。

这个网页编辑器我不会用,,允许我发个PDF吧。。二楼我占楼,学会用了再排版。
附上VCC和GND的检测


嵌入式LINUX-helper2416-分享-adc.pdf (371.15 KB, 下载次数: 33)
嵌入式LINUX-helper2416-分享-adc.pdf (371.15 KB, 下载次数: 33)



最新回复

把文字部分直接拷贝到编辑栏中去,然后再把代码和图片插入到你想要的地方。代码不要直接复制进编辑栏,编辑器有个插入代码的工具。   详情 回复 发表于 2014-8-9 21:28

赞赏

1

查看全部赞赏

点赞 关注

回复
举报

43

帖子

0

TA的资源

一粒金砂(中级)

沙发
 
本帖最后由 kctime 于 2014-8-9 21:53 编辑

                        
刚刚才流水线上逃回家,在实习的日子里没有时间学习开发板,
回家的几天大概了解了以下开发板,加上以前的基础,弄了个ADC的程序和大家分享。

平台 fedora20 + helper2416


根据开发板手册上写的,从PC端传输文件到目标板上的几种方法里随意选一种,这里选用linux下的minicom等同于win下的超级终端


首先连接好设备



然后把arm-linux-gcc加入环境变量。exportPATH = $PATH:xxx/xxx/xxx/

  1. [ljh@localhost code]$ arm-linux-gcc
  2. arm-linux-gcc: no input files
复制代码
在终端建立三个标签,第一个开minicom,第二个用来编写,编译代码,第三个来查找文件

minicom下查找adc设备 如上图


  1. [root@jyxtec /dev]# ls -l | grep adc
  2. crw-rw----    1 root     root       10,  59 Jan  1  2000 adc
复制代码
C是字符设备,  crw-rw---- 可以读写,不能执行,

dev目录下找到adc设备

说明已经有了驱动了。。去找驱动把,,


一般是通过 makefile config 文件和grep指令查找


看看.config文件下的adc选项

  1. CONFIG_S3C_ADC=y
复制代码
在源码主目录下搜索该项

  1. [ljh@localhost s3c-linux.jyx]$ grep -rn "CONFIG_S3C_ADC"
复制代码

复制代码
  1. arch/arm/plat-samsung/Makefile:25:obj-$(CONFIG_S3C_ADC) += adc.o
复制代码
进入这个makefile的目录找到一个adc.c文件
                        
然后我看了半天,不对,

原来在.config文件下还有一个
  1. CONFIG_HELPER2416_ADC=y
复制代码

重新搜索咯
  1. drivers/char/Makefile:68:obj-$(CONFIG_HELPER2416_ADC)
  2.    += helper2416_adcdev.o
复制代码
这回对了
定位到drivers/char/。去这个目录下找到一个helper2416_adcdev.c文件,,然后看看是不是设备驱动。


在这个C文件80多行的地方

找到如下结构体
  1. static struct file_operations helper2416adcdev_fops = {
  2.     .owner   =   THIS_MODULE,
  3.     .open    =   s3c24xx_adcdev_open,
  4.     .release =   s3c24xx_adcdev_close,
  5.     .read    =   s3c24xx_adcdev_read,
  6.     .unlocked_ioctl = helper2416_adc_ioctl,
  7. };
复制代码



主要看 s3c24xx_adcdev_read helper2416_adc_ioctl 这两个函数就好了

  1. static long helper2416_adc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  2. {
  3.     int ret = 0;
  4.     int err = 0;
  5.     int ioarg = 0;

  6.     if (_IOC_TYPE(cmd) != ADCDEV_IOC_MAGIC)
  7.         return -EINVAL;
  8.     if (_IOC_NR(cmd) > ADCDEV_IOC_MAXNR)
  9.         return -EINVAL;

  10.     if (_IOC_DIR(cmd) & _IOC_READ)
  11.         err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
  12.     else if (_IOC_DIR(cmd) & _IOC_WRITE)
  13.         err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));
  14.     if (err)
  15.         return -EFAULT;

  16.     switch(cmd) {
  17.     case ADCDEV_IOCSETCHANNEL:
  18.         ret = __get_user(ioarg, (int *)arg);     
  19.         if (ioarg > 9)
  20.             return -EINVAL;      

  21.         printk("Set ADC Channel number is  %d\n",(int)ioarg);
  22.         helper2416adc.channel =  ioarg;
  23.         break;   
  24.     default:  
  25.         return -EINVAL;      
  26.     }

  27.     return ret;
  28. }
复制代码

这个函数结合开始找到的adc.c一起看,可以知道这货是选择adc通道的,就是说可以用ioctl去选择adc通道。
这里,参数要传址哦
  1.         ret = __get_user(ioarg, (int *)arg);     
  2.         if (ioarg > 9)
  3.             return -EINVAL;      

  4.         printk("Set ADC Channel number is  %d\n",(int)ioarg);
  5.         helper2416adc.channel =  ioarg;
  6.         break;   
复制代码


关于一些常量的定义在helper2416_adcdev.h 里

  1. #define ADCDEV_IOC_MAGIC 'S'
  2. #define ADCDEV_IOCSETCHANNEL _IOW(ADCDEV_IOC_MAGIC, 0x0c, int)
  3. #define ADCDEV_IOC_MAXNR 0x10
复制代码
这几个等会要 copy 到我们的应用代码里

  1. static int s3c24xx_adcdev_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
  2. {
  3. unsigned long err;
  4. int adc_value;
  5. adc_value = s3c_adc_read(helper2416adc.padc_client, helper2416adc.channel);
  6. err = copy_to_user(buff, &adc_value, sizeof(adc_value));
  7. return sizeof(adc_value);
  8. }

复制代码
这个 read 函数里调用的东西在adc.c文件里

  1. int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch)
  2. {
  3.         DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
  4.         int ret;

  5.         client->convert_cb = s3c_convert_done;
  6.         client->wait = &wake;
  7.         client->result = -1;

  8.         ret = s3c_adc_start(client, ch, 1);
  9.         if (ret < 0)
  10.                 goto err;

  11.         ret = wait_event_timeout(wake, client->result >= 0, HZ / 2);
  12.         if (client->result < 0) {
  13.                 ret = -ETIMEDOUT;
  14.                 goto err;
  15.         }

  16.         client->convert_cb = NULL;
  17.         return client->result;

  18. err:
  19.         return ret;
  20. }
  21. EXPORT_SYMBOL_GPL(s3c_adc_read);
复制代码
最后一个宏表示可以被其他的模块使用,,就说明了这货不是要找的驱动文件
再加上这个文件里面没有定义 file_operations 结构体,,所以果断 ctrl+W 了。。


接下来来写 ADC 的代码,
主要就是 打开文件 -->> 选择通道 --> 读取 ADC 的值 --> 要么继续读取,要么退出。。。。
写一个一次的先试试。

  1. <div class="blockcode"><blockquote>//包含头文件


  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. #include <sys/ioctl.h>
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <errno.h>

  10. //定义常量和符号

  11. #define ADCDEV_IOC_MAGIC 'S'
  12. #define ADCDEV_IOCSETCHANNEL _IOW(ADCDEV_IOC_MAGIC, 0x0c, int)
  13. #define ADCDEV_IOC_MAXNR 0x10


  14. //定义设备文件路径
  15. #define ADC_PATH "/dev/adc"


  16. int main()
  17. {
  18.         int adc_dev;
  19.         int ret;
  20.         int data;
  21.       int i=0;

  22.         if((adc_dev=open(ADC_PATH,O_RDWR))<0)  //打开文件,,一定要检测是否打开成功哦
  23.         {
  24.                 perror("open:");
  25.                 exit(1);
  26.             } else        
  27.         {
  28.                 printf("Open ADC DeviceOK\n");
  29.                
  30.                 ret=ioctl(adc_dev,ADCDEV_IOCSETCHANNEL,&i);                //设置ADC通道,记得传址
  31.                 ret = read(adc_dev, &data, sizeof(data));                        //读取ADC转换结果,记得对比返回值
  32.                 if(ret != sizeof(data))                                                
  33.                 {
  34.                         if(errno != EAGAIN)
  35.                         {
  36.                                 printf("Read ADC Device Faild!\n");
  37.                         }

  38.                         
  39.                 }
  40.                 else
  41.                 {
  42.                         printf("Read ADC value is: %d\n", data);
  43.                 }


  44.                 if ( close(adc_dev) < 0 )    //最后记得关闭文件。
  45.                 {
  46.                         perror("close:");
  47.                         exit(1);
  48.                 }
  49.                 else
  50.                         printf("Close ADC Device OK\n");        
  51.         }


  52. }
复制代码





                                                                                                                                                        论坛ID:kctime
                                                                                                                                                        提交时间:2014.08.09


 
 

回复

554

帖子

0

TA的资源

版主

板凳
 
写得很不错哈,其实,HELPER2416上的LINUX驱动都有实现,只是文档还没有跟上,学习LINUX就像学楼主这种精神,跟踪到代码里去就明白怎么回事了,但是这个是慢慢练出来的,不能一步到位,初学者开始的时候不要走得太深,平衡难以把握,以兴趣为准,我没好的建议!呵呵

点评

源代码里有个helper2416.。。的config文件。那里面木有设置PWM。。。当初找了好久的说。。  详情 回复 发表于 2014-8-9 19:44
谢谢boss鼓励哈,,,  详情 回复 发表于 2014-8-9 19:43
 
个人签名My dreams will go on...
http://www.jyxtec.com
 
 

回复

43

帖子

0

TA的资源

一粒金砂(中级)

4
 
spacexplorer 发表于 2014-8-9 19:41
写得很不错哈,其实,HELPER2416上的LINUX驱动都有实现,只是文档还没有跟上,学习LINUX就像学楼主这种精神 ...

谢谢boss鼓励哈,,,
 
 
 

回复

43

帖子

0

TA的资源

一粒金砂(中级)

5
 
spacexplorer 发表于 2014-8-9 19:41
写得很不错哈,其实,HELPER2416上的LINUX驱动都有实现,只是文档还没有跟上,学习LINUX就像学楼主这种精神 ...

源代码里有个helper2416.。。的config文件。那里面木有设置PWM。。。当初找了好久的说。。

点评

这个事情大概是我失误了!  详情 回复 发表于 2014-8-9 19:47
 
 
 

回复

554

帖子

0

TA的资源

版主

6
 
kctime 发表于 2014-8-9 19:44
源代码里有个helper2416.。。的config文件。那里面木有设置PWM。。。当初找了好久的说。。

这个事情大概是我失误了!

点评

boss 那个J14的间距是多少阿,,  详情 回复 发表于 2014-8-9 19:52
 
个人签名My dreams will go on...
http://www.jyxtec.com
 
 

回复

43

帖子

0

TA的资源

一粒金砂(中级)

7
 
spacexplorer 发表于 2014-8-9 19:47
这个事情大概是我失误了!

boss 那个J14的间距是多少阿,,

点评

J14间距是2.0的,标准杜邦线可能不行。。。  详情 回复 发表于 2014-8-9 20:45
 
 
 

回复

241

帖子

4

TA的资源

纯净的硅(初级)

8
 
感谢廖大神的恩惠,这个必须要顶,这个东西正是我所需要的,赶紧回学校带我︿( ̄︶ ̄)︽( ̄︶ ̄)︿飞.飞.飞.

点评

没地方住好么。。帮我排版。。。。我发2楼去  详情 回复 发表于 2014-8-9 21:18
 
 
 

回复

554

帖子

0

TA的资源

版主

9
 
kctime 发表于 2014-8-9 19:52
boss 那个J14的间距是多少阿,,

J14间距是2.0的,标准杜邦线可能不行,得用2.0的。。。

点评

还是自己压排线吧。。。淘宝有头哈  详情 回复 发表于 2014-8-9 21:17
 
个人签名My dreams will go on...
http://www.jyxtec.com
 
 

回复

43

帖子

0

TA的资源

一粒金砂(中级)

10
 
spacexplorer 发表于 2014-8-9 20:45
J14间距是2.0的,标准杜邦线可能不行,得用2.0的。。。

还是自己压排线吧。。。淘宝有头哈
 
 
 

回复

43

帖子

0

TA的资源

一粒金砂(中级)

11
 
yuanlai2010 发表于 2014-8-9 20:44
感谢廖大神的恩惠,这个必须要顶,这个东西正是我所需要的,赶紧回学校带我︿( ̄︶ ̄)︽( ̄︶ ̄)︿飞.飞.飞 ...

没地方住好么。。帮我排版。。。。我发2楼去

点评

把文字部分直接拷贝到编辑栏中去,然后再把代码和图片插入到你想要的地方。代码不要直接复制进编辑栏,编辑器有个插入代码的工具。  详情 回复 发表于 2014-8-9 21:28
 
 
 

回复

241

帖子

4

TA的资源

纯净的硅(初级)

12
 
kctime 发表于 2014-8-9 21:18
没地方住好么。。帮我排版。。。。我发2楼去

把文字部分直接拷贝到编辑栏中去,然后再把代码和图片插入到你想要的地方。代码不要直接复制进编辑栏,编辑器有个插入代码的工具。

点评

排版好麻烦。。。。。睡觉去。。  详情 回复 发表于 2014-8-9 21:53
 
 
 

回复

43

帖子

0

TA的资源

一粒金砂(中级)

13
 
yuanlai2010 发表于 2014-8-9 21:28
把文字部分直接拷贝到编辑栏中去,然后再把代码和图片插入到你想要的地方。代码不要直接复制进编辑栏,编 ...

排版好麻烦。。。。。睡觉去。。
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表