福建建设工程信息网,搜索引擎优化的目标,一个公司多个网站做优化,汕头模拟信号输出是经常会遇到的应用需求#xff0c;解决的办法应多种#xff0c;但我们使用最多的还是数模转换。对于不同的数模转换器我们需要为其编写适用的驱动程序#xff0c;在这一篇中我们就来考虑如何实现DAC8552高精度模数转换器的驱动程序。
1、功能概述 该DAC8552是… 模拟信号输出是经常会遇到的应用需求解决的办法应多种但我们使用最多的还是数模转换。对于不同的数模转换器我们需要为其编写适用的驱动程序在这一篇中我们就来考虑如何实现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”DB21LDB位和DB20LDA用于控制后面的16位数据适用于加载哪一个输出通道还是Power_Down命令。DB19没有定义DAC8552不关心该位的具体数值。DB18为缓冲器选择位用于控制数据的目标通道是DAC A还是DAC B。后续的DB17PD1和DB16PD0用于选择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((dacNULL)||(writeNULL)){return;}if(cs!NULL){dac-ChipSelcetcs;}else{dac-ChipSelcetDefaultChipSelect;}
}2.2、对象操作 我们已经定义了DAC8552的对象类型并为DAC8552对象设计了初始化函数接下来我们看一看DAC8552所要实现的操作。对于DAC8552对象来说我们对其操作无非就是写其移位寄存器以实现命令和数据的下发。从其数据表中我们可以看到操作移位寄存器的时序如下所示 根据我们前面对DAC8552相关数据的了解以及上述时序图我们可以封装对其移位寄存器的操作函数如下
/*操作DAC8552输出通道*/
void SetDAC8552ChannelValue(DAC8552xObjectType *dac,DAC8552LDType ld,DAC8552BSType bs,DAC8552PDType pd,uint16_t data)
{uint32_t inputShiftData0;uint8_t sData[3];inputShiftDatadata;inputShiftDatainputShiftData|(ld20);inputShiftDatainputShiftData|(bs18);inputShiftDatainputShiftData|(pd16);sData[0](uint8_t)(inputShiftData16);sData[1](uint8_t)(inputShiftData8);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_Enableen){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 wData0;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来完成。
欢迎关注