首页 > 其他分享 > 基于I.MX6UL平台的ADS1256驱动开发五.实现功能

基于I.MX6UL平台的ADS1256驱动开发五.实现功能

时间:2022-12-19 19:36:12浏览次数:51  
标签:读取 DRDY int MUX MX6UL 寄存器 驱动 ADS1256

在前面我们已经完成了基本的寄存器读写操作,下面我们就可以根据数据手册来完成基础AD功能的实现。

初始化

初始化的过程基本上是从AD板供应商提供的Demo移植的。

 1 void ADS1256_CfgADC(ADS1256_GAIN_E _gain, ADS1256_DRATE_E _drate)
 2 {
 3     g_tADS1256.Gain = _gain;
 4     g_tADS1256.DataRate = _drate;
 5 
 6     ADS1256_WaitDRDY();
 7 
 8     {
 9         uint8_t buf[4];        /* 暂存ADS1256 寄存器配置参数,之后连续写4个寄存器 */
10 
11         /* 状态寄存器定义
12             Bits 7-4 ID3, ID2, ID1, ID0  Factory Programmed Identification Bits (Read Only)
13 
14             Bit 3 ORDER: Data Output Bit Order
15                 0 = Most Significant Bit First (default)
16                 1 = Least Significant Bit First
17             Input data  is always shifted in most significant byte and bit first. Output data is always shifted out most significant
18             byte first. The ORDER bit only controls the bit order of the output data within the byte.
19 
20             Bit 2 ACAL : Auto-Calibration
21                 0 = Auto-Calibration Disabled (default)
22                 1 = Auto-Calibration Enabled
23             When Auto-Calibration is enabled, self-calibration begins at the completion of the WREG command that changes
24             the PGA (bits 0-2 of ADCON register), DR (bits 7-0 in the DRATE register) or BUFEN (bit 1 in the STATUS register)
25             values.
26 
27             Bit 1 BUFEN: Analog Input Buffer Enable
28                 0 = Buffer Disabled (default)
29                 1 = Buffer Enabled
30 
31             Bit 0 DRDY :  Data Ready (Read Only)
32                 This bit duplicates the state of the DRDY pin.
33 
34             ACAL=1使能自校准功能。当 PGA,BUFEEN, DRATE改变时会启动自校准
35         */
36         buf[0] = (0 << 3) | (1 << 2) | (0 << 1);//此处(0 << 1)表示关闭BUFFER,改为(1 << 1)表示打开BUFFER
37         /*
38         打开或关闭BUFFER会影响芯片可采集电压范围.详见ADS1256数据手册第3页
39         关闭BUFFER,采集范围:AGND-0.1    ~    AVDD+0.1
40         打开BUFFER,采集范围:AGND            ~    AVDD+2.0
41         */
42 
43         buf[1] = 0x08;    /* 高四位0表示AINP接 AIN0,  低四位8表示 AINN 固定接 AINCOM */
44 
45         /*    ADCON: A/D Control Register (Address 02h)
46             Bit 7 Reserved, always 0 (Read Only)
47             Bits 6-5 CLK1, CLK0 : D0/CLKOUT Clock Out Rate Setting
48                 00 = Clock Out OFF
49                 01 = Clock Out Frequency = fCLKIN (default)
50                 10 = Clock Out Frequency = fCLKIN/2
51                 11 = Clock Out Frequency = fCLKIN/4
52                 When not using CLKOUT, it is recommended that it be turned off. These bits can only be reset using the RESET pin.
53 
54             Bits 4-2 SDCS1, SCDS0: Sensor Detect Current Sources
55                 00 = Sensor Detect OFF (default)
56                 01 = Sensor Detect Current = 0.5 μ A
57                 10 = Sensor Detect Current = 2 μ A
58                 11 = Sensor Detect Current = 10μ A
59                 The Sensor Detect Current Sources can be activated to verify  the integrity of an external sensor supplying a signal to the
60                 ADS1255/6. A shorted sensor produces a very small signal while an open-circuit sensor produces a very large signal.
61 
62             Bits 2-0 PGA2, PGA1, PGA0: Programmable Gain Amplifier Setting
63                 000 = 1 (default)
64                 001 = 2
65                 010 = 4
66                 011 = 8
67                 100 = 16
68                 101 = 32
69                 110 = 64
70                 111 = 64
71         */
72         buf[2] = (0 << 5) | (0 << 3) | (_gain << 0);
73         //ADS1256_WriteReg(REG_ADCON, (0 << 5) | (0 << 2) | (GAIN_1 << 0));    /* 选择1;1增益, 输入正负5V */
74 
75         /* 因为切换通道和读数据耗时 123uS, 因此扫描中断模式工作时,最大速率 = DRATE_1000SPS */
76         buf[3] = s_tabDataRate[_drate];    // DRATE_10SPS;    /* 选择数据输出速率 */
77 
78         CS_0();    /* SPI片选 = 0 */
79         ADS1256_Send8Bit(CMD_WREG | 0);    /* 写寄存器的命令, 并发送寄存器地址 */
80         ADS1256_Send8Bit(0x03);            /* 寄存器个数 - 1, 此处3表示写4个寄存器 */
81 
82         ADS1256_Send8Bit(buf[0]);    /* 设置状态寄存器 */
83         ADS1256_Send8Bit(buf[1]);    /* 设置输入通道参数 */
84         ADS1256_Send8Bit(buf[2]);    /* 设置ADCON控制寄存器,增益 */
85         ADS1256_Send8Bit(buf[3]);    /* 设置输出数据速率 */
86 
87         CS_1();    /* SPI片选 = 1 */
88     }

初始化主要就是对STATUS、MUX、ADCON和DRATE4个寄存器进行配置。配置的思路备注里很清楚了。

读取数据

读取数据要切换通道,通道的切换是通过设置MUX寄存器实现的,但是MUX寄存器在写入后需要给其他的指令才可以读取数据,手册上有相关的时序图

我们只需要在DRDY被拉低的时候配置MUX寄存器就行了,要注意点是RDATA指令读取到的数据时上一组MUX选择的输入信号。按照上面的时序图,DRDY拉低以后配置的MUX选择的是2、3脚输入的信号,但是读取到的数据是MUX=0x01时的数据。待下个读取周期读取到的数据则是MUX=0x23时候的。

 

 1 /**
 2  * @brief 读取指定通道码值
 3  * 
 4  * @param _ch 
 5  * @return int32_t 
 6  */
 7 int32_t ADS1256_ReadAdc(uint8_t _ch)
 8 {
 9 
10     // while (DRDY_IS_LOW());
11 
12     /* ADS1256 数据手册第21页 */
13     ADS1256_WaitDRDY();        /* 等待 DRDY = 0 */
14 
15     ADS1256_SetChannal(_ch);    /* 切换模拟通道 */
16     udelay(5);
17 
18     ADS1256_WriteCmd(CMD_SYNC);
19     udelay(5);
20 
21     ADS1256_WriteCmd(CMD_WAKEUP);
22     udelay(5);
23 
24     return (int32_t)ADS1256_ReadData();
25 }

前面一章结尾说了,我们这一版本的驱动不用中断来触发采样,所以做了个延时来轮询DRDY的状态,只要DRDY变低,就开始切换通道,发送同步指令(SYNC),唤醒指令(WAKEUP),最后是读取指令。完成以后,我们可以测试一下

 

加载看看效果

 

到此为止,我们已经拿到AD转换的码值了。

用户态的交互

现在我们已经在内核中实现了模块的驱动,但是我们需要在用户态的程序中获取到实际的数据,并且由于在内核中最好不要处理浮点类数据,我们在文件操作合集中的对应函数中将数据传递给用户态程序

 1 ssize_t ads1256_read(struct file *file, char __user *buf, size_t cnt, loff_t *off)
 2 {
 3 
 4     struct ads1256_device *dev = (struct ads1256_device *)file->private_data;
 5     int ret = 0;
 6     uint8_t ch_num=8;
 7     int32_t adc[8];
 8     int i;
 9 
10     printk("ads1256 read\r\n");
11     for (i = 0; i < ch_num; i++)                            //数据提取与转换
12     {
13         /* 从全局缓冲区读取采样结果。 采样结果是在中断服务程序中读取的。*/
14         adc[i] = ADS1256_ReadAdc(i);
15     }
16     ret = copy_to_user(buf,adc,sizeof(adc));
17     return ret;
18 }

就是在一个8次的for循环中,分别读取各个通道的AD码值,然后通过copy_to_user传递给用户态就可以了。

用户态程序

这里只体现如何从内核态拿到数据并且如何从码值换算到对应的电压值上

 1 #include <sys/types.h>
 2 #include <sys/stat.h>
 3 #include <fcntl.h>
 4 #include <unistd.h>
 5 #include <stdio.h>
 6 #include <stdlib.h>
 7 
 8 
 9 /**
10  * @brief 
11  * 
12  * @param argc                      //参数个数 
13  * @param argv                      //参数
14  * @return int 
15  */
16 int main(int argc,char *argv[])
17 {
18     char *filename;                 //文件名
19 
20     int value = 0;
21     int32_t adc[8];
22     float volt[8];
23     int ret = 0;                    //初始化操作返回值
24     int f = 0;                      //初始化文件句柄
25     int i = 0;
26 
27     filename = argv[1];
28     if(argc != 2){                  //输入参数个数不为3,提示输入格式错误
29         printf("input format error!\r\n");
30     }
31     printf("filename: %s\r\n", filename);
32     
33     f = open(filename, O_RDWR);     //打开文件
34     
35     if(f < 0){
36     printf("file open error\r\n");
37     return -1;
38     }
39     
40     read(f,&adc,sizeof(adc));
41 
42     for(i=0;i<8;i++){
43         volt[i] = (float)adc[i] / 8388607 *5.0;
44         printf("channel %d volt = %.5f\r\n",i,volt[i]);
45     }
46 
47     close(f);                       //关闭文件
48     return 0;
49 }

这里偷了个懒,不考虑负电压的情况,直接将码值换算至对应的电压上。由于我们在配置IC的时候将PGA配置为默认值1,所以输入量程为±5V,在最高位为0的时候为正电压值,5V对应码值为0x7FFFFF,对应值为1/8388607。乘以5就是每个LSB对应的电压值。在编译的时候可以加上下面加红的命令来指定一下指令集,使能硬件浮点运算

arm-linux-gnueabihf-gcc -march=armv7-a -mfpu=neon -mfloat-abi=hard ad1256APP.c -o ad1256APP

搞定以后可以测试一下

因为项目还用不到负电压的测量,这里先不考虑负电压的计算方式。并且还可以根据实际码值来动态调整PGA的值,都是可以后期优化的。先这样吧!

标签:读取,DRDY,int,MUX,MX6UL,寄存器,驱动,ADS1256
From: https://www.cnblogs.com/yinsedeyinse/p/16991096.html

相关文章

  • 基于I.MX6UL平台的ADS1256驱动开发四.IC操作
    在前面章节我们已经完成了最基础的驱动框架的搭建,下面就需要在GPIO可以正常工作的条件下进行IC的读写操作。首先我们要完成最基础的读写操作,然后所有的操作都是基于这个读......
  • USB总线-Linux内核USB3.0设备控制器之dwc3 gadget驱动初始化过程分析(五)
    1.概述USB设备控制器(UDC)驱动的框图如下图所示,由三部分组成。第一部分是UDC驱动核心层,在drivers/usb/gadget/udc/core.c文件中实现,该层是一个兼容层,将USBFunction驱动和具......
  • 【Python自动化框架pytest(三)--数据驱动(参数化)】
    参数化,就是把测试过程中的数据提取出来,通过参数传递不同的数据来驱动用例运行。其实也就是数据驱动的概念。在Unittest中,我们讲过使用ddt库配合unittest实现数据驱动......
  • boa服务器移植到mx6ull
    BOA服务器的移植 1、源码下载http://www.boa.org/News!(lastupdated23February2005)LatestReleasedVersion(0.94.13)here(signaturehere) ---下载地址......
  • 打印乱码,打印驱动安装
    打印机装不了,在“伺服器内容”把驱动删掉,再安装就可以了打印乱码时,Epsonlq-2600k驱动选用:1170、1600、2170、2500的驱动,也可能是打印线的问题。HPLj1160在win98装2100驱......
  • Python SQL 驱动程序 - pymssql
    PythonSQL驱动程序-pymssql前言pymssql官方地址:https://pypi.org/project/pymssql/一、下载pymssql不通的操作系统,不同的Python版本下载对应的pymssql注意:博主运......
  • MacOS怎么安装打印驱动和连接打印机
    一、下载官方驱动https://support.apple.com/kb/dl1888?locale=en_US  二、安装驱动把下载的驱动放到Downloads文件夹下。打开终端,键入以下命令:ps:下载的驱动文......
  • 网络设备驱动
    #include<linux/errno.h>#include<linux/netdevice.h>#include<linux/etherdevice.h>#include<linux/kernel.h>#include<linux/types.h>#include<linux/fcntl.......
  • Windows 无法加载这个硬件的设备驱动程序。驱动程序可能已损坏或不见了。 (代码 39)
    哔站中有视频解决方案,可以直观看如何操作:Windows无法加载这个硬件的设备驱动程序。驱动程序可能已损坏或不见了。(代码39)第一步:明确感叹号故障硬件——右键“属性”—......
  • 模型驱动设计的构造块(上)——DDD
    为了保证软件实践得简洁并且与模型保持一致,不管实际情况如何复杂,必须运用建模和设计的实践。某些设计决策能够使模型和程序紧密结合在一起,互相促进对方的效用。这......