数字和模拟是电子学不可或缺的一部分。大多数设备同时具有ADC和DAC,并且在需要将信号从模拟转换为数字或将数字转换为模拟时使用。同样,诸如声音和光之类的现实世界信号本质上也是模拟信号,因此无论何时必须使用这些现实信号,都必须将数字信号转换为模拟信号,例如使用扬声器产生声音或控制光源。
另一种类型的DAC是脉宽调制器(PWM)。PWM接收数字字并生成具有可变脉冲宽度的数字脉冲。当该信号通过滤波器时,结果将是纯模拟的。模拟信号可以在信号中具有多种类型的数据。
在本教程中,我们将DAC MCP4921与Microchip PIC16F877A进行接口以进行数模转换。
在本教程的此处,我们将把数字信号转换为模拟信号,并在16x2 LCD上显示输入数字值和输出模拟值。它将提供1V,2V,3V,4V和5V作为最终的模拟输出,这将在最后的视频中进行演示。您可以在我们与Raspberry Pi,Arduino和STM32电路板进行DAC接口的宝贵教程中进一步了解DAC。
DAC可用于许多应用中, 例如电机控制,LED灯的控制亮度,音频放大器,视频编码器,数据采集系统等。在直接进入接口部分之前,对MCP4921进行概述很重要。
MCP4921 DAC(数模转换器)
MCP4921是12位DAC,因此MCP4921将提供12位输出分辨率。DAC分辨率意味着可以转换为模拟信号的数字位数。我们可以从公式中获得多少值。对于12位,它等于4096。这意味着12位分辨率的DAC可以产生4096个不同的输出。
通过使用该值,可以轻松计算单个模拟步进电压。为了计算步长,需要参考电压。由于该设备的逻辑电压为5V,因此步进电压为5/4095(因为数字的起始点不为1,所以为0,因此为4096-1),即0.00122100122毫伏。因此,更改1位将更改模拟输出0.00122100122。
因此,这就是转换部分。所述MCP4921是一个8管脚IC。的引脚图和描述可以在下面找到。
所述MCP4921 IC与由SPI协议的微控制器通信。对于SPI通信,设备必须是主设备,它将数据或命令提交给作为从设备连接的外部设备。在SPI通信系统中,多个从设备可以与单个主设备连接。
要提交数据和命令,了解命令寄存器很重要。
下图显示了命令寄存器,
该命令寄存器是16位寄存器。位15到位12用于配置命令。上图清楚显示了数据输入和配置。在此项目中,MCP4921将用作以下配置-
位数 |
组态 |
配置值 |
15位 |
DAC一 |
0 |
14位 |
无缓冲 |
0 |
13位 |
1个(V OUT * D / 4096) |
1个 |
12位 |
输出掉电控制位 |
1个 |
因此二进制数与寄存器的D11至D0位确定的数据一起为0011。需要提交16位数据0011 xxxx xxxx xxxx,其中MSB的前4位是配置,其余是LSB。通过查看写命令时序图,将更加清楚。
根据时序图和数据手册,在向MCP4921的整个命令写入期间,CS引脚为低电平。
现在是时候将设备与硬件接口并编写代码了。
所需组件
对于此项目,需要以下组件-
- MCP4921
- PIC16F877A
- 20 MHz晶振
- 一个显示16x2字符的LCD。
- 2k电阻-1 pc
- 33pF电容器-2个
- 4.7k电阻-1个
- 万用表测量输出电压
- 面包板
- 5V电源,一个手机充电器可以工作。
- 许多连接线或冰山电线。
- 带编程器套件的Microchip编程环境和带编译器的IDE
原理图
电路图为 与PIC单片机的接口DAC4921 给出如下:
该电路在面包板中构建-
代码说明
完整的代码 用于将数字信号转换成模拟与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 //闪存程序存储器代码保护位(代码保护关闭)
以下代码行用于集成LCD和SPI头文件,还声明了XTAL Frequency和DAC的CS引脚连接。
PIC SPI教程和库可在给定的链接中找到。
#包括
对于此项目所需的其他配置,对 SPI_Initialize_Master() 进行了略微修改。在这种情况下,SSPSTAT寄存器的配置方式应使数据输出时间结束时采样的输入数据以及配置为发送的SPI时钟也发生在从活动时钟状态模式转换为空闲时钟状态模式时。其他都一样。
无效SPI_Initialize_Master() { TRISC5 = 0; //设置为输出 SSPSTAT = 0b11000000; // pg 74/234 SSPCON = 0b00100000; //第75/234页 TRISC3 = 0; //设置为从模式的输出 }
同样,对于以下函数,对 SPI_Write() 进行了一些修改。清除缓冲区后将进行数据传输,以确保通过SPI进行完美的数据传输。
无效SPI_Write(字符传入) { SSPBUF =传入; //将用户给定的数据写入到 while(!SSPSTATbits.BF); }
该程序的重要部分是MCP4921驱动程序。由于将命令和数字数据打孔在一起以在SPI上提供完整的16位数据,因此它有些棘手。但是,该逻辑在代码注释中清楚地显示。
/ * 此功能用于将数字值转换为模拟值。 * / void convert_DAC(unsigned int value) { / *步长= 2 ^ n,因此12位2 ^ 12 = 4096 对于5V参考,步长将是5/4095 = 0.0012210012210012V或1mV(大约)* / unsigned int容器; 未签名的int MSB; 未签名的int LSB; / *步骤:1,将12位数据存储到容器中 假设数据为4095,以二进制1111 1111 1111 * / container = value; / *步骤:2创建8位虚拟对象。因此,通过除以256,可在LSB中捕获高4位 LSB = 0000 1111 * / LSB = container / 256; / *步骤:3通过打孔4位数据发送配置。 LSB = 0011 0000或00001111。结果为0011 1111 * / LSB =(0x30)-LSB; / *步骤:4容器仍具有21位值。提取低8位。 1111 1111和1111 11111111。结果是1111 1111,即MSB * / MSB = 0xFF&容器; / *步骤:4通过划分为两个字节来发送16位数据。* / DAC_CS = 0; //数据传输期间CS为低电平。根据数据表,需要 SPI_Write(LSB); SPI_Write(MSB); DAC_CS = 1; }
在主要功能中,使用“ for循环”,在其中创建用于创建1V,2V,3V,4V和5V输出的数字数据。将根据输出电压/ 0.0012210012210012毫伏计算数字值。
void main(){ system_init(); Introduction_screen(); int number = 0; 内部电压= 0; 而(1){ for(volt = 1; volt <= MAX_VOLT; volt ++){ number = volt / 0.0012210012210012; clear_screen(); lcd_com(FIRST_LINE); lcd_puts(“发送的数据:-”); lcd_print_number(number); lcd_com(SECOND_LINE); lcd_puts(“ Output:-”); lcd_print_number(volt); lcd_puts(“ V”); convert_DAC(数字); __delay_ms(300); } } }
使用PIC测试数模转换
使用万用表测试构建的电路。在下图中,LCD上显示了输出电压和数字数据。万用表显示接近的读数。
随附带有工作视频的完整代码,如下。