漯河市住房建设局网站/河南做网站的

漯河市住房建设局网站,河南做网站的,seo在中国,平台公司会倒闭吗DAC在我们的项目中经常使用到,而使用最多的就是AD56xx系列,包括有单通道的AD5662、双通道的AD5623和AD5663、以及四通道的AD5624和AD5664等。出于方便复用的原因,我们设计并实现AD56xx系列DAC的驱动。 1、功能概述 AD56xx系列DAC属于nanoDA…

DAC在我们的项目中经常使用到,而使用最多的就是AD56xx系列,包括有单通道的AD5662、双通道的AD5623AD5663、以及四通道的AD5624AD5664等。出于方便复用的原因,我们设计并实现AD56xx系列DAC的驱动。

1、功能概述

AD56xx系列DAC属于nanoDAC系列,是低功耗,12位、14位或者16位缓冲电压输出数模转换器(DAC),采用2.7V5.5V单电源供电。AD56xx采用多功能三线式串行接口,能够以最高50 MHz的时钟速率工作,并与标准SPIQSPIMICROWIREDSP接口标准兼容。它内置片内精密输出放大器,能够实现轨到轨输出摆幅。其功能框图如下所示:

AD56xx系列DAC都有一个24位的移位寄存器,所有的操作都是通过写移位寄存器来实现的。对于不同的型号其移位寄存器的各位略有差异。具体如下图所示:

单通道没有通道选择位,命令位只有2位,所以我们的软件实际上就是针对不同的功能需求配置移位寄存器。

2、驱动设计与实现

前面已经说过,对AD56xx的操作,实际就是根据需要配置移位寄存器。接下来我们将在此基础上分析并实现AD56xx系列DAC的驱动。

2.1、对象定义

在使用对象之前,我们需要抽象对象的定义。对于AD56xx系列DAC我们需要定义类型枚举,因为该系列包含有多种DAC模块。此外我们还要定义AD56xx系列DAC的对象类型。

/*定义DAC器件的类型*/
typedef enum AD56xx{AD5662=0,AD5623=1,AD5643=2,AD5663=3,AD5624=4,AD5644=5,AD5664=6,TypeNumber,
}AD56xxType;/* 定义AD56XX对象类型 */
typedef struct AD56xxObject {AD56xxType objectType;        //DAC的类型void (*WriteDataToDAC)(uint8_t *tData,uint16_t tSize);        //向DAC发送数据void (*ChipSelcet)(AD56xxCSType cs);     //片选信号
}AD56xxObjectType;

我们抽象了对象,在我们使用这个对象定义声明了一个具体的对象时,它只是一个代表对象的变量,我们需要对它进行初始化才可使用。于是我们定义初始化对象函数。

/* 初始化AD56xx对象 */
void AD56xxInitialization(AD56xxObjectType *dacObj,AD56xxType objectType,AD56xxWrite write,AD56xxChipSelcet cs)
{if((dacObj==NULL)||(write==NULL)||(cs==NULL)){return;}if(objectType<TypeNumber){dacObj->objectType=objectType;}dacObj->WriteDataToDAC=write;dacObj->ChipSelcet=cs;
}

2.2、对象操作

我们已经将AD56xx抽象为对象,那么对AD56xx的操作都转化为对某一个对象的操作。接下来我们来实现对象的操作函数。

2.2.1、软件复位

软件复位也是通过操作输入移位寄存器来实现的。命令位的定义没有变化,数据段的最后一位作为软件复位的模式设定,其它位无效。最后一位为0时,会清除DAC寄存器和输入寄存器,而最后一位为1时清除掉全部寄存器。最后一位为1时,实际就是上电复位模式。输入移位寄存器的数据格式如下:

其软件实现如下:

/* 对AD56xx进行软件复位 */
void Ad56xxSoftwareReset(AD56xxObjectType *dacObj,AD56xxResetType resetMode)
{uint32_t inputShiftData=0;if(resetMode==ResetSoftware){inputShiftData=RESET|Register_Reset_Software;}if(resetMode==ResetPoweron){inputShiftData=RESET|Register_Reset_Poweron;}uint8_t txData[3];txData[0]=inputShiftData>>16;txData[1]=inputShiftData>>8;txData[2]=inputShiftData;dacObj->ChipSelcet(AD56xxCS_Enable);dacObj->WriteDataToDAC(txData,3);dacObj->ChipSelcet(AD56xxCS_Disable);
}

2.2.2、上电复位

上电复位也是通过操作输入移位寄存器来实现的。命令位的定义没有变化,数据段的DB5DB4定义掉电的模式,而DB1DB0定义操作的通道。输入移位寄存器的数据格式如下:

其软件实现如下:

/* 设置AD56xx上电/掉电工作模式 */
void Ad56xxPowerUpDownMode(AD56xxObjectType *dacObj,AD56xxChannelType channel,AD56xxPowerdownType powerdownType)
{uint32_t inputShiftData=0;uint32_t pdc=0;uint32_t pdm=0;uint32_t cmd=Power_Down;uint32_t pdChannel[]={DAC_A,DAC_B,DAC_C,DAC_D,DAC_ALL,DAC_None};pdc=pdChannel[channel];uint32_t pdMode[]={Normal_Operation,_1K_GND,_100K_GND,Three_State};pdm=pdMode[powerdownType];if(dacObj->objectType==AD5662){pdc=DAC_None;pdm=(pdm<<12);cmd=Write_to_Input_Register;}inputShiftData=cmd|pdc|pdm;uint8_t txData[3];txData[0]=inputShiftData>>16;txData[1]=inputShiftData>>8;txData[2]=inputShiftData;dacObj->ChipSelcet(AD56xxCS_Enable);dacObj->WriteDataToDAC(txData,3);dacObj->ChipSelcet(AD56xxCS_Disable);
}

2.2.3LDAC功能

除去单通道的设备外,其他的AD56xx设备都具有LDAC操作功能。而对LDAC操作的寄存器设置如下图所示:

其软件实现如下:

/* 设置AD56xx及同类器件LDAC功能 */
void SetAd56xxLdacFunction(AD56xxObjectType *dacObj,AD56xxChannelType channel)
{uint32_t inputShiftData=0;uint32_t pdChannel[]={DAC_A,DAC_B,DAC_C,DAC_D,DAC_ALL,DAC_None};inputShiftData=pdChannel[channel];inputShiftData=inputShiftData|LDAC_Register_Setup;uint8_t txData[3];txData[0]=(uint8_t)(inputShiftData>>16);txData[1]=(uint8_t)(inputShiftData>>8);txData[2]=(uint8_t)inputShiftData;dacObj->ChipSelcet(AD56xxCS_Enable);dacObj->WriteDataToDAC(txData,3);dacObj->ChipSelcet(AD56xxCS_Disable);
}

2.2.4、内部基准电压源设置

有一些型号以R结尾的AD56xx器件是包含有内部参考电源的。片内基准电压源在上电时默认关闭。通过设置控制寄存器中的软件可编程位DB0,可以开启或关闭此基准电压源。 具体的寄存器设置如下图所示:

其软件实现如下:

/* 开启或关闭内部参考电压源 */
void SetInternalReference(AD56xxObjectType *dacObj,AD56xxRefType ref)
{uint32_t inputShiftData=0;inputShiftData=Reference_Set;if(ref==AD56xxRef_ON){inputShiftData=inputShiftData|Reference_ON;}uint8_t txData[3];txData[0]=(uint8_t)(inputShiftData>>16);txData[1]=(uint8_t)(inputShiftData>>8);txData[2]=(uint8_t)inputShiftData;dacObj->ChipSelcet(AD56xxCS_Enable);dacObj->WriteDataToDAC(txData,3);dacObj->ChipSelcet(AD56xxCS_Disable);
}

2.2.5、输出操作

对各输出通道值的操作也是通过输入移位寄存器来完成。其数据格式如前面输入移位寄存器的介绍。后16位是数据(0-65535),然后是3位地址和3位命令。通讯的时序图如下所示:

其软件实现如下:

/* 设置DA通道的值 */
void SetAD56xxChannelValue(AD56xxObjectType *dacObj,AD56xxChannelType channel,uint16_t data)
{uint32_t inputShiftData=0;uint32_t dac=0;uint32_t cmd=WriteTo_Update_DAC_Channel;uint32_t dacChannel[]={DAC_Channel_A,DAC_Channel_B,DAC_Channel_C,DAC_Channel_D,DAC_Channel_ALL};uint32_t shiftV[]={0,4,2,0,4,0};if(channel>=ChannelNone){return;}dac=dacChannel[channel];if(dacObj->objectType==AD5662){dac=DAC_Channel_A;cmd=Write_to_Input_Register;}inputShiftData=dac|cmd|(data<<shiftV[dacObj->objectType]);uint8_t txData[3];txData[0]=(uint8_t)(inputShiftData>>16);txData[1]=(uint8_t)(inputShiftData>>8);txData[2]=(uint8_t)inputShiftData;dacObj->ChipSelcet(AD56xxCS_Enable);dacObj->WriteDataToDAC(txData,3);dacObj->ChipSelcet(AD56xxCS_Disable);
}

3、驱动的使用

我们已经实现了AD56xx系列DAC的驱动,接下来我们就可以使用我们的这个驱动实现我们的应用了。

3.1、声明并初始化对象

首先需要使用AD56xx对象类型AD56xxObjectType声明一个对象变量。具体声明形式如下:AD56xxObjectType ad56xx;

对象变量需要使用AD56xxInitialization函数进行初始化。这个函数的参数除了对象变量外还有对象类型以及写数据操作和片选操作2个函数指针。在调用初始化函数之前必须准备好这些参数。所以我们需要按如下类型定义相关函数。

/* 向DAC发送数据函数指针类型 */
typedef void (*AD56xxWrite)(uint8_t *tData,uint16_t tSize);/* 片选操作函数指针类型 */
typedef void (*AD56xxChipSelcet)(AD56xxCSType cs);

我们实现这几个函数并将函数指针作为参数传递给初始化函数。初始化函数的调用样式如下:

AD56xxInitialization(&ad56xxobjectTypewritecs);

后两个参数即是上面定义的2个函数的函数指针。这两个函数根据具体的硬件电路来实现。第二个参数为对象类型,为AD56xxType枚举类型。

3.2、基于对象进行操作

初始化完成后就可以操作对象了。对AD56xx系列DAC对象的操作包括:软件复位操作,上下电模式控制,LDAC控制,参考电压操作以及输出控制。下面将调用驱动函数实现相应的应用。

AD56xx系列DAC拥有14个通道,所以我们需要为操作制定通道。还有向该通道设定的数据,由于AD56xx系列DAC1216位,所以我们要发送一个不超过16位的无符号整数。有了这两个参数我们就可以调用SetAD56xxChannelValue函数为AD56xx系列DAC设定输出了。

SetAD56xxChannelValue(&ad56xxchanneldata);

第二个参数为设定的通道,是一个AD56xxChannelType类型的枚举,以此决定我们当前操作的是哪一个通道。而其它的函数:

/*设置AD56xx上电/掉电工作模式*/
void Ad56xxPowerUpDownMode(AD56xxObjectType *dacObj,AD56xxChannelType channel,AD56xxPowerdownType powerdownType);/*对AD56xx进行软件复位*/
void Ad56xxSoftwareReset(AD56xxObjectType *dacObj,AD56xxResetType resetMode);/* 开启或关闭内部参考电压源 */
void SetInternalReference(AD56xxObjectType *dacObj,AD56xxRefType ref);/*设置AD56xx及同类器件LDAC功能*/
void SetAd56xxLdacFunction(AD56xxObjectType *dacObj,AD56xxChannelType channel);

其调用方式是类似的。需要指出的是SetInternalReference函数,只有具有内部参考电源的器件调用这个函数才有作用。

4、应用总结

我们使用AD56xx系列DAC实现过多种应用,都是基于我们的驱动开发的。使用的结果基本都与我们的预期一样。

需要注意对象的类型,特别是AD5662的移位寄存器有很大区别。虽然驱动在这一方面作了处理,但是基于初始化时配置的类型执行的。所以在调用初始化函数初始化对象时一定要传递正确的类型。

​源码公布到GitHUB:https://github.com/foxclever/ExPeriphDriver

欢迎关注:

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

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

相关文章

外设驱动库开发笔记2:AD8400系列数字电位器驱动

一些时候我们需要在系统使用过程中改变某些电路电阻值以达到改变设定的目的&#xff0c;这时候我们就会使用电位器。在我们使用数字控制电路时多选择数字电位器。在这一篇我们就来设计AD8400系列数字电位器的驱动。 1、功能概述 AD8400/AD8402/AD8403分别是单通道/双通道/四通…

外设驱动库开发笔记3:AD527x系列数字电位器驱动

在一些时候我们需要使用精度更高的数字电位器来实现我们的应用。我们经常使用AD527x系列数字电位器来实现这类应用。在通常情况下&#xff0c;AD527x系列数字电位器完全能够满足要求。为了减少重复工作&#xff0c;在这里我们将分系并实现AD527x系列数字电位器的驱动。 1、功能…

PID控制器改进笔记之一:改进PID控制器之参数动态调整

前面我们发布了一系列PID控制器相关的文章&#xff0c;包括经典PID控制器以及参数自适应的PID控制器。这一系列PID控制器虽说实现了主要功能&#xff0c;也在实际使用中取得了良好效果&#xff0c;但还有很多的细节部分可以改进以提高性能和灵活性。所以在这篇中我们来讨论改进…

外设驱动库开发笔记4:AD9833函数发生器驱动

很多时候我们需要输出某种函数信号&#xff0c;如方波、三角波、正弦波等&#xff0c;但想要获得这样的函数信号&#xff0c;不论是硬件电路还是软件实现&#xff0c;却并不是一件简单的事情。不过AD9833这类函数生成芯片可以简化这方面的操作&#xff0c;这一节我们就来设计并…

PID控制器改进笔记之二:改进PID控制器之手自动切换

前面我们发布了一系列PID控制器相关的文章&#xff0c;包括经典PID控制器以及参数自适应的PID控制器。这一系列PID控制器虽说实现了主要功能&#xff0c;也在实际使用中取得了良好效果&#xff0c;但还有很多的细节部分可以改进以提高性能和灵活性。所以在这篇中我们来讨论改进…

外设驱动库开发笔记5:AD7705系列ADC驱动

我们的经常需要采集一些精度要求较高的模拟信号&#xff0c;使用MCU集成的ADC难以达到要求、所以我们需要独立的ADC芯片。这一节我们就来设计并实现AD7705芯片的驱动、并探讨驱动的使用方法。 1、功能概述 AD7705/AD7706是用于低频测量的完整模拟前端。可以直接从传感器接收低…

PID控制器改进笔记之三:改进PID控制器之正反作用

前面我们发布了一系列PID控制器相关的文章&#xff0c;包括经典PID控制器以及参数自适应的PID控制器。这一系列PID控制器虽说实现了主要功能&#xff0c;也在实际使用中取得了良好效果&#xff0c;但还有很多的细节部分可以改进以提高性能和灵活性。所以在这篇中我们来讨论改进…

PID控制器改进笔记之四:改进PID控制器之设定值响应

前面我们发布了一系列PID控制器相关的文章&#xff0c;包括经典PID控制器以及参数自适应的PID控制器。这一系列PID控制器虽说实现了主要功能&#xff0c;也在实际使用中取得了良好效果&#xff0c;但还有很多的细节部分可以改进以提高性能和灵活性。所以在这篇中我们来讨论改进…

PID控制器改进笔记之五:改进PID控制器之串级设定

前面我们发布了一系列PID控制器相关的文章&#xff0c;包括经典PID控制器以及参数自适应的PID控制器。这一系列PID控制器虽说实现了主要功能&#xff0c;也在实际使用中取得了良好效果&#xff0c;但还有很多的细节部分可以改进以提高性能和灵活性。所以在这篇中我们来讨论改进…

滤波器开发之一:基于算数平均的平滑滤波器

信号采集是非常常见的需求&#xff0c;我们也总是希望采集到的数据是纯净而真实的&#xff0c;但这只是我们的希望。环境中存在太多的干扰信号&#xff0c;为了让我们得到的数据尽可能地接近实际值&#xff0c;我们需要降低这些干扰信号的影响&#xff0c;于是就有了滤波器的用…

外设驱动库开发笔记6:AD719x系列ADC驱动

前面我们讨论了AD7705这种ADC器件的驱动开发&#xff0c;在实际中我们使用更多的是AD719x系列的ADC芯片、包括有AD7191、AD7192和AD7193等。接下来我们就来设计并开发AD719x的驱动程序。 1、功能概述 AD7192是一款适合高精密测量应用的低噪声完整模拟前端&#xff0c;内置一个…

滤波器开发之二:基于算数平均的带阻平滑滤波器

信号采集是非常常见的需求&#xff0c;我们也总是希望采集到的数据是纯净而真实的&#xff0c;但这只是我们的希望。环境中存在太多的干扰信号&#xff0c;为了让我们得到的数据尽可能地接近实际值&#xff0c;我们需要降低这些干扰信号的影响&#xff0c;于是就有了滤波器的用…

滤波器开发之三:基于算数平均的阶进平滑滤波器

信号采集是非常常见的需求&#xff0c;我们也总是希望采集到的数据是纯净而真实的&#xff0c;但这只是我们的希望。环境中存在太多的干扰信号&#xff0c;为了让我们得到的数据尽可能地接近实际值&#xff0c;我们需要降低这些干扰信号的影响&#xff0c;于是就有了滤波器的用…

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

有些时候我们需要对高精度的ADC来处理一些要求较高的模拟量采集。在处理温控器的过程中我们就使用到了LTC2400这款ADC。接下来我们就来设计并实现LTC2400的驱动。 1、功能概述 LTC2400是一个供电电压2.7V到5.5V的微功率24位转换器&#xff0c;集成了振荡器、4ppm INL和0.3ppm…

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

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

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

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

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

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

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

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

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

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

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

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