外设驱动库开发笔记7:LTC2400系列ADC驱动

有些时候我们需要对高精度的ADC来处理一些要求较高的模拟量采集。在处理温控器的过程中我们就使用到了LTC2400这款ADC。接下来我们就来设计并实现LTC2400的驱动。

1、功能概述

LTC2400是一个供电电压2.7V5.5V的微功率24位转换器,集成了振荡器、4ppm INL0.3ppm RMS噪声。所需外接基准电压源的电压范围为0.1VVCC;模拟信号输入VIN的输入电压范围为-0.125VREF1.125VREF

1.1、硬件结构

LTC2400模数转换器采用与SPI接口兼容的3线数字接口,可应用于高分辨率和低频应用场合,如称重、温度测量、气体分析、应变仪,数据采集,工业控制等方面。它采用8SO-8封装,其引脚排列如图所示。

LTC2400内部已集成了高精度的振荡器,因此采用片内振荡器时不需要外接任何元件。通过一个引脚,LTC2400可以配置为在50Hz60Hz±2%时优于110dB的抑制,也可以由外部振荡器驱动,用户定义的抑制频率在1Hz120Hz之间。当芯片的F0脚接VCC时,使用内部振荡器可对输入信号中的50Hz干扰进行大于110dB的抑制,其AD转换时间为160ms;F0脚接GND时,使用内部振荡器可对输入信号中的60Hz干扰进行大于110dB的抑制,AD转换时间为133ms;F0脚接外部振荡器fEOSC时,其抑制的频率为fEOSC/2560AD转换时间为2048/fEOSC

LTC2400转换器接受任何外部参考电压从0.1VVCCLTC2400以其扩展的输入转换范围-12.5% VREF112.5% VREF,平稳地解决了先前传感器或信号调理电路的偏移和超量程问题。

1.2、通讯接口

通过对CSSCK的控制,LTC2400可以提供几种灵活的接口模式(内部或外部的SCK模式)。不同转换模式的选择无需对LTC2400的寄存器进行设置,并且不影响数据转换周期。使用时钟信号SCK(PIN7)控制转换数据的输出时,转换结果将在时钟CLK的下降沿由SDO脚输出。在内部时钟模式,SCK信号由LTC2400产生输出在外部SCK模式,SCKLTC2400外部输入的时钟信号。下面详细介绍外部串行时钟的三线接口方法。

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,表示转换正在进行;EOC0表示转换完成,系统处于睡眠状态。当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 {LTC2400ClockType clock;                     //使用的时钟uint32_t dataCode;                          //数据编码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_t rData[4];ltc->ChipSelect(LTC2400CS_Enable);ltc->Delayms(1);ltc->Receive(rData);ltc->Delayms(1);ltc->ChipSelect(LTC2400CS_Disable);return CompoundLTC2400Data(ltc,rData);
}

函数的返回值是转换结果的比例值,是一个浮点数,使用这一返回结果结合具体浮点数的量成范围就可以得到物理量值。

3、驱动的使用

我们已经开发了LTC2400模数转换器的驱动程序,接下来我们用一个简单的实例验证这一驱动。

3.1、声明并初始化对象

使用基于对象的操作我们需要先得到这个对象,所以我们先要使用前面定义的LTC2400模数转换器对象类型声明一个LTC2400模数转换器对象变量,具体操作格式如下:

Ltc2400ObjectType ltc2400;

声明了这个对象变量并不能立即使用,我们还需要使用驱动中定义的初始化函数对这个变量进行初始化。这个初始化函数所需要的输入参数如下:

Ltc2400ObjectType *ltc,所要初始化的对象

LTC2400ClockType clock,采用时钟方式

LTC2400Receive receive,接收数据函数指针

LTC2400ChipSelect cs,片选操作函数指针

LTC2400Delay msDelay,延时函数指针

对于这些参数,对象变量我们已经定义了。所使用的时钟方式为枚举,根据实际情况选择就好了。主要的是我们需要定义几个函数,并将函数指针作为参数。这几个函数的类型如下:

/*定义接收数据函数指针类型*/
typedef void (*LTC2400Receive)(uint8_t *rData);
/*定义片选信号函数指针类型*/
typedef void (*LTC2400ChipSelect)(LTC2400CSType cs);
/*定义延时操作函数指针类型*/
typedef void (*LTC2400Delay)(volatile uint32_t nTime);

对于这几个函数我们根据样式定义就可以了,具体的操作可能与使用的硬件平台有关系。片选操作函数用于多设备需要软件操作时,如采用硬件片选可以传入NULL即可。具体函数定义如下:

/*定义读写操作函数指针类型*/
void LTC2400Recieve(uint8_t *rData)
{HAL_SPI_Receive(&ltc2400hspi,rData,4,1000);
}/*实现片选*/
void LTC2400ChipSelected(LTC2400CSType cs)
{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(&ltc2400INTERNAL_CLOCK50HzLTC2400RecieveLTC2400ChipSelectedHAL_Delay);

这里我们将其初始化为使用改了内部时钟,采用软件控制片选信号。

3.2、基于对象进行操作

我们定义了对象变量并使用初始化函数给其作了初始化。接着我们就来考虑操作这一对象获取我们想要的数据。我们在驱动中已经将获取数据并转换为转换值的比例值,接下来我们使用这一驱动开发我们的应用实例。

/* 获取LTC2400测量的物理量值 */
void GetLTC2400Value(void)
{float ratio;float phyValue;float range=100.0;float zero=0.0;ratio=GetLtc2400Data(&ltc2400);phyValue=(range-zero)*ratio+zero;
}

在这一例中,我们计算了一个量程范围为0100的物理量的值,如果检测的物理量不同,我们根据实际修改即可。

4、应用总结

这一篇中,我们设计并实现了LTC2400模数转换器的驱动程序,并使用这一驱动开发了获取一个量程范围为0100的温度信号的简单应用,得到的结果与我们预期一致,因此我们的驱动符合要求。

在使用驱动时需注意,采用SPI接口的器件需要考虑片选操作的问题。如果片选信号是通过硬件电路来实现的,我们在初始化时给其传递NULL值。如果是软件操作片选则传递我们编写的片选操作函数。

完整的源代码可在GitHub下载:https://github.com/foxclever/ExPeriphDriver

欢迎关注:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/499366.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

外设驱动库开发笔记8:GPIO模拟I2C驱动

I2C总线简单方便,是我们经常使用的一种总线。但有时候我们的MCU没有足够多的I2C控制器来实现我们的应用,所幸我可以使用普通的GPIO引脚来模拟低速的I2C总线通信。这一节我们就来实现使用软件通过普通GPIO操作I2C设备的驱动。 1、功能概述 I2C总线使用两…

嵌入式IAP开发笔记之一:面向STM32的BootLoader程序

对于很多人来说,BootLoader并不是一个陌生的词,甚至会经常用到它。因为在很多情况下我们都需要BootLoader程序,比如我们需要对系统在线升级时就需要它,还有当我们需要在外部存储器中运行程序时也需要用到它。在这里我们就来设计一…

外设驱动库开发笔记9:SHT1x系列温湿度传感器驱动

在我们的产品中,经常需要检测温湿度数据。有很多检测温湿度的方法和模块,其中SHT1x系列温湿度传感器就是一种成本较低使用方便的温湿度检测模块。下面我们就来说一说如何实现SHT1x系列温湿度传感器的驱动。 1、功能概述 SHT1x包括 SHT10, S…

Modbus协议栈应用实例之一:Modbus RTU主站应用

自从开源了我们自己开发的Modbus协议栈之后,有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例,在这一篇中我们先来使用协议栈实现Modbus RTU主站的示例。 1、何为RTU主站 Modbus协议是…

uCOS-III应用开发笔记之一:uCOS-III在STM32的移植

uCOS-III实时操作系统在MCU平台被广泛使用,在这里我们将简单的记录如何将uCOS-III实时操作系统移植到目标平台上并运行。 1、必要的准备 在开始uCOS-III实时操作系统的移植前,我们还需要做一些必要的准备,如确定目标板、准备目标工程及uCOS…

外设驱动库开发笔记10:SHT2x系列温湿度传感器驱动

温湿度检测是嵌入式编程中经常应用到的一项功能。在我们的产品中亦经常使用。SHT2x系列温湿度传感器作为一种高精度低成本的集成模块,一直应用于我们的产品中。在这里我们讨论如何封装SHT2x系列温湿度传感器的驱动。 1、功能概述 SHT20配有一个全新设计的CMOSens芯…

Modbus协议栈应用实例之二:Modbus RTU从站应用

自从开源了我们自己开发的Modbus协议栈之后,有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例,这一篇中我们将使用协议栈实现一个Modbus RTU从站应用。 1、何为RTU从站 Modbus协议是一…

外设驱动库开发笔记11:SHT3x系列温湿度传感器驱动

在我们的产品中经常会遇到温湿度检测的需求。可以用于检测温湿度的传感器元件也有很多。我们经常使用的SHT各系列数字温湿度传感器来实现应用需求。在这里我们将设计并实现SHT3x系列温湿度传感器的驱动。 1、功能概述 SHT3x系列温湿度传感器是适用于各种应用的高品质湿度传感…

LwIP应用开发笔记之十:LwIP带操作系统基本移植

现在,TCP/IP协议的应用无处不在。随着物联网的火爆,嵌入式领域使用TCP/IP协议进行通讯也越来越广泛。在我们的相关产品中,也都有应用,所以我们结合应用实际对相关应用作相应的总结。 1、技术准备 我们采用的开发平台是STM32F407…

ThreadX应用开发笔记之一:移植ThreadX到STM32平台

现在一些小型系统中也往往有多任务处理的需求,这就为实时操作系统提供了用武之地。事实上国内外各种各样的RTOS有很多,而且基本都在走开源的路线,ThreadX也不例外,在这一篇中我们就来学习ThreadX初步应用并将其移植到STM32平台中。…

外设驱动库开发笔记12:TSEV01CL55红外温度传感器驱动

有时候我们需要检测一些无法直接接触的器件的温度。为了实现这一需求,我们通常会选择红外温度传感器来实现这一功能。考虑到复用的问题,我们一般会将操作元器件的代码抽象为驱动函数以备调用。这里我们就来设计并实现TSEV01CL55红外温度传感器的驱动。 …

FreeRTOS应用开发笔记之一:FreeRTOS在STM32的移植

FreeRTOS是如今在小型嵌入式领域应用比较广泛的一种实时操作系统。它是一种开源且免费的操作系统,而且移植和使用都非常的简单。在这里我们将学习并移植FreeRTOS。 1、必要的准备 工欲善其事,必先利其器,在开始学习和移植之前,相…

外设驱动库开发笔记13:MLX90614红外温度传感器驱动

红外温度传感器一般用于非接触式的温度检测。在我们的系统中经常会有这样的需求。所以我们将其设计为通用的驱动库以备复用。这一篇我们将讲述MLX90614红外温度传感器驱动的设计与实现。 1、功能概述 MLX90614是一种红外温度计,用于非接触式温度测量。红外测温是根…

Modbus协议栈应用实例之三:Modbus TCP客户端应用

自从开源了我们自己开发的Modbus协议栈之后,有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例,这一篇中我们将解说如何使用协议栈实现一个Modbus TCP客户端。 1、何为TCP客户端 Modbus…

Modbus协议栈应用实例之四:ModbusTCP服务器应用

自从开源了我们自己开发的Modbus协议栈之后,有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例,这一篇中我们来简述如何使用协议栈实现一个Modbus TCP服务器应用。 1、何为TCP服务器 Mo…

外设驱动库开发笔记14:DS18B20温度变送器驱动

在一时候我们需要相对简单的检测温度信号,而DS18B20就是一款功能和应用都相对简单的温度传感器,通过单线就可以实现检测温度信号的需求。这一篇我们就来实现操作DS18B20获取温度数据的驱动。 1、功能概述 DS18B20是常用的数字温度传感器,其…

Modbus协议栈应用实例之五:Modbus ASCII主站应用

自从开源了我们自己开发的Modbus协议栈之后,有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例,这一篇中我们来使用协议栈实现Modbus ASCII主站应用。 1、何为ASCII主站 我们知道Modbus…

Modbus协议栈应用实例之六:Modbus ASCII从站应用

自从开源了我们自己开发的Modbus协议栈之后,有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例,这一篇中我们来使用协议栈实现Modbus ASCII从站应用。 1、何为ASCII从站 我们知道Modbus…

外设驱动库开发笔记15:DHT11温湿度传感器驱动

与DS18B20一样DHT11也是采用单总线,但所不同的是DHT11可同时实现温度和湿度的检测。在我们的产品中经常使用它来检测环境的温湿度信息。这一篇我们将设计并封装DHT11的驱动程序,以方便重复使用。 1、功能概述 DHT11数字温湿度传感器是一款含有已校准数…

外设驱动库开发笔记16:MS5536C压力变送器驱动

压力检测也是经常会遇到的需求,比如环境压力或者低压气体等都会用到压力检测。这类检测压力都比较低,一般不会超过大气压,有时甚至是负压。这一篇我们要讨论的MS5536C就属于这类器件。接下来我们将设计并实现MS5536C的驱动。 1、功能概述 M…