目录

1.AD/DA介绍

2.硬件电路模型

3.硬件电路

ADC0809:

DAC0832:

PCF8591(推荐使用)

ADC模块:

DAC模块:

4.运算放大器

5.运放电路

电压比较器

反向放大器:

同向放大器:

电压跟随器:

6.DA原理

T型电阻网络DA转换器:

PWM型DA转换器:

7.AD原理

逐次逼近型AD转换器:

8.AD/DA性能指标

分辨率:

转换速度:

9.XPT2046

10.XPT2046时序

11. AD模数转换代码(实现单片机内部电阻阻值可视化)

第一步:

第二步:

第三步:

第四步:

第五步:

第六步:

最终代码:

模块:

XPT2046.c

XPT2046.h

main.c

12.DA数模转换代码

第一步:

第二步:

第三步:

第四步:

最终代码:

模块:

main.c


1.AD/DA介绍

AD(Analog to Digital):模拟-数字转换,将模拟信号转换为计算机可操作的数字信号

DA(Digital to Analog):数字-模拟转换,将计算机输出的数字信号转换为模拟信号

AD/DA转换打开了计算机与模拟信号的大门,极大的提高了计算机系统的应用范围,也为模拟信号数字化处理提供了可能

2.硬件电路模型

AD转换通常有多个输入通道,用多路选择开关连接至AD转换器,以实现AD多路复用的目的,提高硬件利用率

AD/DA与单片机数据传送可使用并口(速度快、原理简单),也可使用串口(接线少、使用方便)

可将AD/DA模块直接集成在单片机内,这样直接写入/读出寄存器就可进行AD/DA转换,单片机的IO口可直接复用为AD/DA的通道

数字量和模拟量成正比关系

注:这里的串口和51单片机其他模块的串口不一样;DA使用比较少,AD使用比较多

3.硬件电路

ADC0809:

通过IN0~IN7输入信号,具体要输入什么信号,就要靠地址锁存与译码,A/D转换信号要靠START(开始转换)、EOC(结束转换)、CLOCK(转换时序)将信号通过锁存器进行输出缓存,最后靠输出使能(OE)给输出出去DB0~DB7

DAC0832:

输入信号D0~D7,放在两个寄存器(8位输入寄存器、8位DAC寄存器)里面,再同时ILE~XFER这些发出输出信号,然后两个寄存器就能通过8位D/A转换器输出信号

以上的ADC0809和DAC0832这两个芯片比较经典简单,比较容易理解,但不推荐使用这两个芯片,年代有点远。

PCF8591(推荐使用)

使用简单,用II2C总线的读写,就可以实现AD和DA的功能

ADC模块:

AIN0\AIN1\AIN2:光敏、热敏、可调节;数字量(0-255)、模拟量(0-5V);ADC触摸屏芯片

DAC模块:

在P21输出PWM波形,通过这个低通率波,就可以使用了

4.运算放大器

运算放大器(简称“运放”)是具有很高放大倍数的放大电路单元。内部集成了差分放大器、电压放大器、功率放大器三级放大电路,是一个性能完备、功能强大的通用放大电路单元,由于其应用十分广泛,现已作为基本的电路元件出现在电路图中

运算放大器可构成的电路有:电压比较器、反相放大器、同相放大器、电压跟随器、加法器、积分器、微分器等

运算放大器电路的分析方法:虚短、虚断(负反馈条件下)

虚短:在电路负反馈的状态下,负极电压等于正极电压;虚断:在负反馈电路中输入阻抗大的时候无法流入和流出

5.运放电路

电压比较器

反向放大器:

负反馈电路性质:V负>V正→VOUT=负,VOUT会负反馈V负,抑制,当V负=V正时,电路稳定了VOUT就停止反馈了。V负<V正→VOUT=正,VOUT一样会正反馈V负,同理。

公式的推导:因为这个电路是负反馈的,有虚短的性质,运算放大器负极和正极都等于0V,输入VIN电压,电流等于VIN/R1,因为流入阻抗大,有虚断的性质,无法流入运算放大器,所以只能流过R2,所以电流R2等于R1的电流,R2的电压等于VIN/R1×R2,VOUT等于R2左边的节点-VIN/R1×R2,最后推导公式为-R2/R1×VIN。有时这个电路也不方便,因为需要双电源

同向放大器:

因为这个电路也是负反馈电路,也拥有虚短和虚断的性质,因为虚短性质运算放大器的负极等于正极等于VIN,运算放大器的负极的电流会流向R1和R2,R2的电流为VIN/R1,因为R2的极性是右正左负,产生一个和R1相同的电流,这样VOUT等于VIN/R1×R2+VIN。会方便很多,不需要双电源

电压跟随器:

是同向放大器的一个变形,可以增加信号的驱动能力

6.DA原理

T型电阻网络DA转换器:

DAC0832中的8位D/A转换器的具体电路图。D7~D0给高电平,控制模拟开关的断开闭合;运算放大器处于一个负反馈电路,拥有虚短和虚断的性质,运算放大器正极接地,因为虚短负极电压为0,所以,两跟线电压为0;电路总电阻为R,电流关系:I1 = 2 I0, I2 = 2 I1……I7 = 2 I6 ---> Ix = 2^x I0,故而达到了二进制的位权的效果,所以有了下面的公式。I0 = 1/256*VREF/R ,当Rfb = R时,输入多少就输出多少

PWM型DA转换器:

低通滤波器用于过滤交流分量;电压跟随器用于增加信号的驱动能力;占空比:开始时间/总时间(开始时间+结束时间)

7.AD原理

AD大概思路:就是我不知道这个输入的电压的大小,就接一个已知的电压,与未知的电压进行比较,这样就间接的就用已知电压表示未知的电压

逐次逼近型AD转换器:

输出数字量    (D7~D0)=V_IN/V_REF×256 …… 结果取整

8.AD/DA性能指标

有很多这里只列举了两个,这两个比较常用

分辨率:

指AD/DA数字量的精细程度,通常用位数表示。例如,对于5V电源系统来说,8位的AD可将5V等分为256份,即数字量变化最小一个单位时,模拟量变化5V/256=0.01953125V,所以,8位AD的电压分辨率为0.01953125V,AD/DA的位数越高,分辨率就越高

转换速度:

表示AD/DA的最大采样/建立频率,通常用转换频率或者转换时间来表示,对于采样/输出高速信号,应注意AD/DA的转换速度

9.XPT2046

10.XPT2046时序

CS:片选、共用线:DCLK时钟、DIN输入、DOUT输出

11. AD模数转换代码(实现单片机内部电阻阻值可视化)

第一步:

把延时、液晶屏LCD模块复制粘贴到本工程

第二步:

建立XPT2046源文件和头文件

第三步:

接口引脚定义:CS\DCLK\DIN\DOUT

第四步:

根据上面时序在XPT2046.c写代码,不要管这么多内部的实现方法,因为已经集成了,直接用就可以了

第五步:

在XPT2046.h中根据单端模式输入配置中的各个通道进行宏定义

第六步:

主函数调用

最终代码:

模块:

XPT2046.c

#include <REGX52.H>
#include <INTRINS.H>

//引脚定义
sbit XPY2046_DIN=P3^4;
sbit XPY2046_CS=P3^5;
sbit XPY2046_DCLK=P3^6;
sbit XPY2046_DOUT=P3^7;

/**
  * @brief  ZPT2046读取AD值
  * @param  Command 命令字,范围:头文件内定义的宏,结尾的数字表示转换的位数
  * @retval AD转换后的数字量,范围:8位为0~255,12位为0~4095
  */
unsigned int XPT2046_ReadAD(unsigned char Command)
{
	unsigned char i;
	unsigned int Data=0;
	XPY2046_DCLK=0;
	XPY2046_CS=0;
	for(i=0;i<8;i++)
	{
		XPY2046_DIN=Command&(0x80>>i);
		XPY2046_DCLK=1;
		XPY2046_DCLK=0;
	}
	for(i=0;i<16;i++)
	{
		XPY2046_DCLK=1;
		XPY2046_DCLK=0;
		if(XPY2046_DOUT){Data|=(0x8000>>i);}
	}
	XPY2046_CS=1;
	return Data>>8;
}

XPT2046.h

#ifndef __XPT2046_H__
#define __XPT2046_H__

#define XPT2046_VBAT	0xAC
#define XPT2046_AUX		0xEC
#define XPT2046_XP		0x9C	//0xBC
#define XPT2046_YP		0xDC

unsigned int XPT2046_ReadAD(unsigned char Command);

#endif

main.c

#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "XPT2046.h"

unsigned int ADValue;

void main(void)
{
	LCD_Init();
	LCD_ShowString(1,1,"ADJ  NTC  GR");
	while(1)
	{
		ADValue=XPT2046_ReadAD(XPT2046_XP);		//读取AIN0,可调电阻
		LCD_ShowNum(2,1,ADValue,3);				//显示AIN0
		ADValue=XPT2046_ReadAD(XPT2046_YP);		//读取AIN1,热敏电阻
		LCD_ShowNum(2,6,ADValue,3);				//显示AIN1
		ADValue=XPT2046_ReadAD(XPT2046_VBAT);	//读取AIN2,光敏电阻
		LCD_ShowNum(2,11,ADValue,3);			//显示AIN2
		Delay(100);
	}
}

12.DA数模转换代码

因为DA数模转换的原理就是PWM,只是多了一个低通滤波,所以我们直接把直流电机调速的工程直接复制,直流电机调速的代码在小编的51单片机直流电机实验

第一步:

更改I/O的定义

第二步:

改名字,在主函数里面将代码中Motor改成DA

第三步:

将按键和数码管模块删除,在主函数里面讲按键和数码管相关代码删除

第四步:

修改主函数

最终代码:

模块:

main.c

#include <REGX52.H>
#include "Delay.h"
#include "Timer0.h"

sbit DA=P2^1;

unsigned char Counter,Compare;	//计数值和比较值,用于输出PWM
unsigned char i;

void main()
{
	Timer0_Init();
	while(1)
	{
		for(i=0;i<100;i++)
		{
			Compare=i;			//设置比较值,改变PWM占空比
			Delay(10);
		}
		for(i=100;i>0;i--)
		{
			Compare=i;			//设置比较值,改变PWM占空比
			Delay(10);
		}
	}
}

void Timer0_Routine() interrupt 1
{
	TL0 = 0x9C;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	Counter++;
	Counter%=100;	//计数值变化范围限制在0~99
	if(Counter<Compare)	//计数值小于比较值
	{
		DA=1;		//输出1
	}
	else				//计数值大于比较值
	{
		DA=0;		//输出0
	}
}
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐