项目需要,最近用到了一个IIC接口的DAC输出芯片-MCP4725。DAC都知道吧,数模转换,输入数字量,输出模拟量。本来想用PWM+二阶RC滤波的方式模拟DAC,后来担心输出纹波太大,索性还是用了这样一个芯片。
之前用了一个数字电位器MCP4017,它俩貌似一个系列,都是MCP开头。
MCP4725主要特性如下,从数据手册截了个图:
我摘几条关键的说一下,剩下的自己看:
- 12位的分辨率,精度高;
- 输出的模拟量掉电不丢失,可以存在芯片内部的EEPROM中;
- 单电源供电,2.7V~5.5V,以供电电压为基准;
- IIC接口支持标准速率、快速和高速。
接下来说用法。
一、应用电路
MCP4725的应用电路很简单,如下:
我这里用3.3V供电,前端加了一个磁珠做滤波。1脚输出模拟电压,4、5脚为IIC接口,其它的不解释。
6脚为硬件地址引脚,功能和24C02的管脚功能类似,用来设置器件地址,参照手册:
二、器件地址
每个IIC设备都有一个地址,而且在同一个电路中,这个地址应该是独一无二的。那么MCP4725的硬件地址是多少?
在7.2章节中,对地址做了描述,如图:
高4位为:1100,低3为:A2A1A0。A0通过外接高低电平能够确认,那么A2和A1是多少?
手册中写到A2和A1在出厂时已经固定了,所以固定的多少?在产品手册第47页中有说明:
根据命名不同,相应的地址也有不同。如我用的芯片型号:MCP4725A0T-E/CH,其中MCP4725表示芯片功能;A0对应Address Options中的A0:
0 0 External
所以地址位中的A2和A1固定为0。
这也是为什么我在应用电路的图中写到器件地址为:1100 000X.
三、工作模式
MCP4725的工作模式分为:正常模式和掉电模式,正常模式又分为快速模式、写DAC模式、写DAC和EEPROM模式。掉电模式又有三种下拉电阻可选。如下图:
3.1快速模式
这种模式下,可以快速更新掉电模式和DAC输出值。这种模式和IIC接口的400KHZ的快速模式是否有关联,我看了一遍手册,没找到确定信息。
通信格式如下:
IIC接口通信,第一个字节是器件地址,第二个字节高两位为命令配置位C2和C1,都是0表明工作在快速模式;紧跟着两位为掉电模式选择位,正常使用时配置为00即可;后四位为DAC的高4位数据。
第三个字节,为DAC的低8位数据。
所以,如果想在快速模式下通信,假设输出0V,发送数据如下:
0xc0 0x00 0x00
很简单!
3.2 写DAC寄存器和EEPROM模式
这种模式下,可以把DAC对应的数字量存入EEPROM中,同时输出模拟量。通信协议如下:
这种模式下进行IIC通信,第一个字节表示器件地址;
第二个字节,高3位表示命令类型,因为我们希望写DAC寄存器和EEPROM,所以高2位为:011。
紧跟着两位没有使用,默认写0即可。
再紧跟着两位用来选择掉电模式,正常工作时为:00.
最后一位没用到,默认写9即可。
第三个字节,为DAC数据的高8位。
第四个字节,高4位为DAC数据的低4位,低四位没用到,写0即可。
所以,当使用3.3V供电,想在写DAC寄存器和EEPROM模式下,输出1.65V电压(对应的DAC值为0x0800),那么发送数据如下:
0xc0 0x60 0x80 0x00
懂了吧!
实际应用中,使用STM32驱动,对应的代码如下:
void MCP4725_WriteToEEPROM(uint16_t value)
{
uint8_t data[3];
// 设置命令字节,写入DAC寄存器和EEPROM
data[0] = 0x60; // 写入DAC寄存器和EEPROM命令
data[1] = (value >> 4) & 0xFF; // 高字节
data[2] = (value << 4) & 0xFF; // 低字节
// 发送数据
HAL_I2C_Master_Transmit(&hi2c2, 0xC0, data, 3, HAL_MAX_DELAY);
}
该代码已经验证过,可以放心使用。
3.3 写DAC寄存器模式
和3.2模式高度相似,只是C0的值不一样,所以在上面的代码基础上改一下就行,不过多解释了。
3.4 掉电模式
说了半天掉电模式,还没咋解释。先放个表,如下:
前面3.2节那里,IIC通信的第二个字节的bit2和bit3那里,提到了PD1和PD0,这两个bit到底是什么,上面的表给了详细的解释。
这也是为什么我一直说正常工作时,这两个bit写00即可。
那么,对地的电阻1K,100K和500K又是怎么回事?看下图:
从这个图,我们可以知道,掉电模式下,图中的那个开关(Power-Down Control Circuit)是断开的。至于后面选哪个电阻,看你实际需要了。
四、读取DAC值
写完以后,为了验证是否写入成功,其实可以将DAC值读出来。IIC通信协议如下:
第3.2小节看懂的话,这个图就很简单了。不过因为我没有用到读数据的功能,所以这里就不提供代码了。
最后感慨一句,好简单啊!我是单片机爱好者-MCU起航,打完收工!