基于I.MX6UL平台的ADS1256驱动开发一.准备
由于工程需求,需要在I.MX6UL平台扩展一块具备高精度AD功能的采集卡,由于网上给的例程是基于STM32的,移植到I.MX6UL上还用了一小段功夫,这里记录一下开发流程。
前期准备
这里选用了基于德州仪器的ADS1256芯片的AD采集卡。产品图如下
IC外围电路及接口产品厂商给了原理图
(上面的U1应该是个2925,为IC提供2.5V的基准电压)
ADS1256芯片的datasheet我放在网盘里(点击下载,提取码:viyq)。
这一章节我们着重根据手册来分析一下ADS1256是如何使用的。
工作模式
从简开始,先不考虑ADS1256的可编程增益(PGA)、复用选择器什么的,以用最简单的方式拿到输入电压值为目的,我们用最简单的方法实现。
例程上采用的是相应中断的方式来扫描电压值,通过中断监测DRDY脚(21)状态来响应中断函数,获取AD码值是在中断服务函数中实现的,为了简化开发流程,第一个步骤我们不用中断,直接用while循环等嗲DRDY信号。SPI接口使用软件模拟,将引脚复用为GPIO。通过软件来模拟SPI读写及时钟信号。后期如果有时间可以采用硬件SPI接口(todo:测试采用硬件接口好像硬件SPI时钟周期太短,不满足IC工作需求,后期有机会修改一下)。
IC工作需求分析
先根据手册看一下IC和我们的开发板之间的接口定义:除去工作电源,采集电路通过一片REF2925位IC提供了2.5V的基准电压(3、4脚),2925的说明这里就不放了),还有一个7.68MHz的晶振作为时钟(18、19脚)。
6脚~13脚是用作电压输入的,25~28脚是可编程的IO接口,这些我们先不用考虑。所以剩下的就是这几个了
还是一切从简,我们先不考虑软件复位功能以及同步功能,所以14、15两个功能引脚我们直接拉高接到5V上。最后采集卡和我们的I.MX6UL开发板通讯所需要的就是5组线:
PS:采集卡上电后可以看一下D0和DRDY两个引脚的信号:D0输出为输入时钟信号(就是接在clk in的那个7.68MHz的晶振)
而DRDY因为默认的采样率是30K,就会有个30K的信号一直出来
这个时候起码知道,IC工作是正常的。
工作时钟
下面我们要看一下读写操作的时钟要求
采集卡和开发板之间采用SPI接口进行数据交互,所以所有的操作都是通过这个SPI操作的。 结合手册中的时钟特征看一下要求,表格中有个很常用的单位是τ CLKIN,这个是18、19脚接入的晶振的周期,即1/7.68e6=0.130208333us。其中要关注的有下面几个时钟
t1:SPI的时钟:最小值是4个clkin周期,大约0.521us,但不能超过10个data的周期,这个data的周期可以视作采样周期。
t2H:SPI高电平维持事件,最小200ns,最大不能超过9个clkin(t2L值一样)
t10:最后一个bit传输后片选信号CS拉高要等待的事件,最小8个clkin
ADS1256支持软件的复位和同步等操作,这里我们先不考虑,可以暂时忽略他们的用法。
寄存器映射
ADS1256内部包含了10个寄存器,映射如下
寄存器地址是连续的(0x00~0x0A),可以使用连续写入或读取的方式对一段连续地址的寄存器进行操作。下面我们了解一下主要的几个寄存器
状态寄存器(STATUS)
状态寄存器STATUS是IC当前的状态
高4位是IC的ID,只读,可以通过读取ID值判定通讯是否正常。
BIT3是数据传输状态(MSB优先或LSB优先),MSB优先意味着传输的时候从高位开始发送,例如5V电压理论上对应的码值为0x7FFFFF,MSB优先时先从左边的7开始发送;LSB优先是从右边的F开始传输。
BIT2和BIT1是自动运算和缓存使能设置,我们先不考虑
BIT0是只读位,和DRDY引脚的状态一样。
复用选择(MUX)
这个寄存器决定了电压输入时的高低电平的接入引脚。
高4位决定了输入信号的正极对应引脚,低4位为负极对应引脚。
比如我们使用共模模式接入信号,寄存器值为0x08就是正极接AIN0,负极接AINCOM,0x18就是正极接AIN1,负极接AINCOM。在读取通道值得时候我们需要先对该寄存器进行设置,然后读取值。
模数配置(ADCON)
ADCON寄存器里用来配置模数转化时候的相关参数。
这个寄存器中我们比较关系的是低3位,PGA,用来设置增益,当测量信号过小的时候可以通过改变增益来设置对应的输入信号量程。
PGA值 | 输入信号量程(默认参考电压为2.5V) | ADCON(2:0) |
1 | ±5V | 000 |
2 | ±2.5V | 001 |
4 | ±1.25V | 010 |
8 | ±0.625V | 011 |
16 | ±312.5mV | 100 |
32 | ±156.25mV | 101 |
64 | ±78.125mV | 110或111 |
不考虑负电压的测量(其实值是一样的,只不过以补码的形式输出),AD输出的码值正向为0x7FFFFF,PGA翻一番的时候对应输入信号的满量程会降低一半。每个PGA下的1个LSB对应的电压是不同的,PGA值越大1个LSB电压值越小,对应的精度越高。
采样率设置(DRATE)
采样率A/D Data Rate是AD功能非常重要的参数,默认情况是30KS/s的采样率,通过DRDY的输出可以看到那个30K的输出。通过设施这个寄存器就可以改变采样率,寄存器8位有效,可以按照指定的设置值设定对应的采样率
注意到上面的几个配置里都是基于7.68MHz的时钟的,所以采集卡的外围电路都是按照这个时钟要求配置的晶振。
前4组寄存器是我们使用AD时候需要配置的,后面的6个,基本上就是IO设置、计算配置什么的,就和我们的常用工作暂时没有什么关系了,可以先不考虑。
命令集
采集卡作为SPI通讯从机和IMX的主机进行数据交互是通过指定的命令进行的,全部的命令一共15组
从上面的命里集合可以看出来,除了读写寄存器的命令其余的都只有1个字节。连续的读写除了固定的指令外后面还跟了起始寄存器的地址。下面结合我们使用的场景来介绍下几个常用的命令。
数据读取RDATA/SDATAC
读取数据的指令需要在DRDY信号被拉低以后进行,IC在进行完模数转换后,会将DRDY输出值拉低,这个时候可以通过RDATA命令读取输出值,但是要注意时序要求
在发送命令完成后,数据读取要等待t6时长才能进行。这个事件SPI时钟应该保持低电平。t6可以从前面的表中查到,最小值为50个CLKIN,大约6.5us。默认情况,即STATUS的ORDER位是0,OUT的输出是以高位先输出的。
连续读取数据RDATAC/SDATAC
连续读取数据分为连续读取开始信号指令(RDATAC)和停止读取指令。
IC在接收连续读取数据的命令以后,会连续的将码值通过DOUT输出给主机,直到接收到SDATAC信号停止发送。在此期间数据会不间断的通过DOUT引脚输出
在连续读取数据模式中,IC会对DIN引脚进行监听,当input_data为0x0F时,退出连续读取模式。要注意的一点是在连续读取模式下,如果我们没有完全读取24个数据bit时,DRDY信号是不会置1的,但是如果有新的数据进行玩AD处理后DRDY信号会返回高电平后重新置0。
由于在该模式下IC回对DIN引脚始终保持监听状态,是绝对不能将DIN和DOUT两个引脚连在一起!
读寄存器RREG
寄存器读取命令RREG(Read from Registers)分3个部分,格式是这样的
0001 rrrr 0000 nnnn
第一部分为第一个字节的高8位,固定为0001
第二部分rrrr为第一字节低八位被读取的寄存器地址
第三部分nnnn为第二个字节的第八位,是读取寄存器的个数-1。但是要注意的是读取1个寄存器时n的值为0。
例如我们想要读取MUX寄存器(0x01)和ADCON(0x02)两个寄存器的值,需要发送的命令为0x11 0x01,可以参考下面的时序图
和前面读取数据的要求一样,在命令和后面读取数据的间隔要满足最小t6个CLKIN。
写寄存器WREG
写寄存器WREG命令(Write to Register)和读的用法基本一致,但是要在第二个比特后加上要写入的数据,时序图是这样的
其中第一个字节的高八位0101是固定的写命令,第八位0011是DRATE寄存器的地址,表示从这个寄存器开始写入数据
第二个字节高八位是0,无实际咦咦咦,第八位0001表示要连续写2个寄存器。
第三个字节是写入DRATE寄存器的值
第四个字节是写入IO寄存器的值。
也就是说写入寄存器的时候最少要有3个字节,前两个是命令内容,包括写入地址和寄存器数量,后面的全部是数据内容。
我们后面在做驱动移植构建的时候,基本上就是基于这一章的原理进行的,并且后面我们不再通过裸机开发采集卡,直接在针对开发板构建Linux下的驱动。