基于单片机的数模转换设计文档格式.docx
《基于单片机的数模转换设计文档格式.docx》由会员分享,可在线阅读,更多相关《基于单片机的数模转换设计文档格式.docx(28页珍藏版)》请在冰点文库上搜索。
独立式按键。
独立按键的输入线较多,结构复杂,一般适用于按键较少,操作速度较高的场合。
行列式键盘。
行列式键盘由行和列线交叉组成,一般适用于按键较多的场合。
使用2×
2矩形键盘,这样键盘模块仅使用8根线与处理器相连,节省了系统资源。
由于我们功能比较少,矩形键盘占用电路板位置较大,因此选择方案一。
1.1.4排阻形式选择与论证
方案一:
多个单个电阻。
个数多,接线困难,误差大。
且浪费资金。
方案二:
排阻。
数量少,接线容易,价格便宜。
由于本次试验本身对接线要求就高,所以采用方案二。
1.1.5、材料选择与论证
方案一:
塑料板。
塑料板质量轻,不易碎,但是也不好加工,且不环保。
方案二:
木板。
木板质量比塑料板重,但比玻璃板轻,易于加工,可塑性强。
由于本次试验对材料的可塑性要求较高,因此采用方案二。
1.2所选器件的分析
1.2.1STEC89C51
引脚图如下:
1.2.2LED显示屏
1.2.3LM324
2理论分析与计算
2.1、D/A转换器的主要技术指标
1.分辨率
分辨率用于表征D/A转换器对输入微小量变化的敏感程度。
①D/A转换器模拟输出电压可能被分离的等级数--可用输入数字量的位数n表示D/A转换器的分辨率;
②可用D/A转换器的最小输出电压与最大输出电压之比来表示分辨率。
2.转换精度
D/A转换器的转换精度是指输出模拟电压的实际值与理想值之差,即最大静态转换误差。
3.输出电压(或电流)的建立时间(转换速度)
从输入的数字量发生突变开始,到输出电压进入与稳定值相差±
0.5LSB范围内所需要的时间,称为建立时间tset。
目前单片集成D/A转换器(不包括运算放大器)的建立时间最短达到0.1微秒以内。
4.温度系数
在输入不变的情况下,输出模拟电压随温度变化产生的变化量。
一般用满刻度输出条件下温度每升高1℃,输出电压变化的百分数作为温度系数。
2.2.1权电阻网络DAC的原理分析
集成运算放大器,作为求和权电阻网络的缓冲,并将电流转换为电压输出。
开关Si的位置受数据锁存器输出的数码di控制:
当di=1时,Si将对应的权电阻接到参考电压UREF上;
当di=0时,Si将对应的权电阻接地。
虚短
运算放大器总的输入电流为
虚断
运算放大器输出电压为
令RF=R/2,则
即:
输出的模拟电压uO正比于输入的数字量Dn,从而实现了从数字量到模拟量的转换。
当Dn=Dn-1…D0=0时,uO=0;
当Dn=Dn-1…D0=11…1时,
权电阻网络D/A转换器的特点
①优点:
结构简单,电阻元件数较少;
②缺点:
阻值相差较大,制造工艺复杂。
3、电路与程序设计
3.1.1、总体框图设计
系统总体框图如图所示
3.1.2、显示电路
LED显示屏与传统的CRT相比,LED不但体积小,厚度薄,耗能少(1到10微瓦、平方厘米),工作电压低(1.5到6v)能与集成电路直接连用。
并且在与集成电路焊接是比数码管接线简单。
容易操作。
3.1.3、权电路
1、权电阻网络D/A转换器电路
权电阻网络D/A转换器电路如下图所示,它由理想运算放大器、电阻网络、电子模拟开关等组成。
当di=1时(i=0,1,2,3),电子模拟开关接VREF,当di=0时,电子模拟开关接地。
3.1.4、按键电路
此电路实现四种不同功能的转换。
按键一实现平板旋转360°
功能,按键二实现一枚硬币平衡摆动的功能,按键三实现八枚硬币平衡摆动的功能,按键四实现始终指向一点的功能。
电路图如图。
图按键电路
3.1.5、驱动电路
本次的电路主要是有程序通过AT89C51驱动的。
显示电路是由P0口和P2.0;
P2.1;
P2.2口驱动的。
权电路是由P1口来驱动的。
输出电路是由单片机通过权电路驱动。
3.1.6、输出电路
电路经过输入的数字电路通过单片机的程序,输出通过权电路,然后2R½
等比分流,再通过LM324输入给电压表。
3.1.7、总电路
3.2、程序流程图
系统初始
按键按下
单片机检测按键
启动D/A转换
电压放大输出
显示电压值
结束
图程序流程图
3.2.2、液晶显示子程序流程图
图液晶显示流程图
图所示的程序用来显示为调节电压。
3.2.3、输出电路程序流程图
单片机输出的数据
DAC输出
频率增加
判外部中断2
判外部中断
退出波形输出等待按键命令
N
Y
图LM324工作流程图
4、测试方案与测试结果
4.1、测试方案
基本要求:
此次试验是通过软件程序和硬件搭建电路实现。
通过按键电路对显示电路数字显示分别输入0V,1V,2V,3V,4V.此时,通过转换电路后读出电压表的显示示数。
观察计算误差。
4.2、测试结果与测试分析
测量结果:
在允许的误差范围内,观察电压表的示数。
如果误差超过了允许的范围,我们先对硬件电路进行排查分析,进行对电路的数据分析,最后到软件程序的分析。
附录
附录1:
电路原理图
附录2:
源程序
#include<
reg51.h>
#defineucharunsignedchar
#defineuintunsignedint
sbitlcdrs=P2^0;
sbitlcdwr=P2^1;
sbitlcden=P2^2;
sbitS1=P2^4;
sbitS2=P2^5;
sbitS3=P2^6;
sbitS4=P2^7;
ucharcodePresetDat[]={"
SHURU:
0.00V"
};
ucharcodeCurrentDat[]={"
MadeByJbms:
ucharcount,S1num,V_point,V_ge,V_shi,I_point,I_ge,I_shi;
ucharS1_OK=0,Confirm=0,DA,VCC,Power;
//ucharlcd_read_dat();
//////////////////延时1ms子程序开始//////////////
voiddelay(uintz)
{
uintx,y;
for(x=0;
x<
121;
x++)
for(y=0;
y<
z;
y++);
}
//////////////////延时1ms子程序结束///////////////
/******写指令子函数******************/
voidlcd_write_com(ucharcom)
lcdrs=0;
//lcdrs=0即设置写指令状态
lcdwr=0;
//写状态
lcden=0;
//从这句开始将en置1然后又置零,是将其显示为高脉冲
P0=com;
//将要写的指令传给P0口
delay(5);
lcden=1;
//en的高脉冲设置完毕
/******写数据子函数******************/
voidlcd_write_dat(ucharx_pos,uchary_pos,uchardat)
x_pos&
=0x0f;
//X位置范围0~15//
y_pos&
=0x01;
//Y位置范围0~1//
if(y_pos==1)x_pos+=0x40;
x_pos+=0x80;
lcd_write_com(x_pos);
lcdrs=1;
//lcdrs=1即设置写数据状态
P0=dat;
//将要写的数据传给P0口
/*******************初始化子函数**************/
voidlcd_init()
ucharnum;
lcd_write_com(0x38);
//显示16×
2,5×
7点阵,8位数据接口。
lcd_write_com(0x0c);
//显示开/关及光标设置
lcd_write_com(0x06);
//设置读写一个字符后指针自动加1或减1及整屏左移动
lcd_write_com(0x01);
lcd_write_com(0x80);
//设置数据指针位置,即从什么位置开始显示,
for(num=0;
num<
14;
num++)
{
lcd_write_dat(num,0,PresetDat[num]);
}
lcd_write_com(0x80+0x40);
//设置数据指针位置
lcd_write_dat(num,1,CurrentDat[num]);
ucharkeyscan()//等待调时间的子函数,S1S2S3为功能键按,S1闪烁调整位置的功能键,S2增加1,S3减少1
if(S1==0)
//键盘按键消抖
if(S1==0)
S1num++;
//S1增加功能键按下的次数
while(!
S1);
//按键松手检测
if(S1num==1)
{
lcd_write_com(0x80+11);
lcd_write_com(0x0f);
//光标闪烁,表示可以调整时间
if(S1num==2)//如果S1即第二次按下,光标向前移动
lcd_write_com(0x80+10);
if(S1num==3)//如果S1即第三次按下,光标向前移动
lcd_write_com(0x80+8);
if(S1num==4)//如果S1即第四次按下,光标向前移动
lcd_write_com(0x80+0x40+11);
if(S1num==5)//如果S1即第五次按下,光标向前移动
lcd_write_com(0x80+0x40+10);
if(S1num==6)//如果S1即第六次按下,光标向前移动
lcd_write_com(0x80+0x40+8);
if(S1num==7)//如果S1即第七次按下,则定时器开始计时,S1num清零,光标不闪烁
S1num=0;
S1_OK=1;
}
if(S1num!
=0)
if(S2==0)
if(S2==0)//在S2按下时,实现加1调整
S2);
//电压增加调整
V_point++;
if(V_point==10)
V_point=0;
lcd_write_dat(11,0,0x30+V_point);
if(S1num==2)
V_ge++;
if(V_ge==10)
V_ge=0;
lcd_write_dat(10,0,0x30+V_ge);
if(S1num==3)
V_shi++;
if(V_shi==6)
V_shi=0;
lcd_write_dat(8,0,0x30+V_shi);
//电流增加调整
if(S1num==4)
I_point++;
if(I_point==10)
I_point=0;
lcd_write_dat(11,1,0x30+I_point);
if(S1num==5)
I_ge++;
if(I_ge==10)
I_ge=0;
lcd_write_dat(10,1,0x30+I_ge);
if(S1num==6)
I_shi++;
if(I_shi==6)
I_shi=0;
lcd_write_dat(8,1,0x30+I_shi);
if(S3==0)//在S3按下时,实现减1调整
//电压减少调整
if(S3==0)
S3);
V_point--;
if(V_point==-1)
V_point=9;
V_ge--;
if(V_ge==-1)
V_ge=9;
V_shi--;
if(V_shi==-1)
V_shi=5;
//电流减少调整
I_point--;
if(I_point==-1)
I_point=9;
I_ge--;
if(I_ge==-1)
I_ge=9;
I_shi--;
if(I_shi==-1)
I_shi=5;
Power=1*V_shi+0.1*V_ge+0.01*V_point;
return(Power);
voidmain()
lcd_init();
P0=0;
while
(1)
VCC=keyscan();
if(!
S4)
if(VCC>
5.00)
VCC=5.00;
P0=10*VCC+1*V_ge+0.1*V_point;