数字和模拟是电子学的一个组成部分。大多数设备同时具有ADC和 DAC,当需要将信号从模拟转换为数字或从数字转换为模拟时使用它们。此外,声音和光等现实世界的信号本质上是模拟的,因此无论何时必须使用这些现实世界的信号,都必须将数字信号转换为模拟信号,例如使用扬声器产生声音或控制光源。 另一种类型的 DAC 是脉冲宽度调制器 (PWM)。PWM 接收一个数字字并生成一个具有可变脉冲宽度的数字脉冲。当这个信号通过一个滤波器时,结果将是纯模拟的。一个模拟信号在一个信号中可以有多种类型的数据。 在本教程中,我们将DAC MCP4921 与 Microchip PIC16F877A 接口以进行数模转换。 在本教程中,我们将数字信号转换为模拟信号,并在16x2 LCD上显示输入数字值和输出模拟值。它将提供 1V、2V、3V、4V 和 5V 作为最终的模拟输出,这在最后给出的视频中进行了演示。 DAC 可用于许多应用 ,例如电机控制、LED 灯的控制亮度、 音频放大器、视频编码器、数据采集系统等。在直接跳转到接口部分之前,了解 MCP4921 的概述非常重要。 MCP4921 DAC(数模转换器) MCP4921 是 12 位 DAC,因此 MCP4921 将提供 12 位输出分辨率。DAC 分辨率是指可以转换为模拟信号的数字位数。我们可以从中获得多少价值是基于公式的。对于 12 位,它 = 4096。这意味着 12 位分辨率 DAC 可以产生 4096 个不同的输出。 通过使用该值,可以轻松计算单个模拟阶跃电压。为了计算步数,需要参考电压。由于该器件的逻辑电压为 5V,因此步进电压为 5/4095(4096-1,因为数字的起点不是 1,而是 0),即 0.00122100122 毫伏。因此,更改 1 位将使模拟输出更改为 0.00122100122。 所以,这就是转换部分。MCP4921是一个 8 引脚 IC。引脚图和说明可以在下面找到。 MCP4921 IC通过SPI 协议与微控制器通信。对于 SPI 通信,设备必须是主设备,它向作为从设备连接的外部设备提交数据或命令。在 SPI 通信系统中,单个主设备可以连接多个从设备。 要提交数据和命令,了解命令寄存器很重要。 在下图中,显示了命令寄存器, 命令寄存器是一个16 位寄存器。bit-15 到 bit-12 用于配置命令。上图清楚地显示了数据输入和配置。在本项目中,MCP4921 将用作以下配置 - 所以二进制是 0011 以及由寄存器的 D11 到 D0 位确定的数据。需要提交16位数据0011 xxxx xxxx xxxx,其中MSB的前4位为配置,其余为LSB。看写命令时序图会更清楚。 根据时序图和数据表,在向 MCP4921 的整个命令写入周期内,CS 引脚为低电平。 现在是时候将设备与硬件连接并编写代码了。 所需组件 对于这个项目,需要以下组件 - MCP4921 PIC16F877A 20兆赫晶体 显示 16x2 字符 LCD。 2k电阻-1个 33pF 电容器 - 2 个 4.7k 电阻器 - 1 个 万用表测量输出电压 面包板 5V供电,一个手机充电器即可工作。 很多连接线或 berg 线。 带有 Programmer 套件和带有编译器的 IDE 的 Microchip 编程环境 示意图 将DAC4921 与 PIC 微控制器连接的电路图 如下所示: 该电路是在面包板中构建的- 代码说明 文章末尾给出了使用 PIC16F877A 将数字信号转换为模拟信号 的完整代码。与往常一样,我们首先需要 设置 PIC 单片机中的配置位。
// PIC16F877A 配置位设置// 'C' 源代码行配置语句// CONFIG#pragma config FOSC = HS // 振荡器选择位(HS 振荡器)#pragma config WDTE = OFF // 看门狗定时器使能位(WDT 禁用)#pragma config PWRTE = OFF // 上电定时器使能位(PWRT 禁用)# pragma config BOREN = ON // 欠压复位使能位(BOR 使能)#pragma config LVP = OFF // 低电压(单电源)在线串行编程使能位(RB3/PGM 引脚具有 PGM 功能;低-电压编程启用)#pragma config CPD = OFF // 数据 EEPROM 存储器代码保护位(数据 EEPROM 代码保护关闭)#pragma config WRT = OFF // 闪存程序存储器写使能位(写保护关闭;所有程序存储器都可以由 EECON 控制写入)#pragma config CP = OFF // Flash 程序存储器代码保护位(代码保护关闭)
以下代码行用于集成 LCD 和 SPI 头文件,还声明了 XTAL 频率和 DAC 的 CS 引脚连接。 PIC SPI 教程和库可以在给定的链接中找到。
#include
SPI_Initialize_Master ()功能针对该项目所需的不同配置稍作修改。在这种情况下,SSPSTAT 寄存器的配置方式是,在数据输出时间结束时采样输入数据以及配置为发送的 SPI 时钟发生在从活动时钟状态模式转换到空闲时钟状态模式时。其他也一样。
无效 SPI_Initialize_Master() { TRISC5 = 0; // 设置为输出 SSPSTAT = 0b11000000; //pg 74/234 SSPCON = 0b00100000; //pg 75/234 TRISC3 = 0; //设置为从模式的输出}
此外,对于以下函数,SPI_Write() 稍作修改。数据传输将在缓冲区清空后进行,以确保通过 SPI 进行完美的数据传输。
无效 SPI_Write(char 传入) { SSPBUF = 传入; //将用户给定的数据写入缓冲区 while (!SSPSTATbits.BF); }
该程序的重要部分是 MCP4921 驱动程序。这是一个有点棘手的部分,因为命令和数字数据被打孔在一起以通过 SPI 提供完整的 16 位数据。但是,该逻辑清楚地显示在代码注释中。
/*此函数用于将数字值转换为模拟值。*/ void convert_DAC(unsigned int value) { /*步长 = 2^n, 因此 12bit 2^12 = 4096 对于 5V 参考,步长将为 5/4095 = 0.0012210012210012V 或 1mV(大约)*/ unsigned int 容器; 无符号整数 MSB; 无符号整数 LSB; /*步骤:1、将12位数据存入容器 假设数据为4095,二进制1111 1111 1111*/ container = value; /*步骤:2 创建虚拟 8 位。因此,通过除以 256,在 LSB 中捕获高 4 位 LSB = 0000 1111*/ LSB = container/256; /*Step: 3 发送配置打孔4位数据。 LSB = 0011 0000 或 0000 1111。结果为 0011 1111 */ LSB = (0x30) | 低位; /*Step:4 容器仍然有 21bit 的值。提取低 8 位。 1111 1111 和 1111 1111 1111。结果是 1111 1111,即 MSB*/ MSB = 0xFF & 容器; /*Step:4 将16bits的数据分成两个字节发送。*/ DAC_CS = 0; // 数据传输期间 CS 为低电平。根据数据表,需要 SPI_Write(LSB); SPI_Write(MSB); DAC_CS = 1; }
在主函数中,使用“for 循环”来创建用于创建 1V、2V、3V、4V 和 5V 输出的数字数据。数字值是根据输出电压 / 0.0012210012210012 毫伏计算得出的。
无效 main() { system_init(); 介绍屏幕(); 整数=0; 国际伏特=0; 而 (1) { for (volt=1; volt<=MAX_VOLT; volt++){ number = volt / 0.0012210012210012; 清除屏幕(); lcd_com(FIRST_LINE); lcd_puts("数据发送:-"); lcd_print_number(数字); lcd_com(第二行); lcd_puts("输出:-"); lcd_print_number(伏特); lcd_puts("V"); 转换_DAC(数字); __delay_ms(300); } } }
使用 PIC 测试数模转换 使用万用表测试构建的电路。在下图中,输出电压和数字数据显示在 LCD 上。万用表显示接近读数。 /* |