栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Linux通过shell命令读取ADC电压

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux通过shell命令读取ADC电压

Linux通过shell命令读取ADC电压 Linux的ADC在应用层上可以直接操作/sys/bus/iio/devices/iio:device0/目录的文件,而对于Linux的ADC操作有两种模式,一种是单次读取模式,第二种是多次读取模式。 一、单次读取
对于Linux系统上的ADC读取,在m3352上支持4路ADC输入,系统提供/sys文件系统接口操作,
在/sys/bus/iio/devices/iio:device0/目录下有in_voltage4_raw~in_voltage7_raw这四个文件,
分别读取这4个文件,可获得对应的ADC值。

cat /sys/bus/iio/devices/iio:device0/in_voltage4_raw 2782

二、多次读取 官方直接写一个C的程序去实现的,可能水平不够,没太看懂这样做的意义。直接用shell写个脚本多执行几次上面的命令不就成多次读取了吗,等以后回来来看看两者的利弊

我写的shell

#!/bin/bash
for a in {1..10}
do
 cat /sys/bus/iio/devices/iio:device0/in_voltage$1_raw
 sleep 1
done

官方给的就复杂了

1.定义两个API函数
int find_type_by_name(const char name, const char type)
获取设备,其中name为需要打开的文件名

int build_channel_array(const char device_dir, struct iio_channel_info **ci_array, int counter)
根据ADC文件获取相应的ADC

2.程序源码

dev_num = find_type_by_name(device_name, "iio:device");            
if (dev_num < 0) {
    printf("Failed to find the %sn", device_name);
    ret = -ENODEV;
    goto error_ret;
}
asprintf(&dev_dir_name, "%siio:device%d", iio_dir, dev_num);            
ret = build_channel_array(dev_dir_name, &infoarray, &num_channels);    
if (ret) {
    printf("Problem reading scan element informationn");
    printf("diag %sn", dev_dir_name);
    goto error_ret;
}
ret = asprintf(&buf_dir_name, "%siio:device%d/buffer", iio_dir, dev_num);
if (ret < 0) {
    ret = -ENOMEM;
    goto error_ret;
}
ret = write_sysfs_int("length", buf_dir_name, buf_len);                
if (ret < 0)
    goto error_free_buf_dir_name;

ret = write_sysfs_int("enable", buf_dir_name, 1);                    
if (ret < 0)
    goto error_free_buf_dir_name;
ret = asprintf(&buffer_access, "/dev/iio:device%d", dev_num);            
if (ret < 0) {
    ret = -ENOMEM;
    goto error_free_buf_dir_name;
}

fp = open(buffer_access, O_RDONLY | O_NONBLOCK);            
if (fp == -1) { 
    printf("Failed to open %sn", buffer_access);
    ret = -errno;
goto error_free_buf_dir_name;
}
scan_size = size_from_channelarray(infoarray, num_channels);            
data = malloc(scan_size*buf_len);
if (!data) {
    ret = -ENOMEM;
    goto error_close_buffer_access;
}
for (j = 0; j < num_loops; j++) {                                
    usleep(timedelay);
    read_size = read(fp, data, buf_len*scan_size);
    if (read_size == -EAGAIN) {
    printf("nothing availablen");
        continue;
    }
    for (i = 0; i < read_size/4; i++, data+=4)
printf("ADC Value: %dn", *(long*)data);
}

ret = write_sysfs_int("enable", buf_dir_name, 0);                    
if (ret < 0)
    goto error_close_buffer_access;

值得注意的是,ADC的多次读取模式中,每次只能开启一个通道,若要切换通道必须先关闭已打开的ADC通道。

(1)创建设备节点
创建/dev/iio:device0设备节点,节点信息,参考/sys/bus/iio/devices/iio:device0/dev文件:
#cat /sys/bus/iio/devices/iio:device0/dev
251:0
设备节点主次设备号是251,0。创建命令:

(2)设置continuos模式
[root@M3352 ~]# echo continuous > /sys/bus/iio/devices/iio:device0/mode

(3)使能通道4
[root@M3352 ~]# echo 1 > /sys/bus/iio/devices/iio:device0/scan_elements/in_volta4_en

(4)运行范例程序

[root@M3352 ~]# ./generic_buffer -n tiadc -l 16 -c 5
ADC Value: 2199
ADC Value: 2199
ADC Value: 2199
ADC Value: 2200
ADC Value: 2202

其中,l和c参数,请参考generic_buffer.c源码。
 
(5)切换通道
切换通道时,则需要先关闭通道4,打开需要的通道,如通道5:

[root@M3352 ~]# echo 0 > /sys/bus/iio/devices/iio:device0/scan_elements/in_volta4_en
[root@M3352 ~]# echo 1 > /sys/bus/iio/devices/iio:device0/scan_elements/in_volta5_en

 然后继续读取即可。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/836912.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号