EM9287 Linux环境的AD数据采集

 2013-11-7          [nemail]    
[lablebox]

        EM9287是英创公司新近推出的,专门针对网络通讯、智能终端等应用的工控主板产品。EM9287可选择预装Linux-3.9.7操作系统。在Linux-3.9.7中,AD数据采集已采用新的工业IO(简称IIO)驱动程序框架,本文主要介绍应用程序如何读取相关的AD数据。此外,英创公司的另一款主流工控主板产品EM9280也升级到Linux-3.9.7,具有与EM9287完全相同的AD通道,因此本文所介绍的AD数据读取方法同样适用于EM9280。

 

        EM9287支持2路单端模拟信号输入AIN1和AIN2,输入量程为 0V – 3.6V,信号管脚在CN1的17#和18#管脚。除了支持2路AD外,应用程序还可读取主板的CPU芯片iMX28的芯片当前温度,以了解设备的运行情况。以下是测试程序:

 

        #include <STDIO.H>
        #include <STDLIB.H> 
        #include <FCNTL.H> 
        #include <UNISTD.H> 
        #include <MATH.H> 

        char iiotype[16][32] = { 
                ''in_voltage0_raw''
                'in_voltage1_raw', 
                'in_voltage2_raw', 
                'in_voltage3_raw', 
                'in_voltage4_raw', 
                'in_voltage5_raw', 
                'in_voltage6_raw', 
                'in_voltage7_raw', 
                'in_temp8_raw', 
                'in_temp9_raw', 
                'in_voltage10_raw', 
                'in_voltage11_raw', 
                'in_voltage12_raw', 
                'in_voltage13_raw', 
                'in_voltage14_raw', 
                'in_voltage15_raw'
}; 

        // return = 0: voltage value from AIN1, unit: mV 
        // < 0: failed
 
        int read_AIN1(float *fvoltage) 
        { 
                int value, ret = 0; 
                char filename[80]; 
                FILE *fp; 
                char buf[20]; 

                sprintf( filename, '/sys/bus/iio/devices/iio:device0/%s', iiotype[0]); 
                fp = fopen(filename, 'rt' ); 
                if( fp==NULL ) 
                { 
                        printf('open %s fail!\n', filename); 
                        *fvoltage = 0.0; 
                        ret = -1; 
                        return ret; 
                } 
                fread( buf, 1, sizeof(buf), fp ); 
                fclose(fp); 
        
                // convert to integer 
                sscanf( buf, '%d', &value ); 
                *fvoltage = 0.9 * value; 
                return ret; 
        } 

        // return = 0: voltage value from AIN2, unit: mV 
        // < 0: failed
 
        int read_AIN2(float *fvoltage) 
        { 
                int value, ret = 0; 
                char filename[80]; 
                FILE *fp; 
                char buf[20]; 

                sprintf( filename, '/sys/bus/iio/devices/iio:device0/%s', iiotype[1]); 
                fp = fopen(filename, 'rt' ); 
                if( fp==NULL ) 
                { 
                        printf('open %s fail!\n', filename); 
                        *fvoltage = 0.0; 
                        ret = -1; 
                        return ret; 
                } 
                fread( buf, 1, sizeof(buf), fp ); 
                fclose(fp); 

                // convert to integer 
                sscanf( buf, '%d', &value ); 
                *fvoltage = 0.9 * value; 
                return ret; 
        } 

        // return = 0: temperature value from CPU, unit: K (Kalvin) 
        // < 0: failed
 
        int read_CPU_temperature(float *ftemp) 
        { 
                int v_ch9, v_ch8, ret = 0; 
                char filename[80]; 
                FILE *fp; 
                char buf[20]; 

                sprintf( filename, '/sys/bus/iio/devices/iio:device0/%s', iiotype[9]); 
                fp = fopen(filename, 'rt' ); 
                if( fp==NULL ) 
                { 
                        printf('open %s fail!\n', filename); 
                        *ftemp = 0.0; 
                        ret = -1; 
                        return ret; 
                } 
                fread( buf, 1, sizeof(buf), fp ); 
                fclose(fp); 

                // convert to integer 
                sscanf( buf, '%d', &v_ch9 ); 

                sprintf( filename, '/sys/bus/iio/devices/iio:device0/%s', iiotype[8]); 
                fp = fopen(filename, 'rt' ); 
                if( fp==NULL ) 
                { 
                        printf('open %s fail!\n', filename); 
                        *ftemp = 0.0; 
                        ret = -1; 
                        return ret; 
                } 
                fread( buf, 1, sizeof(buf), fp ); 
                fclose(fp); 

                // convert to integer 
                sscanf( buf, '%d', &v_ch8 ); 

                *ftemp = ((float)(v_ch9 - v_ch8) * 1012) / 4000; 
                return ret; 
        } 

        int main(int argc, char** argv) 
        { 
                int ret = 0; 
                float fvalue; 

                printf('EM9280/EM9287 IIO AD test v2.0\n'); 

                // read AIN1 
                ret = read_AIN1(&fvalue); 
                if(ret < 0) 
                { 
                        return ret; 
                } 
                printf('AIN1 = %.2f mV\n', fvalue); 

                // read AIN2 
                ret = read_AIN2(&fvalue); 
                if(ret < 0) 
                { 
                        return ret; 
                } 
                printf('AIN2 = %.2f mV\n', fvalue); 

                // read CPU temperature 
                ret = read_CPU_temperature(&fvalue); 
                if(ret < 0) 
                { 
                        return ret; 
                } 
                printf('CPU Temperature = %.1f K, (%.1f C degree)\n', fvalue, (fvalue - 273)); 

                return ret; 
        }

 

        在控制台(console)窗口,也可通过Linux命令查看IIO驱动的原始通道:

 

 

        进一步,可用cat命令读取各个通道AD转换的原始数据,EM9280、EM9287内部AD分辨率为12-bit,所以原始数据范围为:0 – 4095。开发人员可通过以下命令来快速了解设备的AD数据状况。

        #cat in_voltage0_raw //   读取CH0的原始数据
        #cat in_voltage1_raw //   读取CH1的原始数据 
        #cat in_temp8_raw //   读取CPU温度的原始数据 
        #cat in_temp9_raw //   读取CPU温度的原始数据

 

        其他的原始通道涉及EM9287的触摸屏、内部供电电源等,已不在本文的介绍范围。

[lablebox]