51单片机AD/DA

目录

前言

一、AD/DA简介

二、XPT2046型ADC

三、代码

总结



前言


        本篇要介绍的是电子硬件中最重要的手段之一——AD/DA,即模数转换/数模转换,这是单片机进行信号采集的重要途径之一。 

          

        在开发板的AD/DA模块上可以实现对光敏电阻,热敏电阻和旋转拨码器的数据读取。

一、AD/DA简介


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

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

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

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

        可以这样通俗的理解,AD就是电压表,它可以把模拟电压量化成数值,DA就是可调电源,可以根据输入的数值输出相应的电压。相较而言,AD的应用范围要远大于DA,日常开发中也是AD用的更频繁。

二、XPT2046型ADC


        以普中51单片机开发板为例,DAC其实就是在配置了PWM的引脚P2^1后面接了电压跟随器等驱动电路,输出的结果会反映到DA1这颗LED灯珠上,还可以通过J52引脚输出。

        它的AD模组使用的是这颗XPT2046的ADC芯片。XPT2046 是一款 4 线制电阻式触摸屏控制器,内部集成了一个12 位分辨率125KHz速率的逐次逼近型ADC。

         简单介绍下开发板ADC模块的原理图,左边是一个就是ADC芯片XPT2046,它有四个模拟信号输入引脚也就是AN0、AN1、AN2、AN3,可以输入四路模拟信号。芯片连接到单片机的3^4、P3^5、P3^6、P3^7引脚上,这里用的是SPI的通信方式,分别对应SPI的四根通信线,用SPI与单片机进行信息交流,单片机发送指令给XPT2046,后者把转换后的数字信号交给单片机处理。

        右边是AD转换采集的模拟量来源,AN0通道上是一个旋转编码器,通过转动旋转编码器改变内部阻值可以输出不同大小的电压,AN1通道上是一个热敏电阻,AN2通道上是一个光敏电阻,二者的模拟输入分别由10k和100k的电阻分压得到。

        电阻式DA的原理:

         这是个8位T型电阻网DA转换器,D0~D7分别是他的位权,数字量的输入范围是0~127,输出的模拟量取决于电流的大小,这样就可以对电压进行128等分量化,这就是DA的基本原理,之前的篇章里有介绍过PWM,其实PWM世界上也是DA的过程。

        逐次逼近型AD转换器:

        逐次逼近型的ADC内部需要一个DAC做衡量,简单来说就是,用比较器对ADC输入的电压值与DAC的各个位权电压做比较,逐步逼近目标的电压值。

三、代码


        DA的代码和之前介绍的PWM很相似,需要先配置一个定时器,设置好初值、重装载值和救计数方式,就会输出PWM波从而驱动LED灯亮暗变化。

#include <REGX52.H>
#include "Delay.h"
#include "Timer0.h"
//定义引脚
sbit DA=P2^1;   
unsigned char i;
unsigned char Counter,Compare;	//计数值和比较值,用于输出PWM
void Timer0_Init(void);
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
	}
}
void Timer0_Init(void)          //定时器0初始化
{
	TMOD &= 0xF0;		        //设置定时器模式
	TMOD |= 0x01;		        //设置定时器模式
	TL0 = 0x9C;		            //设置定时初值
	TH0 = 0xFF;		            //设置定时初值
	TF0 = 0;		            //清除TF0标志
	TR0 = 1;		            //定时器0开始计时
	ET0=1;
	EA=1;
	PT0=0;
}

          AD部分代码,将三路ADC的值分别存入缓存区再输出到LCD屏上,就可以得到温度,亮度和旋转编码器的旋转角度。

#include <REGX52.H>
#include <INTRINS.H>
//SPI引脚定义
sbit XPY2046_DIN=P3^4;            //DIN
sbit XPY2046_CS=P3^5;             //CS
sbit XPY2046_DCLK=P3^6;           //SCLK
sbit XPY2046_DOUT=P3^7;           //DOUT
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;
}
#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);
	}
}

总结


51单片机AD/DA

        关于这个AD和DA的详细原理不是三两句能说得清的,我理解的也不够深,只要知道它们的作用就好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

且看林地几华里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值