JackCin's blog JackCin's blog
首页
  • 页面

    • Html
    • CSS
  • 核心

    • JavaScript基础
    • JavaScript高级
  • 框架

    • Vue
  • jQuery
  • Node
  • Ajax
Linux
  • 操作系统
  • 数据结构与算法
  • 51单片机
  • CC2530
  • 网站
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

JackCin

前端小菜鸡(✪ω✪)
首页
  • 页面

    • Html
    • CSS
  • 核心

    • JavaScript基础
    • JavaScript高级
  • 框架

    • Vue
  • jQuery
  • Node
  • Ajax
Linux
  • 操作系统
  • 数据结构与算法
  • 51单片机
  • CC2530
  • 网站
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 51单片机

    • 51单片机及补充知识
    • LED
    • 独立按键
    • 数码管
    • LCD1602液晶显示器
    • 矩阵按键
    • 定时器
    • 串口
    • LED点阵屏
    • 蜂鸣器
    • AT24C02存储器
    • AD与DA
      • 一、AD/DA介绍
      • 二、硬件电路模型
        • 1、AD
        • 2、DA
      • 三、运算放大器
      • 四、运放电路
        • 运放电路
        • 1、电压比较器
        • 2、反向放大器
        • 3、同相放大器
        • 4、电压跟随器
      • 五、DA原理
        • 1、T型电阻网络DA转换器
        • 2、PWM型DA转换器
      • 六、AD原理
        • 1、逐次逼近型AD转换器
        • 2、AD/DA性能指标
      • 七、XPT2046
        • 1、功能说明
        • 2、时序
      • 八、AD数模转换代码
      • 九、DA数模转换
    • DS18B20温度传感器
    • DS1302时钟
    • LCD1602液晶显示屏
    • 红外遥控
    • 呼吸灯与直流电机调速(PWM)
  • 单片机
  • 51单片机
JackCin
2023-09-13
目录

AD与DA

# AD/DA转换

学习目标:

  • AD/DA转换,也就是数字信号与模拟信号之间的转换。模拟信号转换为数字信号我们使用可调电阻、光敏电阻和热敏电阻来实现,在光敏电阻小于100时(较暗),D1灯会自动亮;而数字信号转换为模拟信号我们使用实现DA呼吸灯来展示。

# 一、AD/DA介绍

  • AD(Analog to Digital):模拟-数字转换,将模拟信号转换为计算机可操作的数字信号。
  • DA(Digital to Analog):数字-模拟转换,将计算机输出的数字信号转换为模拟信号。
  • AD/DA转换打开了计算机与模拟信号的大门,极大的提高了计算机系统的应用范围,也为模拟信号数字化处理提供了可能。

img

# 二、硬件电路模型

  • AD:就是将电压量转换为数字量。

  • DA:其实有点类似于PWM,最后经过一个低通滤波器,就能实现效果了。

img

  • AD转换通常有多个输入通道,用多路选择开关连接至AD转换器,以实现AD多路复用的目的,提高硬件利用率
  • AD/DA与单片机数据传送可使用并口(速度快、原理简单),也可使用串口(接线少、使用方便)
  • 可将AD/DA模块直接集成在单片机内,这样直接写入/读出寄存器就可进行AD/DA转换,单片机的IO口可直接复用为AD/DA的通道

# 1、AD

这是一个简单的AD芯片(ADC0809),首先选择模拟开关,之后进行AD转换,再通过缓存器输出,就可以了。

img

ADC模块

# 2、DA

这是一个简单的DA芯片(ADC0832),首先输入数据,通过控制电路控制寄存器,最后通过一个DA转换器输出就成了。

img

DAC模块

# 三、运算放大器

  • 运算放大器(简称“运放”)是具有很高放大倍数的放大电路单元。内部集成了差分放大器、电压放大器、功率放大器三级放大电路,是一个性能完备、功能强大的通用放大电路单元,由于其应用十分广泛,现已作为基本的电路元件出现在电路图中
  • 运算放大器可构成的电路有:电压比较器、反相放大器、同相放大器、电压跟随器、加法器、积分器、微分器等
  • 运算放大器电路的分析方法:虚短、虚断(负反馈条件下)

img

  • 运算放大器的输入端输入阻抗非常大,即同相和方向输入端电流都几乎为0(虚断)

# 四、运放电路

# 运放电路 (opens new window)

# 1、电压比较器

电压比较器 (opens new window)

这是电压比较器的作用,当+大于-的时候,输出VCC,当-大于+的时候,输出GDN。

img

img

# 2、反向放大器

通过分析虚短和虚段可以得到这个结论。

img

img

  • 接R2的那条线路,形成了一个负反馈,如图,如果IN输入了0.1V,因为+极接的是GND,所以-极电压大于+极,OUT输出负的最大(电压比较器),但因为负反馈的存在,这个输出的负的最大又会反过来把电压(0.1V)拉低,这时+极电压又会比-极大,OUT输出正的最大,然后又是负反馈拉高输入的电压,就这样不断使输出起到与输入相反的作用,使系统输出与系统目标的误差减小,系统趋于稳定,最后使电路达到一个稳态,(-/+都为0V),这样我们的电路就形成了虚短的状态。

  • 在电压比较器的两个输出端,因为运算比较器的输入阻抗非常大,即同相和反向输入端几乎都没有电流的输入和输出,这种情况我们就叫做虚断

  • 公式的计算过程:

    • 因为虚断和虚短,所以电流的方向就应该是从IN->R1->R2->OUT
      • 所以,经过R1和R2的电流 I 就是IN的电压(之后我们简称VIn),除以R1的电阻,这样就可得R2的电压为I*R2
      • 然后因为电流流向是从左到右,所以OUT的电压就是R2左边的电压减去R2的电压
      • 又因为虚短,可知R2左边的电压为0V,所以公式为0-VIn/R1*R2

# 3、同相放大器

img

img

# 4、电压跟随器

img

img

# 五、DA原理

# 1、T型电阻网络DA转换器

img

img

# 2、PWM型DA转换器

​ 这个的作用就是将交流滤掉,变成直流电压。

img

img

# 六、AD原理

# 1、逐次逼近型AD转换器

逐次逼近型AD转换器的原理就是通过DAC不断变换去和输入的电压进行比较,直到找到一个合适的电压,输出对应数字量就行。

img

# 2、AD/DA性能指标

  • 分辨率:指AD/DA数字量的精细程度,通常用位数表示。例如,对于5V电源系统来说,8位的AD可将5V等分为256份,即数字量变化最小一个单位时,模拟量变化5V/256=0.01953125V,所以,8位AD的电压分辨率为0.01953125V,AD/DA的位数越高,分辨率就越高
  • 转换速度:表示AD/DA的最大采样/建立频率,通常用转换频率或者转换时间来表示,对于采样/输出高速信号,应注意AD/DA的转换速度

# 七、XPT2046

# 1、功能说明

img

# 2、时序

​ CS作为片选,用来选择不同的设备,然后是DCLK上升沿为发送,下降沿为读出,DOUT是读出的值。

img

----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);//16位
		}
	}
	
	XPY2046_CS=1;
	if(Command & 0x08){  //判断选择的是几位的,如果是8位,那后面是补充了8个0,所以要右移8位
	return Data>>8;
	}
	else   //如果是12位的,就是补充了4个0,所以要右移4位
	return Data>>4;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

# 八、AD数模转换代码

------XPT2046.h

#ifndef __XPT2046_H__
#define __XPT2046_H__

#define XPT2046_VBAT	0xAC    //对应光敏电阻
#define XPT2046_AUX		0xEC
#define XPT2046_XP		0x9C	//也可以是0xBC,X+的意思,对应可调电阻
#define XPT2046_YP		0xDC	//Y+的意思,对应热敏电阻

unsigned int XPT2046_ReadAD(unsigned char Command);

#endif
1
2
3
4
5
6
7
8
9
10
11
12
13

AD数模装换

AD数模转换2

AD数模转换3

  • S必选1;

  • A0,A1,A2看下表

    • AD数模转换4
  • MODE看选择,上面代码给出的是8位模式,即MODE=1;

  • SER/—DFR,我们选单端模式(1),在需要触摸压力测试里就选差分模式(0);

  • PD1控制内部参考电压(2.5V)的开关,我们这里不使用内部参考电压,所以选了0;

  • PD0,老师说影响不大,1/0都行,选了0😥;

#ifndef __XPT2046_H__
#define __XPT2046_H__

#define XPT2046_VBAT	0xAC    //对应光敏电阻
#define XPT2046_AUX		0xEC
#define XPT2046_XP		0x9C	//也可以是0xBC,X+的意思,对应可调电阻
#define XPT2046_YP		0xDC	//Y+的意思,对应热敏电阻

unsigned int XPT2046_ReadAD(unsigned char Command);

#endif
1
2
3
4
5
6
7
8
9
10
11
  • 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);
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 九、DA数模转换

  • 这个不是特别理解和DA的关系😣
#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
	}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
编辑 (opens new window)
上次更新: 2023/09/13, 12:29:52
AT24C02存储器
DS18B20温度传感器

← AT24C02存储器 DS18B20温度传感器→

最近更新
01
51单片机及补充知识
09-13
02
独立按键
09-13
03
LCD1602液晶显示器
09-13
更多文章>
Theme by Vdoing | Copyright © 2019-2023 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式