定时中断与数据采集实验.docx
- 文档编号:10805620
- 上传时间:2023-02-23
- 格式:DOCX
- 页数:16
- 大小:49KB
定时中断与数据采集实验.docx
《定时中断与数据采集实验.docx》由会员分享,可在线阅读,更多相关《定时中断与数据采集实验.docx(16页珍藏版)》请在冰豆网上搜索。
定时中断与数据采集实验
实验1定时中断与数据采集实验
1.1实验目的
1掌握定时器/计数器8254的工作原理与编程。
2熟悉中断控制器8259A的工作原理与使用方法。
3掌握硬件中断程序设计的原理与编程方法。
4掌握A/D、D/A转换器的使用与数据采集的方法。
5掌握建立磁盘数据文件的方法。
6掌握TC绘制曲线的方法和技巧。
1.2实验设备
1具有ISA总线插槽和USB接口的PC系列微型计算机,操作系统使用DOS或Windows98,装有TurboC2.0,DosBox。
2超低频信号发生器。
3超低频示波器。
1.3实验要求
程序运行前,配置数据文件(包括中断服务的时间间隔T,中断服务次数N,坐标系在屏幕上的位置,横(时间)纵(幅度)坐标显示范围及刻度等)。
运行后,首先,在屏幕上设定位置绘制坐标系,然后每间隔指定的时间生成设定的正弦曲线上的一个点,保存到指定数据文件并绘制在坐标系里,超过横坐标显示范围后,会滚动显示,显示N个点后,则曲线停止,如果N=0,则会无限显示下去,直到在键盘上按下指定的按键,才停止显示。
停止显示后,按指定键程序结束运行。
同时,将从A/D通道上采集到的数据通过D/A输出,在示波器上显示相应的波形曲线。
具体要求如下:
1横坐标标注为时间,纵坐标标注为幅度。
2曲线动态显示
3配置文件如有错误要能提示,不会造成程序运行报系统错误。
4编程时要尽量把具有独立功能的代码写成子程序。
4注意变量的命名要清晰,代码的注释要丰富。
5后面的数据采集要在此程序基础上编程、添加代码,注意程序的结构。
1.4设计前的分析和计算
对通道0进行操作需要对8254定时/计数器的控制字写入36H。
进行读写操作时,先读写低8位字节,再读写高8位字节,通道0工作在方式3,即方波发生器(分频器方式)。
方波的频率为1.193MHz/65536
18.2Hz,方波周期约为838ns,即8254定时器每隔838ns记一个数。
对于实验要求的Nms,此时此时计数初值为Nms/838ns=1193*N,考虑到1193*N可能超出计数器的最大计数值65536,若1.193*N小于65536,则直接设置8254计数器的初始值为需要的计数值1193*N,需要将这个计数初值转换成十六进制数。
若1193*N大于65536,首先将计数器初始值设置为1193*N和65536的余数,计满余数对应的时间,之后再计数m=1193*N/65536次,计数初值设置为0即可。
采用这样的设计方式,实现了对于任意给定时间间隔的计数。
图形的绘制:
显示器的屏幕是不能够直接进行绘图的。
因此绘图之前需要将屏幕转换为可绘图的格式,而且注意绘图模式下的屏幕坐标是以像素为单位,而二维的屏幕绘图模式,左上角是原点,向右是X轴正半轴,向下时Y轴正半轴。
要在图形坐标下的绘制转换为屏幕像素坐标下的形式才行。
数据文件的创建和数据保存:
首先在主程序中创建一个只写的文本文件,然后在采集到一个数据后将该数据的数字量和对应的电压等信息用fprintf()函数写入文件。
在退出程序时关闭数据文件。
1.6实验程序
#include
#include
#include
#include
doubleTimeInterval;
intEndStroke;
intCurInterruptTimes;
longintCurInterruptNum;
longintInterruptNum;
intLongCount;
unsignedcharL8;
unsignedcharH8;
intIWXMin,IWXMax,IWYMin,IWYMax;/*RegionofScreenPixel*/
doubleDXMin,DXMax,DYMin,DYMax;/*Regionofrealvalue*/
doubleDXStep,DYStep;/*StepofGrid*/
doubleDReferenceLine;/*realvalueofReferenceLine*/
intIGrid;/*1:
DrawGrid;0:
Don'tdrawgrid*/
intIsShowRealData;/*Doesshowtherealdata,1:
showrealdata;0:
simulatedata*/
FILE*fp;
intLastWDotX,LastWDotY;
voidinterrupt(*oldint8)(void);
voidinterruptmyint8(void);
voidCalculateInterruptPara(doubleDTimeInterval,int*ILongCount,unsignedchar*CL8,unsignedchar*CH8);
voidSetupTimerInterrupt(void);
voidRestoreTimerInterrupt(void);
voidReadSetupFromFile(void);
voidReadSetupFromFile(void);
voidProcess();
//获得屏幕X坐标
intGetScreenX(doubleRealX,intWXMin,intWXMax,doubleXMin,doubleXMax)
{
intWX=(WXMax-WXMin)/(XMax-XMin)*(RealX-XMin)+WXMin;
returnWX;
}
//获得屏幕Y坐标
intGetScreenY(doubleRealY,intWYMin,intWYMax,doubleYMin,doubleYMax)
{
intWY=WYMax-(WYMax-WYMin)/(YMax-YMin)*(RealY-YMin);
returnWY;
}
//计算定时器间隔
intGetInterval(doubleRealInterval,intWRegion,doubleRegion)
{
intInterval=WRegion/Region*RealInterval;
returnInterval;
}
//绘制坐标系
voidDrawCoordinate(intWXMin,intWXMax,intWYMin,intWYMax,doubleXMin,doubleXMax,doubleYMin,doubleYMax,doubleXStep,doubleYStep,doubleRefLine,intGrid)
{
charLabel[10];
intWYRefLine;
intWDot;
doubleDot;
inti;
/*DrawFrame*/
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);
setcolor
(1);
setlinestyle(0,0,3);
line(WXMin-25,WYRefLine,WXMax+25,WYRefLine);
line(WXMax+25,WYRefLine,WXMax,WYRefLine-13);
line(WXMax+25,WYRefLine,WXMax,WYRefLine+13);
line(WXMin,WYMax+25,WXMin,WYMin-15);
line(WXMin,WYMin-15,WXMin-13,WYMin+5);
line(WXMin,WYMin-15,WXMin+13,WYMin+5);
gcvt(RefLine,5,Label);
setcolor(63);
setlinestyle(0,0,1);
settextstyle(0,0,1);
outtextxy(WXMin-20,WYRefLine-2,Label);
/*DrawXStep*/
i=0;
while
(1)
{
Dot=XMin+i*XStep;
WDot=GetScreenX(Dot,WXMin,WXMax,XMin,XMax);
if(WDot>WXMax)
{
break;
}
if(Grid==1)
{
line(WDot,WYMin,WDot,WYMax);
}
else
{
line(WDot,WYMax,WDot,WYMax-5);
}
gcvt(Dot,5,Label);
outtextxy(WDot-5,WYMax+8,Label);
i++;
}
/*DrawyStep*/
i=0;
while
(1)
{
Dot=YMin+i*YStep;
WDot=GetScreenY(Dot,WYMin,WYMax,YMin,YMax);
if(WDot { break; } if(Grid==1) { line(WXMin,WDot,WXMax,WDot); } else { line(WXMin,WDot,WXMin+5,WDot); } gcvt(Dot,5,Label); if(Dot<0) { outtextxy(WXMin-30,WDot-2,Label); } else { outtextxy(WXMin-20,WDot-2,Label); } i++; } } voidInitiateGraphic(void) { intDriver=DETECT,Mode; initgraph(&Driver,&Mode,""); setbkcolor (2); } //读取配置 voidReadSetupFromFile(void) { FILE*fp1; fp1=fopen("Setup.txt","r"); fscanf(fp1,"%d,%d,%d,%d\n",&IWXMin,&IWXMax,&IWYMin,&IWYMax); fscanf(fp1,"%le,%le,%le,%le\n",&DXMin,&DXMax,&DYMin,&DYMax); fscanf(fp1,"%le,%le\n",&DXStep,&DYStep); fscanf(fp1,"%le\n",&DReferenceLine); fscanf(fp1,"%d\n",&IGrid); fscanf(fp1,"%d\n",&IsShowRealData); fclose(fp1); } //计算中断定时器初值 voidCalculateInterruptPara(doubleDTimeInterval,int*ILongCount,unsignedchar*CL8,unsignedchar*CH8) { doubleTotalCounter=DTimeInterval*1193; intResidue; *ILongCount=TotalCounter/65536; Residue=TotalCounter-65536*(*ILongCount); *CH8=Residue>>8; *CL8=Residue&0x0FF; } //设置定时器中断和初值 voidSetupTimerInterrupt(void) { /*StartInterrupt*/ disable(); oldint8=getvect(0x08); outportb(0x43,0x36); outportb(0x40,L8); outportb(0x40,H8); setvect(0x08,myint8); enable(); } //恢复原始中断映射 voidRestoreTimerInterrupt(void) { disable(); outportb(0x40,0x00); outportb(0x40,0x00); setvect(0x08,oldint8); enable(); } //中断程序核心任务,完成数据采集,曲线显示,数据存储和D/A输出,在中断服务程序中调用 voidProcess() { intIndex,IData; doubleDData; intADDA; doubleDealedData; doubleRealTime; doubleXRegion; intWDotX,WDotY; intWDotZero; Index=CurInterruptNum; RealTime=CurInterruptNum*TimeInterval/1000.0; if(IsShowRealData==1) { outportb(0x280,0x00); do {; }while(! (inportb(0x285)&0x80)); IData=inportb(0x281)|((inportb(0x282)&0x0f)<<8);/*A/D*/ DData=5-(4095-IData)*10.0/(pow(2,12)); ADDA=(DealedData-(-5))*pow(2,12)/10;/*D/A*/ outportb(0x283,(ADDA&0x00ff)); outportb(0x284,((ADDA>>8)&0x0f)); } elseif(IsShowRealData==0) { IData=Index%10; DData=50*sin(0.1*Index); } fprintf(fp,"%d\t%d\t%le\t%le\n",Index,IData,RealTime,DData); 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); setcolor(4); setlinestyle(0,0,3); if(LastWDotX { if(LastWDotX! =0) { WDotZero=LastWDotY+(WDotY-LastWDotY)*(IWXMin-WDotX)/(WDotX-LastWDotX); line(IWXMin,WDotZero,WDotX,WDotY); } else { line(WDotX,WDotY,WDotX,WDotY); } } else { line(WDotX,WDotY,LastWDotX,LastWDotY); } LastWDotX=WDotX;LastWDotY=WDotY; setcolor(63); setlinestyle(0,0,1); } } //定时器中断服务程序 voidinterruptmyint8(void) { if(kbhit()) { EndStroke=bioskey(0); } if(LongCount==0) { Process(); CurInterruptNum++; } elseif(LongCount>0) { CurInterruptTimes++; outportb(0x40,0x00); outportb(0x40,0x00); if(CurInterruptTimes<=LongCount) { ; } elseif(CurInterruptTimes==(LongCount+1)) { outportb(0x40,L8); outportb(0x40,H8); Process(); CurInterruptTimes=0; CurInterruptNum++; } } outportb(0x20,0x20); } voidmain() { char*DataFileName; DataFileName=(char*)malloc(sizeof(char)*100); printf("PleaseEntertheIntervaloftheinterrupt: \n"); scanf("%le",&TimeInterval); printf("Pleaseinputthetimesofinterrupt: \n"); scanf("%d",&InterruptNum); printf("Pleaseenterthenameofdatafile: \n"); scanf("%s",DataFileName); fp=fopen(DataFileName,"w"); if(fp==NULL) { printf("can'topenthedatafile%s",DataFileName); return; } CalculateInterruptPara(TimeInterval,&LongCount,&L8,&H8); CurInterruptNum=0; CurInterruptTimes=0; InitiateGraphic(); ReadSetupFromFile(); DrawCoordinate(IWXMin,IWXMax,IWYMin,IWYMax,DXMin,DXMax,DYMin,DYMax,DXStep,DYStep,DReferenceLine,IGrid); SetupTimerInterrupt(); while (1) {//以下是处理退出机制 if(InterruptNum==0) { if(EndStroke==11875) { break; } } elseif(InterruptNum<0) { InterruptNum=-InterruptNum; } else { if(CurInterruptNum { if(EndStroke==11875) { break; } } elseif(CurInterruptNum==InterruptNum) { break; } } } RestoreTimerInterrupt(); fclose(fp); free(DataFileName); closegraph(); getch(); } 1.7实验运行结果和调试分析 图1定时中断和数据采集实验结果图 从上图可以得出,信号的输出能够真实反映实时采集的信号,当输入信号的幅值和频率都发生变化时,输出的信号也跟随着进行平滑地变化。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 定时 中断 数据 采集 实验