数据采集器的方案设计书实验报告Word格式.docx
- 文档编号:18260449
- 上传时间:2022-12-14
- 格式:DOCX
- 页数:21
- 大小:245.75KB
数据采集器的方案设计书实验报告Word格式.docx
《数据采集器的方案设计书实验报告Word格式.docx》由会员分享,可在线阅读,更多相关《数据采集器的方案设计书实验报告Word格式.docx(21页珍藏版)》请在冰豆网上搜索。
1、2、1、硬件电路
如图所示,ADC0808的时钟信号CLK由Proteus的虚拟信号源提供,时钟频率的设置为600kHz;
8路模拟量中IN0接Vcc,IN7接地,其他6路通过电位器分压获得;
单片机串行口的数据收发线与虚拟终端连接。
需要说明的是Proteus中ADC0808的数据线,OUT1表示最高位,OUT8表示最低位。
1、2、2、程序设计
程序的流程如图所示,主程序首先完成对串行口和外部中断的初始化,并等待上位机的采集命令,一旦收到采集命令,就启动对IN0的转换。
转换完成,ADC0808通过EOC向单片机发出中断请求,单片机响应中断,读取转换结果,并将其保存到数组adbuf中。
然后启动下一通道的转换,当8路模拟量全部采集完成时,主程序再将存放在数组adbuf中的8路数字量转换为ASCII码,通过串行口发送出去,为了能在虚拟终端上得到清楚的显示格式,相邻两路数字量之间输出空格码,每行显示8个数字量后,输出回车、换行码。
数据采集器的程序:
#include<
reg51.h>
absacc.h>
#defineuintunsignedint
#defineucharunsignedchar
ucharidataadbuf[8];
//存放A/D转换结果
uintaddr;
//IN0~IN7的通道地址
ucharn;
//通道计数
voidinit_serial(void)
{SCON=0x50;
//0101,00008位数据位,无奇偶校验
TMOD=0x20;
//定时器T1工作于方式2
PCON=PCON&
0x7f;
//SMOD=0
TH1=-3;
//装入时间常数,波特率为9600
TL1=-3;
TR1=1;
}/启动定时器T1
voidsend(uchardat)
{SBUF=dat;
while(TI==0);
TI=0;
}
voidint0(void)interrupt0
{adbuf[n]=XBYTE[addr];
//读取并保存当前转换结果
addr++;
//指向下一通道的地址
n++;
//计数器加工厂
if(n<
8)
XBYTE[addr]=0;
//启动对一一通道的转换
else
EX0=0;
voidgetadc(void)
{n=0;
addr=0x7ff8;
//指向IN0通道的地址
//启动对当前通道的转换
EX0=1;
//允许外部中断0中断
while(n<
8);
}//等待8路模拟量转换完成
voidmain()
{uchari;
init_serial();
//初始化串行口
IT0=1;
//外部中断0下降沿触发
EA=1;
//开中断
while
(1)
{while(RI==0);
//等待接收完一个字符
RI=0;
//清除接收标志
i=SBUF;
//读取收到的字符
if(i==0x41)
{getadc();
//依次完成对8个通道模拟量的转换
for(i=0;
i<
8;
i++)
{send(adbuf[i]/100+0x30);
//发送百位的ASCLL码
adbuf[i]=adbuf[i]%100;
send(adbuf[i]/10+0x30);
//发送十位的ASCLL码
send(adbuf[i]%10+0x30);
//发送个位的ASCLL码
send(0x20);
//发送空格码
}
send(0x0d);
//发送回车、换行
send(0x0a);
}
1、2、3、调试方法与步骤
在Keil下建立项目,输入源程序,编译后进入调试方式全速运行,在虚拟终端的窗口中输入大写字母“A”,此时8路模拟量转换结果会在一行中显示出来,依次为IN0、IN1、…、IN7,由于IN0接+5V,IN7接地,因此对应的显示值为255和000,而IN1~IN6的值由电位器RV1中心抽头的位置确定,调节RV1,然后在虚拟终端的窗口中输入大写字母“A”,IN1~IN6的值将随之变化。
如果在虚拟终端的窗口无任何显示,首先应检查串行口的初始化是否正确、虚拟终端的波特率是否与串行口一致、串行口能否收到采集命令“A”。
如果串行口能收到采集命令,应检查外部中断的初始化是否正确、启动信号START、转换结束信号EOC、输出允许信号OE的连接是否正确,ADC0808的时钟CLOCK设置不正确,也将无法完成A/D转换。
如果程序能够将IN0~IN7的转换结果存入数组adbuf,应重点检查串行口数据发送函数send()。
2、数字电压表的设计
2、1、8位串行A/D转换器TLC549
REF+
REF-
AIN
CS
CLK
DO
TLC549内部结构
2、2、数字电压表的设计过程
利用TCL549转换器设计一个简易数字电压表,用4位LED显示器将被测电压显示出来,测量范围为0.000~5.000V(电路连接:
将ACS、ACLK、ADO分别与P10~P12相连)。
2、2、1、硬件电路
如图所示,将TLC549的CS、CLK、DO接到单片机的三条I/O口线,REF+、REF-直接接到Vcc、GND,模拟输入AIN接电位器的中心抽头,调节电位器即或改变被测输入电压值。
2、2、2程序设计
程序首先读取A/D转换结果存入adin,其值在0~255之间,对应的电压值u=adin/255*5000(mV),然后将u转换为4位BCD码送显示缓存,并调用显示程序将显示出来,小数点固定在最高位。
数字电压表的设计程序:
#defineulongunshgnedlong
ucharcodesegtab[]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89,0x8c,0xff};
uchardbuf[4]={0,0,0,0};
sbitAD_CS=P1^0;
sbitAD_CLK=P1^1;
sbitAD_DAT=P1^2;
bdataucharadin;
sbitadin0=adin^0;
voiddelay(void)
20;
i++);
uchargetad(void)//A/D转换程序
AD_CS=0;
//令CS为低选中TLC549
delay();
//延时
i++)//循环读取8位A/D转换结果
{AD_CLK=0;
//令CLK引脚为低
adin=adin<
<
1;
//先读取高位,后读取低位
adin=AD_DAT;
//读取数据线的一位数据
AD_CLK=1;
}//令CLK恢复为高位
AD_CS=1;
returnadin;
voiddisp(void)
{uchari,n,bsel;
bsel=0xfe;
//首先点亮最低位
for(n=0;
n<
4;
n++)
{P2=bsel;
//位选口
P0=segtab[dbuf[n]];
//将显示缓存的数据转换为字段码显示
if(n==3)P0=P0&
//点亮最高位的小数点
bsel=(bsel<
1)+1;
//准备显示下一位
for(i=1;
200;
P0=0xff;
}//熄灭所有字段
{ulongu;
uchari;
{u=(ulong)getad()*5000/255;
//将转换结果换成电压值
3;
i++)//转换为4位BCD码送显示缓存
{dbuf[i]=u%10;
u=u/10;
dbuf[3]=u;
disp();
}//显示电压值
2、2、3、调试方法
在Keil下建立项目,输入源程序,编译后进入高度方式全速运行,数码管将以“X.XXX”的格式显示当前测量的电压值,调节电位器,数码管上的电压值将随之而变化。
如果数码管没有显示,应首先检查显示及显示函数。
注意,将电压值u转换成BCD码送显示缓存如果出问题,也会影响显示结果。
如果数码管能正常显示,但显示的电压值与实际值不同,一般A/D转换程序有问题,可重点检查getad()函数,如果电位器W的中心抽头从最低调到最高,该函数返回的A/D转换结果也相应地由0x00变化到0xFF,说明A/D转换是对的,应检查语句“u=(ulong)getad()*5000/255;
”以及随后的BCD码转换程序。
3、信号发生器的设计
3、1、串行D/A转换器TLC5615
REFIN
AGND
SCLK
DIN
DOUT
OUT
TLC5615内部结构
3、2、用TLC5615设计信号发生器的过程
3、2、1、在Proteus环境下,用TLC5615设计一个锯齿波发生器。
(1)、硬件电路
如图所示,将TLC5615的SCLK、CS、DOUT分别与单片机的P1.0、P1.1、P1.2相连,基准电压接+5V。
(2)、程序设计
为了产生锯齿波,可定义一个用于计数的字符变量n,其值由0开始加1,每次加1后就将其输出,由TLC5615转换为相应的电压值,当n为255时,再加1又回到0,这样就实现了一个周期的转换。
程序如下:
#include<
intrins.h>
sbitSCLK=P1^0;
//时钟输入
sbitCS=P1^1;
//片选信号
sbitDIN=P1^2;
//串行数据输入
voiddatout(uintdat)//向TL5615输出16位数据
CS=1;
//初始化片选信号为高
SCLK=0;
//初始化时钟为低
CS=0;
//选中TL5615
16;
{dat=dat<
//将最高位移入进位位CY
DIN=CY;
//将数据送到DIN引脚
SCLK=1;
//SCLK产生上升沿
}//SCLK恢复为低
CS=1;
}//片选信号恢复为高
voidmain(void)
{uchari=0;
{i=i++;
datout(i<
2);
在Keil下建立项目,输入源程序,编译后进入调试方式全速运行,示波器显示的波形如图所示。
1、在Proteus环境下,设计一个正弦波发生器。
ucharcodewavetab[60]={
0x80,0x8D,0x9A,0xA7,0xB4,0xBF,0xCB,0xD5,
0xDF,0xE7,0xEE,0xF4,0xF9,0xFD,0xFF,0xFF,
0xFF,0xFD,0xF9,0xF4,0xEE,0xE7,0xDF,0xD5,
0xCB,0xC0,0xB4,0xA7,0x9A,0x8D,0x80,0x72,
0x65,0x58,0x4C,0x40,0x34,0x2A,0x21,0x18,
0x11,0x0B,0x06,0x02,0x00,0x00,0x00,0x02,
0x06,0x0A,0x10,0x18,0x20,0x2A,0x34,0x3F,
0x4B,0x58,0x65,0x72};
voiddatout(uintdat)
}//SCLK恢复为低
}//片选信号恢复为高}
{uinti=0;
60;
i++)//从波表读取数字量输出
datout(wavetab[i]<
运行程序,Proteus的虚拟示波器将观察到如图所示的波形。
4、频率与周期的测量
4、1、频率的测量
4、1、1、频率测量的过程
在Proteus环境下,设计的频率计电路如图所示,将定时器T0设置在定时方式2,定时时间为250us,满4000次中断正好1s,定时器T1工作于计数方式1,其初值为0。
在启动定时器T0开始定时后,随即送到T1(P3.5)引脚的被测脉冲进行计数,当T0定时满1s后,立即停止T1计数,关闭定时器T0,T1的计数值即为被测信号的频率。
频率测量模块的程序:
reg52.h>
externvoidinit_lcd(void);
externvoiddisp_str(ucharx,uchary,uchar*p);
sbitFS=P3^5;
//被测信号FS输入端
bitRDY=0;
//测量完成标志
uintmsn;
//定时中断计数
uintcount(void)//测量FS的频率
{RDY=0;
TMOD=0X5a;
//T0:
定时方式2,T1:
计数方式1;
TH0=TL0=-250;
//T0定时时间为250us
msn=4000;
//4000次中断正好1s
TH1=TL1=0X00;
//T1工作于计数方式,初值为0
ET0=1;
//允许T0中断
//开中断
while(FS==1);
//等待被测信号变低
while(FS==0);
//等待被测信号变高
TR0=1;
//T0开始定时
//T1开始计数
while(RDY==0);
//等待1s
TR1=0;
//关闭T1、T0
TR0=0;
return(TH1*256+TL1);
//返回计数值
voidtimer0(void)interrupt1using1
{msn--;
if(msn==0)//如果1s已到
RDY=1;
}//设置测量完成标志位
{uintf;
ucharstr[9]="
f=Hz"
;
init_lcd();
//液晶屏初始化
{f=count();
//测量频率
_nop_();
for(i=6;
i>
2;
i--)//测量结果转换为5位ASCII码
{str[i]=f%10+0x30;
f=f/10;
str[2]=f+0x30;
for(i=2;
6;
i++)//用空格码替换高位的0
{if(str[i]!
='
0'
)break;
str[i]='
'
disp_str(0,3,str);
}//显示测量结果
液晶显示模块1602DRV.C:
#defineuintunsignedint
sbitRS=P3^3;
//数据/命令寄存器选择控制端
sbitRW=P3^1;
//读写控制端
sbitE=P3^0;
//使能控制端
sfrLCD=0x80;
//P0作为总线端口
sbitBF=LCD^7;
//就绪线BF,低电平有效
voidlcd_cmd(ucharcmd)//向液晶屏发送指令
{LCD=cmd;
RS=0;
RW=0;
E=1;
_nop_();
E=0;
while
(1)
{LCD=0xff;
RW=1;
if(BF==0)break;
voidlcd_dat(uchardat)//向液晶屏写入数据
{LCD=dat;
RS=1;
dat=LCD;
voidinit_lcd(void)//初始化液晶屏
{lcd_cmd(0x01);
//清屏幕
lcd_cmd(0x3c);
//设置双行显示,5*10点阵
lcd_cmd(0x0c);
}//开显示,关闭光标
voiddisp_str(ucharx,uchary,uchar*p)//在x行、y列显示字符串p
{if(x==0)
lcd_cmd(0x80+y);
//设置写入地址
else
lcd_cmd(0xc0+y);
while(*p)//将字符依次发送到液晶屏
lcd_dat(*p++);
(3)、调试方法
将被测信号FS用Proteus的虚拟信号源DCLOCK代替,设置其频率,切换以Keil下,全速运行程序,此时液晶屏的显示将如图所示。
停止程序的运行,回到Proteus修改DCLOCK的频率,再次切换到Keil下运行程序,液晶屏上的测量结果将随之变化。
如果液晶屏没有显示,可将语句“f=count();
”注销,然后再编译运行,如果仍没有显示,就检查1602DRV.C模块中I/O口的定义是否与线路一致,直到能正常显示时,再将注销的
语句恢复。
如果液晶屏仍没有显示,说明调用count()函数没有返回,可能是RDY变量始终无效,此时应检查定时器T0的初始化是否正确,电路的连接有无错误。
4、2、周期的测量
4、2、1、周期测量的过程
在Proteus环境下,用定时器/计数器测量周期的电路如图所示,用D触发器对被测量信号进行分频,这要周期的测量也变成了脉宽的测量。
(2)、程序设计(液晶屏显示模块程序与频率测量模块一样)
周期测量模块程序:
sbitCLR=P1^0;
//触发器清0控制位
uintTs;
//存放测量结果
//测量就绪标志
voidcontrol(void)
{IT0=1;
//下降沿触发INT0
//允许外部中断0中断
TH0=0;
//定时器初值为0
TL0=0;
TMOD=0x09;
//定时器T0工作方式1,由TR0及INT0控制T0定时启停
CLR=0;
CLR=1;
//D触发器清0
//允许T0定时
}//开中断,由被测信号的上升沿启动定时
voidint_0(void)interrupt0using1
{TR0=0;
//关闭定时器T0
EA=0;
//关中断
Ts=TH0*256+TL0;
{ucharstr[9]="
T=us"
//用于测量结果输出
{control();
//初始化定时器及中断
//等待INT0引脚下降沿
RDY=0;
{str[i]=Ts%10+0x30;
Ts=Ts/10;
str[2]=Ts+0x30;
将被测信号FS用Proteus的虚拟信号源DCLOCK代替,设置其周期,如图所示,切换到Keil下,全速运行程序,此时液晶屏的显示将如图所示。
停止程序的运行,回到Proteus修改DCLOCK的周期,再次切换到Keil下运行程序,液晶屏上的测量结果将随之变化。
如果液晶屏没有显示,但将语句“while(RDY==0);
”注销后能够显示,说明测量电路或程序有问题;
如果D触发器的Q端没有波形输出,就不会产生中断,RDY将始终为0,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据 采集 方案设计 实验 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)