51单片机实验五:A/D和D/A转换

一、实验环境与实验器材

环境:Keli STC-ISP 烧写软件 ,Proteus.

器材: TX-1C 单片机(STC89C52RC)、电脑。

二、 实验内容及实验步骤

1.A/D转换

**概念:**模数转换是将连续的模拟信号转换为离散的数字信号的过程。模拟信号是连续的,而数字信号是离散的,ADC 的作用就是对模拟信号进行采样和量化,将其转换为数字形式。

**需求:**用单片机控制ADC0804进行模数转换,当拧动实验板上A/D旁边的电位器Re2时,在数码管的前三位以十进制方式动态显示出A/D转换的数字量(8位A/D转换后数值在0~255变化)。

代码:

objectivec 复制代码
#include "reg52.h"				   // 52系列单片机头文件
#include "intrins.h"
#define  uchar unsigned char
#define uint unsigned int 
sbit dula=P2^6;					   // 申明U1锁存器的锁存端
sbit wela=P2^7;					   // 申明U2锁存器的锁存端
sbit adwr=P3^6;					   // 定义A/D的WR端口
sbit adrd=P3^7;					   // 定义A/D的RD端口
uchar code table[]={
	0x3f,0x06,0x5b,0x4f,
	0x66,0x6d,0x7d,0x07,
	0x7f,0x6f,0x77,0x7c,
	0x39,0x5e,0x79,0x71
};

void delayms(uint xms)
{
	uint i,j;
	for(i=xms;i>0;i--)				// i=xms即延时约xms毫秒
		for(j=110;j>0;j--);
}

void display(uchar bai,uchar shi,uchar ge)	// 显示子函数
{
	dula=1;
	P0=table[bai];				   // 送段选数据
	dula=0;
	P0=0xff;					   // 送位选数据前关闭所有显示,防止打开位选锁存时
	wela=1;						   // 原来段选数据通过位选锁存器造成混乱
	P0=0x7e;					   // 送位选数据
	wela=0;
	delayms(50);				   // 延时	

	dula=1;
	P0=table[shi];				
	dula=0;
	P0=0xff;					   
	wela=1;						   
	P0=0x7d;					   
	wela=0;
	delayms(50);


	dula=1;
	P0=table[ge];				
	dula=0;
	P0=0xff;					   
	wela=1;						   
	P0=0x7b;					   
	wela=0;
	delayms(50);
}

void main()					  // 主程序
{
	uchar a,A1,A2,A3,adval;
	wela=1;
	P0=0x7f;				 // 置CSAD为0,选通ADCS以后不必再管ADCS
	wela=0;
	while(1)
	{
		adwr=1;
		_nop_();			 // 延时一个机器周期
		adwr=0;
		_nop_();
		adwr=1;
	for(a=10;a>0;a--)			  //TX-1C实验班A/D工作频率较低,所以启动转换后
								  //要多留点时间用来转换
		{						  //把显示部分放这里的原因也是为了延长转换时间
			display(A1,A2,A3);
		}
		P1=0xff;				  //读取P1之前先给其写全1
		adrd=1;					  //选通ADCS
		_nop_();
		adrd=0;					  //A/D读使能
		_nop_();
		adval=P1;
		adrd=1;
		A1=adval/100;			  //分出百,十和个位
		A2=adval%100/10;
		A3=adval%10;
	}

}

图2.1.1 模数转化硬件效果1

图2.1.2 模数转化硬件效果2

Proteus仿真图:

图 2.1.3 模数转换proteus仿真图

因为延时过短原因,数码管一闪一闪显示107,我们可以调节变阻器RV1来使它的值变化

仿真视频:

AD转换

2.D/A 转换

**概念:**数模转换是将离散的数字信号转换为连续的模拟信号的过程。DAC 的作用是将数字信号还原为模拟信号。

**要求:**用单片机控制DAC0832芯片输出电流,让发光二极管D12由灭均匀变到亮,再由最亮均匀熄灭。在最亮和最暗时使用蜂鸣器分别警告一声,完成整个周期时间控制再5s左右,循环变化。

代码:

objectivec 复制代码
#include "reg52.h"
#define uchar unsigned char
#define uint unsigned int 
sbit dula=P2^6;
sbit wela=P2^7;
sbit dawr=P3^6;
sbit dacs=P3^2;
sbit beep=P2^3;

void delayms(uint xms)
{
	uint i,j;
	for(i=xms;i>0;i--)
		for(j=110;j>0;j--);	
}

void main()
{
	uchar val,flag;
	dula=0;
	wela=0;
	dacs=0;
	dawr=0;
	P0=0;
	while(1)
	{
		if(flag==0)
		{
			val+=5;
			P0=val;
			if(val==255)
			{
				flag=1;
				beep=0;
				delayms(100);
				beep=1;
			}
			delayms(50);
	}
	else
	{
		val-=5;
		P0=val;
		if(val==0)
		{
			flag=0;
			beep=0;
			delayms(100);
			beep=1;
		}
		delayms(50);
	  }
	}
}

图2.2.1 数模转换(最亮)

图2.2.2 数模转换(暗)

Proteus仿真:

图2.2.3 数模转换仿真图

不存在,有懂的兄弟评论区或私信帮忙一下。

图2.2.4 数模转换仿真图出错

三.简易版

1.A/D

通过 ADC(模数转换器) 读取模拟电压值,并将结果显示在 LCD1602 液晶屏 上。

objectivec 复制代码
#include "reg52.h"
sbit start=P3^0;
sbit eoc=P3^1;
sbit oe=P3^2;
sbit rs=P3^3;
sbit rw=P3^4;
sbit e=P3^5;
unsigned int vol=0;
unsigned char t[]={"0123456789"};
unsigned char str[]={"VOLTAGE:"};			// 显示更美观

void delay(unsigned int n)					// 延时函数
{
	unsigned int i,j;
	for(i=0;i<n;i++)
	{
		for(j=0;j<120;j++);
	}
}

void writedat(unsigned char dat)			// 写入数据 lm016
{
	rs=1;
	rw=0;
	e=0;
	P1=dat;
	delay(100);
	e=1;
	e=0;
}

void writecom(unsigned char com)
{
	rs=0;
	rw=0;
	e=0;
	P1=com;
	delay(100);
	e=1;
	e=0;
}

void initlcd()
{
	writecom(0x38);
	writecom(0x0c);
	writecom(0x06);
	writecom(0x01);
}

void adc()
{
	start=0;
	start=1;
	delay(100);
	start=0;
	while(eoc!=1);
	oe=1;
	vol=P2;
	oe=0;
}

void display()
{
	unsigned char temp0=0,temp1=0,temp2=0;
	int i;
	vol=vol*100/51;                 // 扩大一百倍显示小数,  5v时显示255,差了51倍。
	temp0=vol/100;
	temp1=(vol%100)/10;
	temp2=(vol%10);
	for(i=0;i<8;i++)
	{
		writedat(str[i]);
		delay(100);
	}
	writecom(0x80+0x40+4);
	delay(100);
	writedat(t[temp0]);
	delay(100);
	writedat('.');
	delay(100);
	writedat(t[temp1]);
	delay(100);
	writedat(t[temp2]);
	delay(100);
	writedat('V');
	delay(100);
}

void main()
{
	initlcd();
	while(1)
	{
		adc();
		display();
	}
	
}

proteus仿真:

存在误差

图3.1.1 A/D转换简易仿真图

演示视频:

ADC(模数转换器) 读取模拟电压值简易版AD转换

2.D/A

通过按键控制输出信号,并实现两种不同的输出模式:PWM 方波 和 阶梯波。

objectivec 复制代码
#include "reg52.h"
#define uint unsigned int
sbit key0=P1^0;
sbit key1=P1^1; 
uint value=100;
uint flag=0;

void delay(uint n)
{
	uint i=0,j=0;
	for(i=0;i<n;i++)
	{
		for(j=0;j<120;j++);
	}
}

void key()
{
	if(key0==0&&flag==0)
	{
		flag=1;
	}
	if(flag==1&&key0==1)
	{
		value+=50;
		flag=0;	
	}

	if(key1==0&&flag==0)
	{
		flag=1;
	}
	if(flag==1&&key1==1)
	{
		value-=50;	
		flag=0;
	}
}

void PWM()				 // 方波
{
	P2=0;
	delay(100);
	P2=255;
	delay(value);
}

void stair()
{
	uint i=0;
	for(i=0;i<255;i++)
	{
		P2=i;
		delay(1);
	}
		for(i=255;i>0;i--)
	{
		P2=i;
		delay(1);
	}
}

void main()
{
	while(1)
	{
		//PWM();
		stair();
		key();
	}

}

proteus仿真:

图3.2.1 D/A转换简易版仿真图

参考视频:知弦【Proteus电路仿真及应用(51单片机系列)】这位博主的51仿真视频讲的不错,博主都是从他这参考的。

相关推荐
国科安芯4 小时前
航天器多路并联大功率电源系统设计与ASP4644均流特性分析
单片机·嵌入式硬件·fpga开发·安全性测试
茯苓gao6 小时前
嵌入式开发笔记:CANopen相关移位运算与通信协议术语详解
网络·嵌入式硬件·学习·信息与通信
梁朝辉9 小时前
STM32H750VBT6中ADCINP与INN什么区别
stm32·单片机·嵌入式硬件
省四收割者10 小时前
一文详解信号完整性(1)
python·嵌入式硬件·数学建模·信息与通信·信号处理·智能硬件
崇山峻岭之间11 小时前
单片机无感FOC驱动之ADC
单片机·嵌入式硬件
Ligocious11 小时前
1.点亮一颗小小的LED
单片机·嵌入式硬件
KaifuZeng15 小时前
通信与接口协议面试八、CAN通信
单片机·嵌入式硬件·面试·通信与接口协议
智源单片机设计16 小时前
基于单片机的直流电机双闭环调速系统设计
单片机·嵌入式硬件
KaifuZeng1 天前
通信与接口协议面试一、基本概念
嵌入式硬件·通信与接口协议
wuyk5551 天前
24. C 语言模块化:不是拆几个.c 文件那么简单
c语言·开发语言·stm32·单片机