LTC2400模数转换器的驱动设计与实现

有些时候我们需要对高精度的adc来处理一些要求较高的模拟量采集。在处理温控器的过程中我们就使用到了ltc2400这款adc。接下来我们就来设计并实现ltc2400的驱动。
1 、功能概述
ltc2400是一个供电电压2.7v到5.5v的微功率24位转换器,集成了振荡器、4ppm inl和0.3ppm rms噪声。所需外接基准电压源的电压范围为0.1v~vcc;模拟信号输入vin的输入电压范围为-0.125vref~1.125vref。
1.1 、硬件结构
ltc2400模数转换器采用与spi接口兼容的3线数字接口,可应用于高分辨率和低频应用场合,如称重、温度测量、气体分析、应变仪,数据采集,工业控制等方面。它采用8脚so-8封装,其引脚排列如图所示。
ltc2400内部已集成了高精度的振荡器,因此采用片内振荡器时不需要外接任何元件。通过一个引脚,ltc2400可以配置为在50hz或60hz±2%时优于110db的抑制,也可以由外部振荡器驱动,用户定义的抑制频率在1hz到120hz之间。当芯片的f0脚接vcc时,使用内部振荡器可对输入信号中的50hz干扰进行大于110db的抑制,其ad转换时间为160ms;f0脚接gnd时,使用内部振荡器可对输入信号中的60hz干扰进行大于110db的抑制,ad转换时间为133ms;当f0脚接外部振荡器feosc时,其抑制的频率为f eosc /2560,ad转换时间为2048/f eosc 。
ltc2400转换器接受任何外部参考电压从0.1v到vcc。ltc2400以其扩展的输入转换范围-12.5% vref到112.5% vref,平稳地解决了先前传感器或信号调理电路的偏移和超量程问题。
1.2 、通讯接口
通过对cs和sck的控制,ltc2400可以提供几种灵活的接口模式(内部或外部的sck模式)。不同转换模式的选择无需对ltc2400的寄存器进行设置,并且不影响数据转换周期。使用时钟信号sck(pin7)控制转换数据的输出时,转换结果将在时钟clk的下降沿由sdo脚输出。在内部时钟模式,sck信号由ltc2400产生输出在外部sck模式,sck为ltc2400外部输入的时钟信号。下面详细介绍外部串行时钟的三线接口方法。
当ltc2400上电时,如果sck为低电平,转换进入外部串行模式;在cs信号的下降沿,sck信号必须为低电平。
当cs为高电平时,sdo为高阻态,此时,sdo连接的接口线可以作为其它应用。如果ltc2400在转换和睡眠时cs为低电平,那么,sdo的输出状态将用于指示eoc。在ad转换阶段,sdo的输出状态eoc将变为高电平,而一旦转换完成,eoc又变为低电平。在ltc2400处于睡眠状态时,如果cs为低电平,系统会在sck的上升沿将其唤醒。ltc2400的外部串行时钟接口时序图如下:
cs信号除用来检测ltc2400的状态和输出ad转换数据外,还可用来控制全部串行数据输出之前进行的新一次ad转换。在ltc2400处于数据输出状态时,cs由低变高以停止串行输出,同时开始新的ad转换。
由于在cs为高电平时,数据输出端sdo为高阻态,因此,在ltc2400的转换过程中,可通过将cs变为低电平来检测转换状态。当cs为低电平时,sdo脚输出的eoc信号为1,表示转换正在进行;eoc为0表示转换完成,系统处于睡眠状态。当ltc2400处于睡眠状态时,其转换结果将保存在内部移位寄存器中。cs为低可在sck的上升沿唤醒ltc2400,此时转换数据将在sck的下降沿串行输出。eoc通常在sck的第一个上升沿被锁存,直到第32个上升沿锁存结束,同时,系统将在第32个下降沿开始的新一轮转换。
一般情况下,在数据输出过程中,如果cs为低电平,那么,系统将在sck的第一个上升沿和第32个下降沿中间将cs变高以停止数据输出。
1.3 、工作过程
ltc2400是一种低功耗、采用δ-σ技术且具有3线串行接口的ad转换器,而且在ad转换完成后将直接进入睡眠状态。ltc2400的三线接口线分别是数据输出(sdo)、时钟(sck)和片选(cs)。其工作流程如图所示:
ltc2400完成转换就进入睡眠状态。睡眠状态的供电电流仅为20μa。若cs一直为高电平,芯片将保持睡眠状态。进入睡眠状态时,数据最后的转换结果将保存在芯片内部的静态移位寄存器中。
当cs变为低电平时,ltc2400开始输出转换结果,此时数据转换没有等待时间,输出数据即为刚进行的转换结果。该转换结果是在串行时钟sck的控制下由sdo输出的,并在sck的下降沿更新,而在sck的上升沿可靠读取。当32位数据从ltc2400读出或当cs被拉高时,数据输出结束。此后ltc2400将自动开始新的数据转换和重复周期。
2 、驱动设计与实现
我们已经了解了ltc2400模数转换器的基本情况,接下来我们将设计并实现ltc2400模数转换器的驱动程序。
2.1 、对象定义
首先我们需要抽象出ltc2400模数转换器的对象类型。作为一个对象最起码包括量方面的内容:属性和操作。关于ltc2400模数转换器的属性我们简单分析一下。ltc2400模数转换器是一个主动发送数据的器件,并没有需要配置的地方,仅有一个时钟通过外部引脚设置,所以为了应用更清楚我们将其时钟引脚的配置作为其属性记录下来。另一个其返回的数据带有状态标识,我们将其作为另一个属性以记录当前的状态。
至于操作也很简单,首先我们要从ltc2400接收数据,而这个与具体的平台联系紧密,所以我们将从ltc2400接收数据作为对象的一个操作。ltc2400模数转换器采用spi通讯接口,有时需要在软件中对片选信号进行操作,所以我们将片选型号的操作作为对象的另一个操作。在一些情况下,有些针对对象的活动需要延时进行,而在不同的平台中采取的延时方式不尽相同,为了操作方便我们将延时操作作为对象的一个操作。于是我们可抽象的ltc2400的对象类型如下:
/* 定义ltc2400对象类型 */typedef struct ltc2400object { ltc2400clocktypeclock; //使用的时钟 uint32_tdatacode; //数据编码 void(*receive)(uint8_t *rdata); //接收数据 void(*chipselect)(ltc2400cstype cs); //实现片选 void(*delayms)(volatile uint32_t ntime); //实现ms延时操作}ltc2400objecttype;定义了ltc2400模数转换器的对象类型,我们还需要设计对象的初始化函数,因为对象必须初始化后才能使用。初始化函数至少包含有2方面内容:一是为对象变量赋必要的初值;二是检查这些初值是否是有效的。特别是一些操作指针错误的话可能产生严重的后果。基于这一原则,我们设计ltc2400模数转换器的对象初始化函数如下:
/* ltc2400对象初始化函数 */void ltc2400initialization(ltc2400objecttype*ltc, ltc2400clocktype clock, ltc2400receive receive, ltc2400chipselect cs, ltc2400delay msdelay){ if((ltc==null)||(receive==null)||(msdelay==null)) { return; } ltc->datacode=0; ltc->clock=clock; if(cs==null) //硬件电路实现片选 { ltc->chipselect=defaultchipselect; } else { ltc->chipselect=cs; } ltc->receive=receive; ltc->delayms=msdelay;}至此关于ltc2400模数转换器的对象定义才算完成。在使用初始化函数时,需要注意片选操作函数,如果是采用硬件电路选中则可使用null作为参数。
2.2 、对象操作
我们获取对象的目的就是希望通过对象来得到我们想要的数据。对于ltc2400模数转器来说,就是从其接收adc转换数据。所以我们封装ltc2400的操作函数如下:
/* 获取ltc2400转换数据,返回量程数据的比例值 */float getltc2400data(ltc2400objecttype*ltc){ uint8_trdata[4]; ltc->chipselect(ltc2400cs_enable); ltc->delayms(1); ltc->receive(rdata); ltc->delayms(1); ltc->chipselect(ltc2400cs_disable); returncompoundltc2400data(ltc,rdata);}函数的返回值是转换结果的比例值,是一个浮点数,使用这一返回结果结合具体浮点数的量成范围就可以得到物理量值。
3 、驱动的使用
我们已经开发了ltc2400模数转换器的驱动程序,接下来我们用一个简单的实例验证这一驱动。
3.1 、声明并初始化对象
使用基于对象的操作我们需要先得到这个对象,所以我们先要使用前面定义的ltc2400模数转换器对象类型声明一个ltc2400模数转换器对象变量,具体操作格式如下:
ltc2400objecttypeltc2400;
声明了这个对象变量并不能立即使用,我们还需要使用驱动中定义的初始化函数对这个变量进行初始化。这个初始化函数所需要的输入参数如下:ltc2400objecttype*ltc,所要初始化的对象
ltc2400clocktypeclock,采用时钟方式
ltc2400receivereceive,接收数据函数指针
ltc2400chipselectcs,片选操作函数指针
ltc2400delaymsdelay,延时函数指针
对于这些参数,对象变量我们已经定义了。所使用的时钟方式为枚举,根据实际情况选择就好了。主要的是我们需要定义几个函数,并将函数指针作为参数。这几个函数的类型如下:
/*定义接收数据函数指针类型*/typedef void(*ltc2400receive)(uint8_t *rdata);/*定义片选信号函数指针类型*/typedef void(*ltc2400chipselect)(ltc2400cstype cs);/*定义延时操作函数指针类型*/typedef void (*ltc2400delay)(volatileuint32_t ntime);对于这几个函数我们根据样式定义就可以了,具体的操作可能与使用的硬件平台有关系。片选操作函数用于多设备需要软件操作时,如采用硬件片选可以传入null即可。具体函数定义如下:
/*定义读写操作函数指针类型*/voidltc2400recieve(uint8_t *rdata){ hal_spi_receive(<c2400hspi,rdata,4,1000);} /*实现片选*/void ltc2400chipselected(ltc2400cstypecs){ if(ltc2400cs_enable==cs) { hal_gpio_writepin(gpiof, gpio_pin_4, gpio_pin_reset); } else { hal_gpio_writepin(gpiof, gpio_pin_4, gpio_pin_set); }}对于延时函数我们可以采用各种方法实现。我们采用的stm32平台和hal库则可以直接使用hal_delay()函数。于是我们可以调用初始化函数如下:
ltc2400initialization(<c2400,internal_clock50hz,ltc2400recieve,ltc2400chipselected,hal_delay);
这里我们将其初始化为使用改了内部时钟,采用软件控制片选信号。
3.2 、基于对象进行操作
我们定义了对象变量并使用初始化函数给其作了初始化。接着我们就来考虑操作这一对象获取我们想要的数据。我们在驱动中已经将获取数据并转换为转换值的比例值,接下来我们使用这一驱动开发我们的应用实例。
/* 获取ltc2400测量的物理量值 */void getltc2400value(void){ float ratio; float phyvalue; float range=100.0; float zero=0.0; ratio=getltc2400data(<c2400); phyvalue=(range-zero)*ratio+zero;}在这一例中,我们计算了一个量程范围为0到100的物理量的值,如果检测的物理量不同,我们根据实际修改即可。
4 、应用总结
这一篇中,我们设计并实现了ltc2400模数转换器的驱动程序,并使用这一驱动开发了获取一个量程范围为0到100的温度信号的简单应用,得到的结果与我们预期一致,因此我们的驱动符合要求。
在使用驱动时需注意,采用spi接口的器件需要考虑片选操作的问题。如果片选信号是通过硬件电路来实现的,我们在初始化时给其传递null值。如果是软件操作片选则传递我们编写的片选操作函数。
完整的源代码可在github下载:https://github.com/foxclever/experiphdriver

3D打印机工作原理详解,它的部件都有哪些作用
4G网络覆盖深圳公交 免费WIFI正试点
深度学习基本概率分布教程
工业APP是IIoT平台应用生态的价值体现
苹果手机如何寻找丢失设备?
LTC2400模数转换器的驱动设计与实现
怎么判断霍尔元件的类型呢?
哈佛大学研发新型生物相容性材料,可3D打印成任何形状
如何实现智能工厂应用?
陶瓷电容器涨价2-3成 手机也跟着涨?
集成电感转换器模块和线性稳压器,在什么场合优先选择前者呢
TI BMS在储能系统中的优势
雷军很勤奋,小米性价比也很高,可销量为何还是在华为ov之下?
有关机器视觉的四个真相,你知道几个
云从科技怎么样_云从科技首发3D结构光人脸识别技术
差分探头差分信号的常见测量方法有哪些
介绍一种新型的可充电锌-肼(Zn-Hz)电池
入侵报警器的设计与制作,Light control alarm
!!HP8563E HP8563E频谱分析仪HP8563E!
区块链赛马游戏CryptoDerby加密马介绍