一、实验环境与实验器材
环境:Keli,STC-ISP烧写软件,Proteus.
器材:TX-1C单片机(STC89C52RC)、电脑。
二、 实验内容及实验步骤
1.A/D转换
概念:模数转换是将连续的模拟信号转换为离散的数字信号的过程。模拟信号是连续的,而数字信号是离散的,ADC 的作用就是对模拟信号进行采样和量化,将其转换为数字形式。
需求:用单片机控制ADC0804进行模数转换,当拧动实验板上A/D旁边的电位器Re2时,在数码管的前三位以十进制方式动态显示出A/D转换的数字量(8位A/D转换后数值在0~255变化)。
代码:
#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左右,循环变化。
代码:
#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 液晶屏 上。
#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 方波 和 阶梯波。
#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仿真视频讲的不错,博主都是从他这参考的。