定时中断与数据采集实验.docx

上传人:b****7 文档编号:10805620 上传时间:2023-02-23 格式:DOCX 页数:16 大小:49KB
下载 相关 举报
定时中断与数据采集实验.docx_第1页
第1页 / 共16页
定时中断与数据采集实验.docx_第2页
第2页 / 共16页
定时中断与数据采集实验.docx_第3页
第3页 / 共16页
定时中断与数据采集实验.docx_第4页
第4页 / 共16页
定时中断与数据采集实验.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

定时中断与数据采集实验.docx

《定时中断与数据采集实验.docx》由会员分享,可在线阅读,更多相关《定时中断与数据采集实验.docx(16页珍藏版)》请在冰豆网上搜索。

定时中断与数据采集实验.docx

定时中断与数据采集实验

实验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定时中断和数据采集实验结果图

从上图可以得出,信号的输出能够真实反映实时采集的信号,当输入信号的幅值和频率都发生变化时,输出的信号也跟随着进行平滑地变化。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 哲学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1