【OK210试用体验】4.1 Linux下驱动的编写---ADC篇 - 在线问答 - 电子技术论坛 - 最好最受欢迎电子论坛!

【OK210试用体验】4.1 Linux下驱动的编写---ADC篇

中科院 ( 楼主 ) 2015-9-21 15:47:35  只看该作者 倒序浏览
由于还没有对S5PV210的AD/DA部分有过说明,所以这里以ADC驱动为例谈一下:
首先要定义ADC的相关的结构体:
  1. struct s3c_adc_request {
  2.         /* for linked list */
  3.         struct list_head *list;
  4.         /* after finish ADC sampling, s3c_adc_request function call this function with three parameter */
  5.         void (*callback)(int channel, unsigned long int param, unsigned short sample);
  6.         /* for private data */
  7.         unsigned long int param;
  8.         /* selected channel for ADC sampling */
  9.         int channel;
  10. };
复制代码
在ADC初始化的部分就要检查是不是用户已经赋值,如果没有,就要完成赋给他默认的值
然后是ADC转化部分的主要几个函数:
  1. static unsigned int s3c_adc_convert(void)
  2. {
  3.         unsigned int adc_return = 0;
  4.         unsigned long data0;
  5.         unsigned long data1;

  6.         writel((readl(base_addr + S3C_ADCCON) | S3C_ADCCON_PRSCEN) & ~S3C_ADCCON_STDBM,
  7.                 base_addr + S3C_ADCCON);

  8.         writel((adc_port & 0xF), base_addr + S3C_ADCMUX);

  9.         udelay(10);

  10.         writel(readl(base_addr + S3C_ADCCON) | S3C_ADCCON_ENABLE_START,
  11.                 base_addr + S3C_ADCCON);

  12.         do {
  13.                 data0 = readl(base_addr + S3C_ADCCON);
  14.         } while (!(data0 & S3C_ADCCON_ECFLG));

  15.         data1 = readl(base_addr + S3C_ADCDAT0);

  16.         writel((readl(base_addr + S3C_ADCCON) | S3C_ADCCON_STDBM) & ~S3C_ADCCON_PRSCEN,
  17.                 base_addr + S3C_ADCCON);

  18.         if (plat_data->resolution == 12)
  19.                 adc_return = data1 & S3C_ADCDAT0_XPDATA_MASK_12BIT;
  20.         else
  21.                 adc_return = data1 & S3C_ADCDAT0_XPDATA_MASK;

  22.         return adc_return;
  23. }
复制代码
如何把转化的值发送给系统,就想要另外一个函数进行处理
  1. int s3c_adc_get(struct s3c_adc_request *req)
  2. {
  3.         unsigned adc_channel = req->channel;
  4.         int adc_value_ret = 0;

  5.         adc_value_ret = s3c_adc_convert();

  6.         req->callback(adc_channel, req->param, adc_value_ret);

  7.         return 0;
  8. }
复制代码

在应用程序部分,需要做的事情就比较简单,主要是读出通道内的值并且转化为电压:

  1. int main(void)
  2. {
  3.         fprintf(stderr, "press Ctrl-C to stopn");
  4.         int fd = open("/dev/adc", "r");
  5.         if (fd < 0) {
  6.                 perror("open ADC device:");
  7.                 return 1;
  8.         }
  9.         ioctl(fd,'s',0);
  10.         int ADCValue=0;
  11.         double voltage=0;
  12.         for(;;) {
  13.                 ADCValue=0;
  14.                 voltage=0;
  15.                 read(fd, &ADCValue, sizeof(int));
  16.                 if(ADCValue==-1) continue;
  17.                 //channel 0 12bit ADC max voltage = 3.3v /10K+1k *10K =3v
  18.                 voltage=(float)3.3*ADCValue/4096;
  19.                 printf("adc = %d voltage=%f V n",ADCValue,voltage);
  20.                 usleep(500* 1000);
  21.         }
  22.        
  23.         close(fd);
  24. }
复制代码




0个回复

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

本版积分规则


关闭

站长推荐上一条 /6 下一条

小黑屋|手机版|Archiver|电子发烧友 ( 湘ICP备2023018690号 )

GMT+8, 2024-4-20 02:01 , Processed in 0.613106 second(s), Total 57, Slave 42 queries .

Powered by 电子发烧友网

© 2015 bbs.elecfans.com

微信扫描
快速回复 返回顶部 返回列表