外设驱动库开发笔记42:DAC8552 DAC驱动

  模拟信号输出是经常会遇到的应用需求,解决的办法应多种,但我们使用最多的还是数模转换。对于不同的数模转换器我们需要为其编写适用的驱动程序,在这一篇中我们就来考虑如何实现DAC8552高精度模数转换器的驱动程序。

1、功能概述

  该DAC8552是一个16位,双通道,电压输出数模转换器(DAC)提供低功率操作和灵活的串行主机接口。每个芯片上的精确输出放大器允许轨到轨输出摆动,以实现在2.7V到5.5V的供应范围。该设备支持标准三线串行接口,能够操作与输入数据时钟频率高达30MHz的VDD = 5V。

1.1、功能结构

  DAC8552这种设备在正常情况下的低功耗使得它非常适合便携式、电池驱动设备和其他低功耗应用。采用SOIC-8的封装形式,引脚定义如下:

  DAC8552需要一个外部参考电压来设置每个DAC通道的输出范围。DAC8552还包括一个电源上电复位电路,以确保DAC输出功率能够输出到零,并保持在那里,直到获取一个有效的写入值。DAC8552拥有一个SPI串行接口,该接口提供了灵活的功能。

  从上述结构图可知,DAC8552每次仅能操作一路输出,因为全部的操作都是通过同一个移位寄存器来实现的。

1.2、移位寄存器

  DAC8552有一个24位的输入移位寄存器,前面8位用来作控制位,后面16位用作数据位。具体如下图所示:

  在前面的8位控制位中,DB23和DB22是保留位必须为“0”,DB21(LDB)位和DB20(LDA)用于控制后面的16位数据适用于加载哪一个输出通道还是Power_Down命令。DB19没有定义,DAC8552不关心该位的具体数值。DB18为缓冲器选择位,用于控制数据的目标通道是DAC A还是DAC B。后续的DB17(PD1)和DB16(PD0)用于选择Power_Down的模式。具体的命令如下表中描述:

  至于Power_Down的模式有几种选择,如下表所示:

2、驱动设计与实现

  我们已经了解了DAC8552的基本结构及寄存器命令,接下来我们将根据这些认知设计DAC8552的驱动程序。

2.1、对象定义

  在设计DAC8552的驱动程序之前,我们先来考虑一下DAC8552的对象定义问题。我们作为一个对象一般会包括属性和操作两个方面的内容。我们先来分析DAC8552对象应该包含有哪些属性。属性用于标识对象的某些特性,DAC8552通过SPI总线下发数据和命令,我们没有发现什么需要特别标记的特性,所以我们不需要为DAC8552对象设计属性。
  我们再来看一看,DAC8552对象需要实现哪些操作。首先DAC8552使用SPI总线进行通讯,而SPI总线采用片选信号来区分不同的节点,所以我们需要操作DAC8552的片选信号,而片选型号的操作显然依赖于特定的操作平台,所以我们将控制其片选信号作为DAC8552对象的一个操作。另外,DAC8552作为模拟量输出对象,我们需要向其发送命令和数据,而向其发送数据和命令也依赖于具体的操作平台,所以应将其作为对象的一个操作来实现。据此我们可以定义DAC8552的对象类型如下:

/* 定义DAC8552对象类型 */
typedef struct DAC8552Object {void (*WriteDataToDAC)(uint8_t *tData,uint16_t tSize);        //向DAC发送数据void (*ChipSelcet)(DAC8552CSType cs);     //片选信号
}DAC8552xObjectType;

  我们定义了DAC8552的对象类型,但当我们使用其声明一个对象时,并不能直接使用,我们需要对对象进行初始化,这就需要我们设计一个对象初始化的函数。对象初始化函数处理对象相关的属性和操作的配置,具体实现如下:

/*初始化DAC8552对象*/
void DAC8552Initialization(DAC8552xObjectType *dac,     //DAC8552对象变量DAC8552WriteType write,      //写数据函数指针DAC8552ChipSelectType cs             //片选操作函数指针)
{if((dac==NULL)||(write==NULL)){return;}if(cs!=NULL){dac->ChipSelcet=cs;}else{dac->ChipSelcet=DefaultChipSelect;}
}

2.2、对象操作

  我们已经定义了DAC8552的对象类型并为DAC8552对象设计了初始化函数,接下来我们看一看DAC8552所要实现的操作。对于DAC8552对象来说,我们对其操作无非就是写其移位寄存器以实现命令和数据的下发。从其数据表中我们可以看到操作移位寄存器的时序如下所示:

  根据我们前面对DAC8552相关数据的了解以及上述时序图,我们可以封装对其移位寄存器的操作函数如下:

/*操作DAC8552输出通道*/
void SetDAC8552ChannelValue(DAC8552xObjectType *dac,DAC8552LDType ld,DAC8552BSType bs,DAC8552PDType pd,uint16_t data)
{uint32_t inputShiftData=0;uint8_t sData[3];inputShiftData=data;inputShiftData=inputShiftData|(ld<<20);inputShiftData=inputShiftData|(bs<<18);inputShiftData=inputShiftData|(pd<<16);sData[0]=(uint8_t)(inputShiftData>>16);sData[1]=(uint8_t)(inputShiftData>>8);sData[2]=(uint8_t)inputShiftData;dac->ChipSelcet(DAC8552CS_Enable);dac->WriteDataToDAC(sData,3);dac->ChipSelcet(DAC8552CS_Disable);
}

3、驱动的使用

  我们设计了DAC8552的对象驱动,但这个驱动是否正确我们需要验证一下。所以接下来我们设计一个简单的例子来实现对驱动程序的验证。

3.1、声明并初始化对象

  我们使用设计的驱动程序操作DAC8552时,首先需要使用我们定义的对象类型声明一个DAC8552对象。

DAC8552xObjectType dac8552;

  声明了这个对象变量之后,我们还需要使用初始化函数对其进行初始化方可使用。这一初始化函数拥有3个参数:

DAC8552xObjectType *dac,     //DAC8552对象变量
DAC8552WriteType write,      //写数据函数指针
DAC8552ChipSelectType cs     //片选操作函数指针

  第一个参数正是我们要初始化的对象变量;第二个参数为向DAC8552写命令和数据的函数指针;第三个参数是片选信号操作函数指针。这两个函数指针需要我们实现。它们的原型如下:

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

  我们根据函数原型定义,在具体的实现平台上实现它们,如我们在STM32平台上实现如下:

/*定义片选信号函数*/
void DAC8552CS(DAC8552CSType en)
{if(DAC8552CS_Enable==en){HAL_GPIO_WritePin(GPIOF, GPIO_PIN_4, GPIO_PIN_RESET);}else{HAL_GPIO_WritePin(GPIOF, GPIO_PIN_4, GPIO_PIN_SET);}
}/*定义发送数据函数*/
void DAC8552TransmitData(uint8_t *wData,uint16_t wSize)
{HAL_SPI_Transmit (&dac8552hspi, wData, wSize, 1000);
}

  我们将对象变量以及上面实现的2个函数的函数指针作为参数传递给DAC8552对象初始化函数来实现对象变量的初始化。具体如下:

DAC8552Initialization(&dac8552,               //DAC8552对象变量DAC8552TransmitData,    //写数据函数指针DAC8552CS               //片选操作函数指针);

3.2、基于对象进行操作

  初始化对象变量后,我们就可以基于该对象变量实现我们对DAC8552的操作了。我们已经封装了对其移位寄存器操作的函数,直接调用该函数来说实现我们的操作。一个简单的实现函数如下:

/* 修改DAC8552的通道输出 */
void DAC8552Operation(void)
{uint16_t wData=0;wData=(uint16_t)(65535*tValueA/100);SetDAC8552ChannelValue(&dac8552,              //所操作的DAC对象DAC8552_LoadA,         //加载的通道DAC8552BS_BufferA,     //选择的缓存DAC8552PD_Normal,      //Power-Down设置wData                  //所写的数据);wData=(uint16_t)(65535*tValueB/100);SetDAC8552ChannelValue(&dac8552,              //所操作的DAC对象DAC8552_LoadB,         //加载的通道DAC8552BS_BufferB,     //选择的缓存DAC8552PD_Normal,      //Power-Down设置wData                  //所写的数据);
}

  在这个例子中我们分别通过百分比设定值调整了A、B通道的输出,实现在正常模式下操作A或者B通道,并更新指定的缓存。

4、应用总结

  我们设计并实现了DAC8552模数转换器的驱动程序,并且设计了一个简单的应用来验证这一驱动程序的正确性。所得到的结果证明驱动的设计是没有问题的,实际上我们已经将其运用到实际的项目中,效果良好。
  在使用驱动程序时需要注意,片选信号并非必须实现。因为有些时候我们可能需要在硬件上直接将其选中,此时添加片选操作函数是没有什么意义的,我们可以在初始化时传入NULL来完成。

欢迎关注:

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

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

相关文章

软件设计开发笔记2:基于QT设计串口调试工具

串口通信是我们经常会遇到的问题。很多时候当我们设计一个串口应用时&#xff0c;我们希望有一个简便的、可视的方式来验证它。这一篇中我们就来基于QT设计一个串口调试工具。 1、概述 在开始软件设计之前&#xff0c;我们来简略地分析一下这样一个小软件其要包含的主要内容有…

外设驱动库开发笔记43:GPIO模拟SPI驱动

SPI总线是我们常用的串行设备接口&#xff0c;一般情况下我们都会适应硬件SPI接口&#xff0c;但有些时候当硬件端口不足时&#xff0c;我们也希望可以使用软件来模拟SPI硬件接口&#xff0c;特别是要求不是很高的时候。在这一篇中我们将来讨论如何使用GPIO和软件来模拟SPI通讯…

外设驱动库开发笔记44:DDC114 ADC驱动

在产品设计过程中&#xff0c;很多时候都会用到ADC器件&#xff0c;而在一些特殊场合还需要一些特别的ADC器件。我们在这篇中将讨论常用于医疗器件方面的&#xff0c;DDC114这款电流输入ADC&#xff0c;并为其设计一个驱动程序。 1、功能概述 模数转换器DDC114是一款电流输入型…

PID控制器改进笔记之七:改进PID控制器之防超调设定

我们已经设计了PID控制器&#xff0c;并根据实际使用的情况对器进行了诸多的改进。在这一篇中我们将讨论如何改进PID控制器超调的问题。 1、问题提出 在前面的文章中&#xff0c;我们曾推导过增量式PID控制器的公式&#xff0c;并且对其进行了离散化以适用于程序实现&#xff…

软件设计开发笔记3:基于QT的Modbus RTU主站

Modbus是一种常见的工业系统通讯协议。在我们的设计开发工作中经常使用到它。在这一篇中我们将简单实现一个基于QT的Modbus RTU主站上位工具。 1、概述 Modbus RTU主站应用很常见&#xff0c;有一些是通用的&#xff0c;有一些是专用的。而这里我们希望实现一个主要针对我们的…

外设驱动库开发笔记45:MS4515DO压力传感器驱动

很多时候我们需要检测流量和压力这些参数&#xff0c;比如我们要检测大气压&#xff0c;或者通过测量差压来获得输送流体的流量等&#xff0c;都需要用到压力传感器。这一篇我们就来讨论MS4515DO压力传感器的数据获取。 1、功能概述 MS4515DO是TE公司推出的一款基于PCB安装的小…

外设驱动库开发笔记48:MCP4725单通道DAC驱动

在产品设计过程中&#xff0c;我们经常会遇到数模转换的应用需求。在本篇种我们就来讨论一下MCP4725单通道数模转换器的驱动设计与实现。 1、功能概述 MCP4725是一个低功耗&#xff0c;高精度&#xff0c;单通道&#xff0c;12位缓冲电压输出数字到模拟转换器(DAC)与非易失性存…

如何确保不使用动态内存

在许多嵌入式应用程序中&#xff0c;内存分配必须是静态的&#xff0c;而不是动态的。意味着在应用程序中不应使用对malloc()或free()等内容的调用&#xff0c;因为它们可能会在运行时失败&#xff08;内存不足、堆碎片&#xff09;。 但是&#xff0c;当与第三方库甚至 C/C 标…

go 单元测试 testing 打印输出_2020,你需掌握go 单元测试进阶篇

本文说明go语言自带的测试框架未提供或者未方便地提供的测试方案&#xff0c;主要是用于解决写单元测试中比较头痛的依赖问题。也就是伪造模式&#xff0c;经典的伪造模式有桩对象(stub),模拟对象(mock)和伪对象(fake)。比较幸运的是&#xff0c;社区有丰富的第三方测试框架支持…

一文读懂Git工作流

Git是目前最流行的代码管理工具&#xff0c;相信大家也都是在用Git来管理自己团队的源代码。 团队一般为了规范开发&#xff0c;保持良好的代码提交记录以及维护 Git 分支结构清晰&#xff0c;方便后续维护等&#xff0c;都会迫切需要一个比较规范的 Git 工作流。 本文就是在…

xbox360fsd更新游戏封面_游戏类短视频创作指南

一&#xff0e;起步阶段1.内容发布垂直&#xff0c;整体风格一致&#xff0c;选定一个品类的游戏内容风格持续更新注意&#xff1a;冷启动时期不要频繁更换游戏类型2.账号IP化 根据自身风格特色打造独特的风格账号。有利延长账号生命周期&#xff0c;提升粉丝转化率。搞笑、中二…

开发者们都在关注的网站

开发者们都在关注的网站 &#x1f609; 综合类&#xff08;5个&#xff09; 1、GitHub 全球最大的编程开源社区&#xff0c;很多优秀的开源项目都在上边&#xff0c;不知道这个都不要说自己是程序员&#x1f602; 访问地址&#xff1a;https://github.com 2、CSDN 全球最大中…

ios framework 调用第三方 framework_Python基础:标准库和常用的第三方库

Python的标准库有&#xff1a;名称作用datetime为日期和时间处理同时提供了简单和复杂的方法。zlib直接支持通用的数据打包和压缩格式&#xff1a;zlib&#xff0c;gzip&#xff0c;bz2&#xff0c;zipfile&#xff0c;以及 tarfile。random提供了生成随机数的工具。math为浮点…

作图神器ProcessOn - 免费好用

因工作需要&#xff0c;我经常需要花一些流程图&#xff0c;时序图&#xff0c;架构图什么的&#xff0c;之前使用的Windows系统&#xff0c;大部分情况下就用的Visio来画图。后来为了工作方便&#xff0c;换成了Mac电脑&#xff0c;结果发现Mac上没有Visio&#xff0c;然后就在…

三电平igbt死区时间计算_基于大功率三电平IGBT模块并联的参考设计

当前的可再生能源行业中&#xff0c;光伏和风力发电均面临着补贴逐步退坡&#xff0c;平价上网时代即将到来的挑战。为应对这一挑战&#xff0c;光伏逆变器和风力变流器厂家研发的新品单机功率越来越高&#xff0c;以取得更低的单位功率成本。市场上1.5MW的集中式光伏逆变器和3…

手把手教你搭建开发环境之Java开发

大家好呀&#xff0c;从今天开始&#xff0c;我们的手把手系列教程就正式开始啦。 如果你觉得本文对你有一些帮助&#xff0c;欢迎大家关注、点赞、分享给需要的小伙伴们&#xff0c;谢谢大家啦。 前言 Java虽然是一个比较老的语言&#xff0c;但到现在依然充满了活力&#x…

opc服务器组态文件已写保护_远程组态软件不仅方便了PLC无线远程监控,也大大降低了工程成本...

远程组态软件不仅方便了PLC无线远程监控&#xff0c;也大大降低了工程成本组态软件远程监控1.本地上位SCADA系统采集分布各地现场PLC等设备运行的数据&#xff0c;并可以下发控制指令&#xff1b;2.提供稳定的OPC接口服务&#xff0c;常年稳定运行&#xff0c;规模可达10万数据…

奇妙的安全旅行之加密算法概述

前言 hi&#xff0c;大家好呀&#xff0c;信息安全作为当前社会中比较重要的一个课题&#xff0c;已经覆盖了人们生活的方方面面&#xff0c;虽然有时候我们可能并没有意识到&#xff0c;其实信息安全防护已经在背后默默的保护我们的信息安全了。例如&#xff0c;当你在互联网…

怎么调节电机启动值_开关式智能充电机-全自动充电机-铅酸电池充电机品牌-济南能华...

开关式智能充电机-全自动充电机-铅酸电池充电机品牌-济南能华NHCD系列 全自动智能充电机&#xff0c;可调智能充电机&#xff0c;可调直流充电机&#xff0c;可调全自动充电机 &#xff0c;可调蓄电池充电机 便携式可调智能充电机 便携式全自动充电机 大功率可调充电机 大功率智…

奇妙的安全旅行之MD算法

hi&#xff0c;大家好&#xff0c;今天我们开始介绍消息摘要算法中的MD&#xff08;Message Digest&#xff09;算法&#xff0c;MD算法家族包括&#xff1a;MD2&#xff0c;MD4&#xff0c;MD5&#xff0c;MD算法生成的消息摘长度要都是128位的。 其中MD5算法是消息摘要算法的…