C语言测控系统程序设计实验报告文档格式.docx
- 文档编号:22428403
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:21
- 大小:559.46KB
C语言测控系统程序设计实验报告文档格式.docx
《C语言测控系统程序设计实验报告文档格式.docx》由会员分享,可在线阅读,更多相关《C语言测控系统程序设计实验报告文档格式.docx(21页珍藏版)》请在冰豆网上搜索。
设计思路
1.如何实现任意时间间隔?
(附程序流程图)
时间间隔的选取是根据用户的需要来进行的,因此程序首先应该是要求用户输入时间间隔T(ms),设定了8254的通道0定时器的计数初值,再通过将计数初值先写低8位后写高8位的方式来初始化通道0。
代码实现为:
通过CalIPara()函数来计算计数初值的高低8位:
voidCalIPara(doubleDTimeI,int*ILongCount,unsignedchar*CL8,unsignedchar*CH8)
{
doubleTotalCounter=DTimeI*1193;
intResidue;
ILongCount[0]=TotalCounter/65536;
Residue=TotalCounter-65536*ILongCount[0];
CH8[0]=Residue>
>
8;
CL8[0]=Residue&
0x0FF;
}
通过SetupTimerInterrupt()函数来对8254的通道0定时器的初始化:
voidSetupTimerInterrupt(void)
disable();
oldint8=getvect(0x08);
outportb(0x43,0x36);
if(LongCount==0)
{
outportb(0x40,L8);
outportb(0x40,H8);
}
else
outportb(0x40,0x00);
setvect(0x08,myint8);
enable();
这样,每隔T(ms)时间,8259A的中断请求信号引起中断服务的执行。
时间间隔是由用户自己选择的,因此这样的设计能够实现任意时间间隔。
程序流程图如下:
2.如何设计显示信息便于验证定时的正确性?
(文字表述及必要的代码)
在验证的Proecess()函数中,加入printf(),实现每次中断中都打印当前的中断次数,然后通过观察在一定时间段内的中断次数来计算时间间隔,对比设计的初值,这样可以准确地验证定时的正确性。
代码如下:
intIndex;
Index=CINum;
printf("
%d"
Index);
3.如何实现错误提示?
在主函数中,在用户每输入完一项数据后都进行循环判断,若输入不符合要求,则循环要求用户重新输入,直到输入符合要求的数据。
printf("
Pleaseinputtimeintervalofinterruptevents(milisecond):
\n"
);
do
scanf("
%le"
&
TimeI);
if(TimeI<
0.001||TimeI>
5000)
{
getchar();
printf("
\nInputerror!
Pleaseinputagain:
"
}
else
break;
}while
(1);
Pleaseinputthetimesofinterrupt(0toendless):
do
%d"
INum);
if(INum<
0)
4.如何实现按键停止定时中断服务?
(文字表述及必要的代码)
若用户输入的中断次数为0,或已执行中断次数小于用户输入的中断次数,中断将会一直执行,直到用户对键盘上的设定按键来停止中断。
即通过kbhit()函数获取按键信号,通过bioskey(0)函数获得键值。
在中断函数myinterrupt08()中获得按键和其键值:
if(kbhit())
EndStroke=bioskey(0);
在主函数中判断按键属性:
if(InterruptNum==0)
while
(1)
/*PressStostop*/
if(EndStroke==8051)break;
else
while(CurrentInterruptNum<
InterruptNum)
5.程序编写过程中遇到过的问题及解决办法。
出现的问题:
在实现错误提示过程中,使用do-while函数进行循环判断时,错误输入数据后程序进行死循环,没有出现相应的输入提示。
解决办法:
事实证明由于没有进行相关函数的缓冲,因此通过同学的帮忙在do-while函数增加getchar()函数对输入进行缓冲,即可解决这个问题。
程序运行结果截图(不同运行参数条件下)
1.中断时间T=10ms,中断次数N=100,程序运行如下:
2.中断时间T=20ms,中断次数N=0,通过“s”键停止中断,程序运行如下:
3.中断时间T=-10ms,中断次数N=-10,查看错误提示;
修正后中断时间T=30ms,中断次数N=1000,通过“s”键停止中断,程序运行如下:
实验二数据处理与绘图程序设计
1.掌握数据文件的建立、存储和读取方法。
2.掌握C语言绘图程序设计方法。
3.掌握DosBox的使用方法。
PC机,WinXP操作系统,TurboC2.0,DosBox
程序运行前,配置数据文件(包括中断服务的时间间隔T,中断服务次数N,正弦曲线的振幅、周期,坐标系在屏幕上的位置,横(时间)纵(幅度)坐标显示范围及刻度等),运行后,首先,在屏幕上设定位置绘制坐标系,然后每间隔指定的时间生成设定的正弦曲线上的一个点,保存到指定数据文件并绘制在坐标系里,超过横坐标显示范围后,会滚动显示,显示N个点后,则曲线停止,如果N=0,则会无限显示下去,直到在键盘上按下指定的按键,才停止显示。
1.横坐标标注为时间,纵坐标标注为幅度。
2.曲线动态显示
3.配置文件如有错误要能提示,不会造成程序运行报系统错误。
6.后面的数据采集要在此程序基础上编程、添加代码,注意程序的结构。
1.如何实现配置文件参数的读取?
通过编写Setup.txt文件来实现,其中文件内容根据回车分行,依次为坐标系在屏幕上的位置、横(时间)纵(幅度)坐标显示范围及刻度、参考横线、网格、中断时间间隔及中断次数。
具体说明如下图:
读取文件数据时,采用fscanf()函数读取,通过ReadSetupFromFile()函数实现,代码如下:
voidReadSetupFromFile(void)
FILE*fp1;
fp1=fopen("
D:
\\Setup.txt"
"
r"
fscanf(fp1,"
%d,%d,%d,%d\n"
IWXMin,&
IWXMax,&
IWYMin,&
IWYMax);
%le,%le,%le,%le\n"
DXMin,&
DXMax,&
DYMin,&
DYMax);
%le,%le\n"
DXStep,&
DYStep);
%le\n"
DReferenceLine);
%d\n"
IGrid);
fclose(fp1);
2.如何编写绘制坐标系的子程序?
首先,设计GetScreenX()函数、GetScreenY()函数以及GetInterval()函数来实现将用户配置的坐标系显示范围与刻度转化为实际屏幕上的点的位置的功能,然后根据坐标系在屏幕上的位置求出首尾点,通过画直线将坐标系画出来,即由DTrail()函数来实现,代码如下:
intGetScreenX(doubleRealX,intWXMin,intWXMax,doubleXMin,doubleXMax)
intWX=(WXMax-WXMin)/(XMax-XMin)*(RealX-XMin)+WXMin;
returnWX;
intGetScreenY(doubleRealY,intWYMin,intWYMax,doubleYMin,doubleYMax)
intWY=WYMax-(WYMax-WYMin)/(YMax-YMin)*(RealY-YMin);
returnWY;
intGetInterval(doubleRealInterval,intWRegion,doubleRegion)
intInterval=WRegion/Region*RealInterval;
returnInterval;
/*Drawthetrail*/
voidDTrail(intWXMin,intWXMax,intWYMin,intWYMax,doubleXMin,doubleXMax,doubleYMin,doubleYMax,doubleXStep,doubleYStep,doubleRefLine,intGrid)
charLabel[10];
intWYRefLine;
intWDot;
intDot;
inti;
/*Drawtheframe*/
line(WXMin,WYMin,WXMax,WYMin);
/*top*/
line(WXMin,WYMin,WXMin,WYMax);
/*left*/
line(WXMin,WYMax,WXMax,WYMax);
/*Bottom*/
line(WXMax,WYMin,WXMax,WYMax);
/*right*/
/*Drawreferenceline*/
WYRefLine=GetScreenY(RefLine,WYMin,WYMax,YMin,YMax);
line(WXMin,WYRefLine,WXMax,WYRefLine);
gcvt(RefLine,5,Label);
outtextxy(WXMax+1,WYRefLine-2,Label);
/*DrawXStep*/
i=0;
while
(1)
Dot=XMin+i*XStep;
WDot=GetScreenX(Dot,WXMin,WXMax,XMin,XMax);
if(WDot>
WXMax)
if(Grid==1)
line(WDot,WYMin,WDot,WYMax);
line(WDot,WYMax,WDot,WYMax-5);
gcvt(Dot,5,Label);
outtextxy(WDot-5,WYMax+8,Label);
i++;
/*DrawyStep*/
Dot=YMin+i*YStep;
WDot=GetScreenY(Dot,WYMin,WYMax,YMin,YMax);
if(WDot<
WYMin)
line(WXMin,WDot,WXMax,WDot);
line(WXMin,WDot,WXMin+5,WDot);
if(Dot<
outtextxy(WXMin-30,WDot-2,Label);
outtextxy(WXMin-20,WDot-2,Label);
3.如何保存数据文件,数据文件的格式?
读取文件数据后先提示输入保存数据文件名称,将模拟得到的数据保存在该文件中,保存数据时,采用文件写入功能,加制表符分割,将数据写入。
格式如图所示:
fprintf(fp,"
%d\t%d\t%le\t%le\n"
Index,IData,RealTime,DData);
4.如何将生成的正弦数据动态显示成曲线?
每次的中断过程中,根据中断时间和当前中断次数计算出当前时间,代入到模拟的数据采集正弦函数中,则可求得当前点的纵坐标,再根据已有的前一点数据,连接两点得到一较短线段,当时中断次数较大时,就能够打正弦曲线绘制出来,由于中断过程是不断进行的,因此在坐标系上看实现了动态效果。
同时,实际中使用中可能会出现幅值超过坐标显示范围的部分,因此对这部分也需要进行一定的处理,因此,考虑到超出部分是由于坐标系的Y轴坐标不够大,这可以对Setup.txt文件中进行相应的修改即可,因此超出坐标轴的部分不进行显示,如:
有线段的一部分在显示范围内,一部分在坐标范围外,即采取计算出该线段与坐标边框线的交点,只画出坐标显示范围内的部分。
5.如何实现滚动?
if(RealTime>
DXMax)
XRegion=DXMax-DXMin;
DXMin=DXMax;
DXMax=DXMin+XRegion;
cleardevice();
DrawCoordinate(IWXMin,IWXMax,IWYMin,IWYMax,DXMin,DXMax,DYMin,DYMax,DXStep,DYStep,DReferenceLine,IGrid);
LastWDotX=IWXMin-1;
if(RealTime<
=DXMax)
WDotX=GetScreenX(RealTime,IWXMin,IWXMax,DXMin,DXMax);
WDotY=GetScreenY(DData,IWYMin,IWYMax,DYMin,DYMax);
if(LastWDotX<
IWXMin)
line(WDotX,WDotY,WDotX,WDotY);
line(WDotX,WDotY,LastWDotX,LastWDotY);
LastWDotX=WDotX;
LastWDotY=WDotY;
程序运行结果截图(不同运行条件下)
1.中断时间T=50ms,幅值为50,程序运行如下:
2.更改中断时间,改变周期,运行结果如下所示:
实验三AD/DA数据采集与模拟量输出实验
1.熟悉AD/DA卡的工作原理
2.掌握AD/DA卡的安装、配置及编程方法。
3.了解实时数据采集和模拟量输出的常用方案。
1.具有ISA总线插槽和USB接口的PC系列微型计算机,操作系统使用DOS或Windows98,装有TurboC2.0,DosBox。
2.超低频信号发生器。
3.超低频示波器。
4.HY1232模入/模出接口板。
程序运行前,配置数据文件,运行后,首先,在屏幕上设定位置绘制坐标系,然后每间隔指定的时间通过A/D采集信号发生器的输出信号,保存到指定数据文件、绘制在坐标系里、并通过D/A输出,
1.能通过配置文件来改变程序的运行模式,不必修改代码即可让程序在启动时或者工作于实验二方式或者工作于实验三方式。
2.A/D采集过程得到的数字量及解码后得到模拟量均要保存到数据文件中。
1.A/D转换代码的实现?
进行从端口读入AD12位AD值,使用位运算组合后,乘上对应的系数,就得到了AD采样值。
outportb(0x280,0x00);
while((inportb(0x285)&
0x80)==0)
;
IData=inportb(0x281)|((inportb(0x282)&
0x0f)<
<
8);
DData=5-(4095-IData)*10./4096;
2.解码的原理和实现?
12位AD对应-5V到+5V之间的电压变化,产生212=4096个量,所以该12位AD的分辨率为:
10/4096=0.00244140625V。
代码为:
DData就是实际的电压值。
3.D/A转换的数字量与A/D转换的数字量如何变换?
D/A的实现?
D/A转换时,把12位A/D转换的结果通过位运算分解为两个8位数字量,通过端口控制D/A输出。
程序如下:
if(IData<
4095)
IDAData=IData+1;
IDAData=IData;
outportb(0x283,IDAData&
0x0ff);
outportb(0x284,(IDAData>
8)&
0x0f);
4.如何实现实验二和实验三的切换?
通过在设置一个变量ADDA,当ADDA==0时,进行实验二,ADDA==1时,进行实验三。
从而可以实现实验二和实验三的切换。
在Process()函数中插入代码
if(ADDA==1)
略
IData=Index%10;
DData=5*sin(RealTime);
5.程序运行结果截图
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 测控 系统 程序设计 实验 报告