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仿真视频讲的不错,博主都是从他这参考的。

相关推荐
sagima_sdu1 小时前
【嵌入式八股11】STM32
stm32·单片机·嵌入式硬件
良许Linux2 小时前
如何系统地入门学习stm32?
stm32·单片机·学习
KaiGer6663 小时前
AUTOSAR图解==>AUTOSAR_SWS_EFXLibrary
单片机·汽车·嵌入式·autosar
li158172604145 小时前
FEMDRW032G-88A19江波龙 工规级/工业宽温级/车规级 eMMC 应用领域 车载系统、工控设备、智能终端等
嵌入式硬件·车载系统·云计算
the sun345 小时前
STM32各个外设和CortexM3内核的关系
stm32·单片机·嵌入式硬件
电子艾号哲5 小时前
STM32单片机入门学习——第42节: [12-2] BKP备份寄存器&RTC实时时钟
stm32·单片机·学习
云山工作室5 小时前
基于单片机的热释电红外报警器(论文+源码)
单片机·嵌入式硬件
A-花开堪折6 小时前
Qemu-STM32(十五):STM32F103加入Flash控制器
stm32·单片机·嵌入式硬件
正点原子2 天前
【正点原子STM32MP257连载】第四章 ATK-DLMP257B功能测试 #ADC测试 #DHT11测试
linux·stm32·单片机·嵌入式硬件