风筝
发表于: 2020-2-9 11:33:53 | 显示全部楼层

数字和模拟是电子学不可或缺的一部分。大多数器件同时具有ADC和DAC,并且在需要将信号从模拟转换为数字或将数字转换为模拟时使用。而且,诸如声音和光之类的现实世界信号本质上也是模拟的,因此,每当必须使用这些现实世界信号时,就必须将数字信号转换为模拟信号,例如使用扬声器产生声音或控制光源。


另一种类型的DAC是脉宽调制器(PWM)。 PWM接收数字字并生成具有可变脉冲宽度的数字脉冲。当该信号通过滤波器时,结果将是纯模拟的。模拟信号中的信号可以具有多种类型的数据。


在本篇文章中,我们将Microchip的单片机PIC16F877连接ADAC MCP4921以实现数模转换。在本文中,我们将把数字信号转换为模拟信号,并在1602 LCD上显示输入数字值和输出模拟值。它将提供1V、2V、3V、4V和5V作为最终的模拟输出。


DAC可用于许多应用中,例如电机控制、LED灯的控制亮度、频放大器、视频编码器、数据采集系统等。


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-Pinout.png


MCP4921 IC通过SPI通信与微控制器通信。对于SPI通信,设备必须是主设备,它将数据或命令提交给作为从设备连接的外部设备。在SPI通信系统中,多个从设备可以与单个主设备连接。


要提交数据和命令,重要的是要了解命令寄存器。


下图显示了命令寄存器,

MCP4921-IC-Communication-with-Microcontroller-by-the-SPI-Protocol.png


命令寄存器是一个16位寄存器。位15到位12用于配置命令。上图清楚显示了数据输入和配置。寄存器的D11至D0位所确定的数据一起为0011。需要提交16位数据0011 xxxx xxxx xxxx,其中MSB的前4位是配置,其余是LSB。通过查看写命令时序图,将更加清楚。

MCP4921-Timing-Diagram.png


根据时序图和数据手册,在向MCP4921的整个命令写入期间,CS引脚为低电平。现在是时候将器件与硬件连接并编写代码了。


所需的组件

●    MCP4921

●    PIC16F877A单片机

●    20 MHz晶振

●    显示16x2字符LCD。

●    万用表

●    面包板

●    5V电源


连接原理图

下面给出了将DAC4921与PIC微控制器连接的电路图:

Circuit-Diagram-for-DAC-MCP4921-Interfacing-with-PIC-Microcontroller-PIC16F877A.png

该电路在面包板中制作,

Circuit-Hardware-for-DAC-MCP4921-Interfacing-with-PIC-Microcontroller-PIC16F877A.jpg


代码说明

本文末尾提供了用于使用PIC16F877A将数字信号转换为模拟信号的完整代码。与往常一样,我们首先需要在PIC微控制器中设置配置位。

  1. // PIC16F877A Configuration Bit Settings
  2. // 'C' source line config statements
  3. // CONFIG

  4. #pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
  5. #pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
  6. #pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
  7. #pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
  8. #pragma config LVP = OFF         // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3/PGM pin has PGM function; low-voltage programming enabled)
  9. #pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
  10. #pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
  11. #pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)
复制代码

以下代码行用于包含LCD和SPI头文件,还声明了XTAL频率和DAC的CS引脚连接。

  1. #include <xc.h>
  2. #include <stdint.h>
  3. #include "supporing_cfile\lcd.h"
  4. #include "supporing_cfile\PIC16F877a_SPI.h"

  5. /*
  6. Hardware related definition
  7. */

  8. #define _XTAL_FREQ 200000000 //Crystal Frequency, used in delay
  9. #define DAC_CS PORTCbits.RC0 //Declaring DAC CS pin
复制代码

根据本文所需的其他配置,对SPI_Initialize_Master()进行了略微修改。将SSPSTAT寄存器配置为数据输出时间结束时采样输入数据,及将SPI时钟配置为从活动时钟状态模式转换为空闲时钟状态模式进行发送时。其他都一样。

  1. void SPI_Initialize_Master()
  2. {
  3.                 TRISC5 = 0; // Set as output
  4.                 SSPSTAT = 0b11000000; //pg 74/234
  5.                 SSPCON = 0b00100000; //pg 75/234
  6.                 TRISC3 = 0; //Set as output for slave mode
  7. }
复制代码

同样,对SPI_Write()函数也进行了一些修改。清除缓冲区后将进行数据传输,以确保通过SPI进行完美的数据传输。

  1. void SPI_Write(char incoming)
  2. {
  3.                 SSPBUF = incoming; //Write the user given data into buffer
  4.                 while (!SSPSTATbits.BF);
  5. }
复制代码

该程序的重​​要部分是MCP4921驱动程序。由于将命令和数字数据结合在一起以在SPI上提供完整的16位数据,因此它有些困难。但是,该逻辑在代码注释中清楚地显示。

  1. /*
  2. This Function is for converting the digital value to the analog.
  3. */
  4. void convert_DAC(unsigned int value)
  5. {
  6.    /*Step Size = 2^n, Therefore 12bit 2^12 = 4096
  7.      For 5V reference, the step will be 5/4095 = 0.0012210012210012V or 1mV (approx)*/
  8.   unsigned int container ;
  9.   unsigned int MSB;
  10.   unsigned int LSB;
  11.   /*Step: 1, stored the 12 bit data into the container
  12.    Suppose the data is 4095, in binary 1111 1111 1111*/
  13.   container = value;   
  14.   /*Step: 2 Creating Dummy 8 bit. So, by dividing 256, upper 4 bits are captured in LSB
  15.    LSB = 0000 1111*/
  16.   LSB = container/256;
  17.   /*Step: 3 Sending the configuration with punching the 4 bit data.
  18.    LSB = 0011 0000 OR 0000 1111. Result is 0011 1111 */
  19.   LSB = (0x30) | LSB;
  20.   /*Step:4 Container still has the 21bit value. Extracting the lower 8 bits.
  21.    1111 1111 AND 1111 1111 1111. Result is 1111 1111 which is MSB*/  
  22.   MSB = 0xFF & container;   
  23. /*Step:4 Sending the 16bits data by dividing into two bytes. */
  24.     DAC_CS = 0;     // CS is low during data transmission. As per the data-sheet it is required         
  25.     SPI_Write(LSB);
  26.     SPI_Write(MSB);   
  27.     DAC_CS = 1;              
  28. }
复制代码

在main函数中,使用“ for loop”用于创建用于1V、2V、3V、4V和5V输出的数字数据。 将根据输出电压/ 0.0012210012210012毫伏计算数字值。

  1. void main() {
  2.     system_init();
  3.     introduction_screen();
  4.     int number=0;
  5.     int volt=0;
  6.     while (1) {
  7.         for (volt=1; volt<=MAX_VOLT; volt++){
  8.             number = volt / 0.0012210012210012;
  9.             clear_screen();           
  10.             lcd_com(FIRST_LINE);            
  11.             lcd_puts("DATA Sent:- ");
  12.             lcd_print_number(number);
  13.             lcd_com(SECOND_LINE);            
  14.             lcd_puts("Output:-      ");            
  15.             lcd_print_number(volt);
  16.             lcd_puts("V");
  17.             convert_DAC(number);
  18.             __delay_ms(300);                                    
  19.         }
  20.     }
  21. }
复制代码

测试PIC的数模转换

使用万用表测试搭建的电路。 在下图中,LCD上显示了输出电压和数字数据。 万用表显示接近的读数。

Testing-the-Digital-to-Analog-Conversion-Using-PIC.jpg


代码

以下是本文使用的完整代码: main.rar (1.8 KB, 下载次数: 18)

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 10 | 回复: 13



手机版|

GMT+8, 2024-12-22 16:27 , Processed in 0.050326 second(s), 6 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表