示 波 器
———C语言程序设计
姓 名: 龚 吉 祥
同 组 人: 王辉亚 谭 超
班 级: 09 软件(1)班
学 号: A093GZ053020129
指导老师: 陈美成
院 校: 贵州航天职业技术学院
时 间: 20##-11-09
目 录
一:摘要、引言 ------------------------------------------------------------------------------4
二:程序分析----------------------------------------------------------------------------------6
2.1:软件需要实现的功能 -------------------------------6
2.2:编译环境 --------------------------------------6
2.3:项目规划 ------------------------------------- 6
2.4:程序的技术难点 -------------------------------- 7
三:程序设计及算法分析 ---------------------------------8
3.1 程序框架设计 --------------------------------8
3.1.1 :程序设计草图 -----------------------------------8
3.1.2 程序流程图 ------------------------------------ 9
3.1.3 程序所需全局变量:-------------------------------10
3.1.4 函数分析:--------------------------------------10
3.2 程序模块函数详解 ----------------------------------13
3.2.1:按钮的设计-------------------------------------13
3.2.2,设置按钮按下的效果函数 -------------------------15
3.2.3,制作旋转圆形按钮 ------------------------------17
3..2..4:图形模式下的汉字输出 --------------------------20
3.3 程序界面的绘制 --------------------------------------21
3.3.1 绘波区的刻度函数 -------------------------------22
3.3.2 绘制程序固定不变的界面 --------------------------22
3.4 动态界面需要的相关元素 ------------------------------27
3.4.1 鼠标的监听-------------------------------------- 28
3.4.2 当鼠标离开按钮,程序界面的恢复---------------------30
3.4.3 当鼠标在旋转按钮上点击鼠标左键的效果函数 ----------31
3.4.4 获取鼠标点击界面上的那一个按钮 ------------------- 32
3.5 波形图函数 ------------------------------------------34
3.5.1 正弦波 ----------------------------------------34
3.5.2 方波 ------------------------------------------ 36
3.5.3 三角波 ---------------------------------------- 37
3.5.4 锯齿波 -----------------------------------------38
3.5.5 模拟音波 ---------------------------------------38
3.5.6 无规律波 ---------------------------------------39
3.6 波形图函数测量值输出 ------------------------------40
3.6.1:正弦波的相关数据输出----------------------------- 40
3.7:主要操作界面及函数(主函数)------------------------42
四:示波器最终效果 ----------------------------------50
五:总结 -------------------------------------------------51
六:展望与发展 ---------------------------------------- 52
七:参考文献--------------------------------------------------------------------------------53
摘要:随着计算机技术的发展,传统仪器开始向计算机化的方向发展。虚拟仪器是90年代提出的新概念。虚拟仪器技术的提出与发展,标志着二十一世纪自动测试与电子测量仪器领域技术发展的一个重要方向。所谓虚拟仪器,就是在通用的计算机平台上定义和设计仪器的测试功能,使用者操作这台计算机,就像是在使用一台专门设计的电子仪器。
本程序就是通过图形化虚拟示波器,因为在数据的采集和处理过程现在本组的技术能力有限,所以就通过简单的数学知识和C语言的相关知识来解决这个示波器程序。在程序中利用C语言基础知识和不断的重画图形来实现模拟的示波器。
在程序重主要利用的了鼠标中断,数学的正弦函数和其他的图形函数来实现波的显示来模拟示波器。
关键字: 示波器、正弦波、三角波、方波、频率、周期、振幅
引言
虚拟示波器是采用基于计算机的虚拟技术,用以模拟通用示波器的面板操作和处理功能,也就是使用个人计算机及接口电路来采集现场或实验室信号,并通过图形用户界面来模仿示波器的操作界面,完成信息采集、调理、分析处理和显示输出等功能。
该程序所设计的虚拟示波器,是在数据采集硬件的支持下,配备一定的软件,完成波形的存储、分析、显示等功能。一般测试仪器有信号采集、信号处理和结果显示三大部分组成,这三大部分均由硬件构成。虚拟示波器也是由这三大部分组成,但是,除了信号采集部分是有硬件实现之外,其它两部分都是由软件实现。
所设计的虚拟示波器总体上包括数据采集、波形显示、参数测量、频谱分析、等几大模块组成,虚拟示波器的结构框架图如下:
●这是示波器的基本处理过程,而本程序只实现了④, ⑤两步,前面的数据都是通过随机函数或设定一个值,然后通过后面的相关调节来改变数据,所以本程序只实现一个简单的模拟示波器。
程序分析
1 该软件需要实现的功能:
(1) 波形的展宽,压缩。
(2) 幅度的放大与缩小。
(3) 波形的平移。
(4) 实现信号的测量功能。
2编译环境:
(1) 硬件平台:
CPU:P41.8GHz;
内存:256MB以上。
(2) 编译工具:Win—tc中文版
(3) 运行环境:windowsXP
3 项目规划:
q 数据的信号的采集
这一个模块用来实现对外界信号的数据信号的测量。因为该部分知识尚未掌握。所以这些数据通过设置一个固定值和随机函数来代替数据的采集。
q 数据信号的采集:
该模块实现把收集好的信号转变为图形界面输出。本程序只通过了一些数学函数来完成。
q 实现用户与程序的交互性:
本程序实现这一点是通过接收用户的鼠标操作。该模块由黄金翔来完成。
q 波形的显示:
该模块以实现波形的图形显示。比如:正弦波,三角波,方波,锯齿波…..。该模块由袁财富完成。
q 数据信号测量和显示,调频,调幅,平移:
该模块实现波形的相关数据的显示,调频,调幅,平移。该模块由张志中来完成。
q 程序的设计以及程序的最终组合:
程序模块的组合和相关的完善,该模块由组长伍俊完成。
4 程序技术难点
1:无法实现对信号的采集,如:电量,电压、电流、频率、相位差、调幅度等
2:在试验过程中无法反映相关真实的数据,只能一味的用函数模拟波形。
3: 除掉前面两条没不用考虑的技术难点,这个程序在制作过程中的技术难点就是鼠标的控制,即鼠标的点击状态,和鼠标的当前位置。
4:汉字的图形画界面显示,本程序调用的是汉字字库HZK16的文字点阵图来实行汉字的显示。
5:波形的重画方法,程序执行过程中因为要不断的画波,而又因为不断的重画会导致画面的不流畅和闪烁,所以本程序中暂且采用的是檫去上一次的波的方法来减少程序的闪烁。
6:程序中波的展宽与压缩,其间不能改变波的原来的参数,只能通过一种算法来实现。
三 程序设计及算法分析
说明:
本程序因为需求的知识面甚广,而现在只学了C语言。而示波器的真正功能就未实现,这个程序做的就是模拟示波器的应用的一小部分。
3.1 程序框架设计
3.1.1:程序的设计草图,
说明:
程序通过几次设计及查看老师给的示例图片,最终通过PS 画出了上面的草图。
还有相关的坐标已由图中给出。该草图方便其他成员对整个程序大致有一个了解。
3.1.2 :程序流程图;
说明:
该流程图是整个程序执行过程中的大致描述。
3.1.3 程序所需全局变量:
1.int zf=40; /*用于存储振幅当前值*/
2.int zq=36; /*用于存储周期当前值*/
3.int py=2; /*用于存储平移当前值*/
4.int Chang_zf; /*用于存储振幅值改变前的值*/
5.int Chang_zq; /*用于存储当前周期的上次周期值*/
6.int Chang_py; /*用于存储当前平移的上次平移值*/
7.int smbo=0; /*用于存储保存当前是什么波*/
8.static int MoliNum[32]; /*用于存储模拟音波中的值*/
3.1.4函数分析:
void DrawButtonUp(int left,int top,int width,int height,int color)
/*函数说明;
函数用于画按钮没有被按下时的画面,这个函数主要画有背景的按钮,
其中left,top, width, height ,color 从字面意思就可以明白表示是按钮的左上角的坐标和按钮的宽度,还有按钮背景的颜色*/
void DrawButtonUp1(int left,int top,int width,int height)
/*函数说明;
函数用于画按钮没有被按下时的画面,这个函数没有画有背景的按钮,
其中left,top, width, height ,color 从字面意思就可以明白表示是按钮的左上角的坐标和按钮的宽度,这个函数是一个“死“按钮。因为如果要改变按钮 那么 就得改原代码函数。 这个函数在本程序下面主要是实现做动态画面的,已因为这一点,为了动态效果的流畅,所以没有画按钮背景*/
void DrawForm(int left,int top,int width,int height,int color)
/*函数说明;
函数用于绘画窗口的函数,因为要达到窗口的效果所以它和按钮有相似之处已有不同之处*/
void DrawButtonDown(int left,int top,int width,int height,int color)
/*函数说明;
函数用于画按钮被按下时的画面,这个函数主要画有背景的按钮,
其中left,top, width, height ,color 从字面意思就可以明白表示是按钮的左上角的坐标和按钮的宽度,还有按钮背景的颜色*/
void DrawButtonDown1(int left,int top,int width,int height)
/*函数说明;
函数用于绘画按钮被按下的函数,同前面的DrawButtonUp1 一样没有画按钮背景颜色 */
void DrRotationBtn(int x,int y,int r)
/*函数说明;
用于实现旋转按钮的绘制函数 ,X,Y是中心坐标,R 是最大半径。*/
void DrawKedu(int x,int y)
/*函数说明;
用于实现旋转按钮DrRotationBtn刻度的绘制函数 ,X,Y是中心坐标。该函数没有半径的设置 针对后面才加的函数 。所以需要在里面改动画的位置
*/
void initgr()
/* BGI初始化
函数说明;
初始化图形模式*/
void getmouse(int *x,int *y,int *key)
/*函数说明;
中断调用获取寄存器中存的鼠标坐标及案件状态*/
void visbilemouse()
/*函数说明;
显示鼠标*/
void mouse(int *x,int *y,int *z,int smbo)
/*函数说明;
画鼠标是利用将一个空矩形存入内存中,
然后再在该空矩形中画鼠标形状*/
void hanzi16(int x,int y,char *s,int colour)
/*函数说明;
中文输入输出函数,该函数需要汉字字库文件 HZK16 的支持*/
void myouttext(int x, int y,int num)
/*函数说明;
控制单个数字的输出显示 */
void Drowxy(int x,int y,int w,int h)
/*函数说明;
画示波器显示波的坐标, x,y 为坐标原点位置*/
void Sine_date(int zf,int zq,int Chang_zf,int Chang_zq)
/*函数说明;
用于实现正弦波的相关数据的显示,zf当前现在波的振幅zq当前现在波的周期Chang_zf上次波的振幅Chang_zq上次波的周期*/
void Podu(int zq,int py,int Chang_zq,int Chang_py)
/*函数说明;
用于实现正弦波的坡度的显示,该函数因为前期是实现鼠标点击处的坡度。但是在后期程序的改动所以没多用这个。已因为时间原因程序没多大改动。*/
void Sinew(int zf,int zq,int py,int Chang_zf,int Chang_zq,int Chang_py)
/*函数说明:
画正弦波函数 */
void NoRuleWave(int zf,int zq)
/*函数说明;
该函数原本已实现一些无规律波,或者方便扩展好改动为其他波,但是由于时间问题 这个函数就只是随便加了个随机函数*/
void MOliWave(int MoliNum[])
/*函数说明;
该函数用于随机生成一个数 ,然后用sound()PC 函数播放出这个数值的声音,已是在程序的基础上现在加的东东,方便以后更改和扩展*/
void Graph_face()
/*函数说明;
该函数是 主要函数,其功能是实现本程序的 基本不动画面的绘制,比如按钮和背景 还其他的按钮边框之类。本函数只程序运行的开始时使用*/
int Return_button(int x,int y,int z)
/*函数说明;
该函数是已是该程序的主要函数之一,用于判断用户当前鼠标的动作,比如一个按钮的按下,相应程序的操作。 */
void Huifu()
/*函数说明;
该函数是已是该程序的主要函数之一,用于判断实现程序动态的效果的恢复工作,比如一个按钮按下以后鼠标离开按钮后 那么这个按钮就需要恢复到正常状态*/
mousedata(int x,int y)
/*函数说明;
用于显示鼠标处的坐标*/
void Huifu_1()
/*函数说明;
程序说明段的文字颜色恢复,是程序后面加上的效果。*/
int DrRtinP(int x,int y,int m_x,int m_y,int Old_x,int Old_y,int r,int back)
/*函数说明;
x,Y为圆心坐标m_x,m_y为鼠标点击处坐标*/
void DengLu()
/*函数说明:做登陆效果*/
void DrawSoftAny()
/*函数说明:程序说明函数*/
3.2:程序模块函数详解.
3.2.1:按钮的设计;
分析:计算机中的按钮都是通过改变局部的颜色而达到动态的按钮效果。
如图;
1,
设置按钮弹起的效果函数;
void DrawButtonUp(int left,int top,int width,int height,int color)/* Draw button*/
{
setfillstyle(1,color);
bar(left,top,left+width,top+height);
setcolor(15);
line(left-2,top,left+width,top);
line(left-1,top+1,left+width,top+1);
line(left-1,top+2,left-1,top-1+height);
line(left-2,top+2,left-2,top-1+height);
setcolor(7);
line(left,top+height,left+width,top+height);
line(left-1,top+height-1,left+width+1,top+height-1);
line(left-1+width,top+2,left-1+width,top+height);
line(left+width,top+2,left+width,top+height);
}
2,为了按钮 的恢复 一下函数是恢复按钮周围变宽效果 已减少
Bar();重画函数使用的时间
void DrawButtonUp1(int left,int top,int width,int height) /*Draw button */
{
setcolor(15);
line(left-2,top,left+width,top);
line(left-1,top+1,left+width,top+1);
line(left-1,top+2,left-1,top-1+height);
line(left-2,top+2,left-2,top-1+height);
setcolor(7);
line(left,top+height,left+width,top+height);
line(left-1,top+height-1,left+width+1,top+height-1);
line(left-1+width,top+2,left-1+width,top+height);
line(left+width,top+2,left+width,top+height);
}
函数效果如图;
3.2.2,设置按钮按下的效果函数;
void DrawButtonDown(int left,int top,int width,int height,int color) /*Draw button */
{
setfillstyle(1,color);
bar(left,top,left+width,top+height);
setcolor(8);
line(left-2,top,left+width,top);
line(left-1,top+1,left+width,top+1);
line(left-1,top+2,left-1,top-1+height);
line(left-2,top+2,left-2,top-1+height);
setcolor(15);
line(left,top+height,left+width,top+height);
line(left-1,top+height-1,left+width,top+height-1);
line(left-1+width,top+2,left-1+width,top+height);
line(left+width,top+2,left+width,top+height);
}
为了按钮 的恢复 一下函数是恢复按钮周围变宽效果 已减少
Bar();重画函数使用的时间
void DrawButtonDown1(int left,int top,int width,int height) /*Draw button */
{
setcolor(8);
line(left-2,top,left+width,top);
line(left-1,top+1,left+width,top+1);
line(left-1,top+2,left-1,top-1+height);
line(left-2,top+2,left-2,top-1+height);
setcolor(15);
line(left,top+height,left+width,top+height);
line(left-1,top+height-1,left+width,top+height-1);
line(left-1+width,top+2,left-1+width,top+height);
line(left+width,top+2,left+width,top+height);
}
函数效果如图;
3.2.3,制作旋转圆形按钮;
void DrRotationBtn(int x,int y,int r)
{
int i=0;float a;
setcolor(15);
for(i=0;i<=360;i+=6)
{
a=i*PI/180;
line(x+(r-5)*cos(a),y+(r-5)*sin(a),x+r*cos(a),y+r*sin(a)) ;
}
setcolor(8);
circle(x,y,r);
circle(x,y,r-1);
circle(x,y,r+1);
setfillstyle(1,7);
pieslice(x,y,0,360,r-5);
setfillstyle(1,15);
pieslice(x,y,0,360,r-10);
for(i=0;i<=360;i+=6)
{
a=i*PI/180;
line(x+(r-15)*cos(a),y+(r-15)*sin(a),x+(r-10)*cos(a),y+(r-10)*sin(a)) ;
}
}
3.2.4,制作旋转按钮刻度
void DrRotationBtn(int x,int y,int r,int label) /*画旋转的按钮*/
{
int i=0,j,k=10,last=0;float a;
if(label!=0) /*如果不在调位移旋转按钮上*/
{
setcolor(15);
for(i=0;i<=360;i+=6)
{ a=i*PI/180;
line(x+(r-5)*cos(a),y+(r-5)*sin(a),x+r*cos(a),y+r*sin(a)) ;
}
setcolor(8);
circle(x,y,r);
circle(x,y,r-1);
circle(x,y,r+1);
setfillstyle(1,7);
pieslice(x,y,0,360,r-5);
setfillstyle(1,15);
pieslice(x,y,0,360,r-10);
for(i=0;i<=360;i+=6)
{ a=i*PI/180;
line(x+(r-15)*cos(a),y+(r-15)*sin(a),x+(r-10)*cos(a),y+(r-10)*sin(a)) ;
}
/*画调节大小*/
for(j=4;j<=20;j++)
for(i=(j-4)*18;i<=150;i++)
{
a=i*PI/180;
putpixel(x+(r+j)*cos(a),y+(r+j)*sin(a),0);
}
for(j=4;j<=20;j++)
for(i=350-(j-4)*18;i>210;i--)
{
a=i*PI/180;
putpixel(x+(r+j)*cos(a),y+(r+j)*sin(a),0);
}
}
else
{
setcolor(0);
/*画调节大小*/
setlinestyle(0,1,3);
line(x-r,y,x+r,y);
setlinestyle(0,1,1);
line(x-r,y,x-r+5,y-5);
line(x-r,y,x-r+5,y+5);/*标箭头*/
line(x+r,y,x+r-5,y-5);
line(x+r,y,x+r-5,y+5);
setcolor(15);
}
}
int DrRtinP(int x,int y,int m_x,int m_y,int Old_x,int Old_y,int r,int back,int label) /*x,Y为圆心坐标m_x,m_y为鼠标点击处坐标*/
{ float Cosa,Sina,rr;
setcolor(15);
if(label!=0) /*如果不在调位移旋转按钮上*/
{
if(Old_x!=0 && Old_y!=0)
{ rr=sqrt((x-Old_x)*(x-Old_x)+(y-Old_y)*(y-Old_y));
Cosa=(Old_x-x)/rr;
Sina=(Old_y-y)/rr;
line(x+(r-15)*Cosa,y+(r-15)*Sina,x+r*Cosa,y+r*Sina);
}
else
{
line(x,y-5,x,y-20);
}
rr=sqrt((x-m_x)*(x-m_x)+(y-m_y)*(y-m_y));
Cosa=(m_x-x)/rr;
Sina=(m_y-y)/rr;
setcolor(4);
line(x+(r-15)*Cosa,y+(r-15)*Sina,x+r*Cosa,y+r*Sina);
return (acos(Cosa)*180)/PI/30*back; /*旋转按扭的返回值*/
}
else
{
setcolor(7);
setlinestyle(0,1,3);
line(Old_x,y-5,Old_x,y+5);
setcolor(0);
line(x-r-r+5,y,x+r+r-5,y);
line(x,y-10,x,y+10);
return (m_x-x); /*旋转按扭的返回值*/
}
}函数效果如图;
3.2.5:图形模式下的汉字输出。
void hanzi16(int x,int y,char *s,int colour) /*中文输入输出函数*/
{
FILE *fp;
char buffer[32]; /* 32字节的字模缓冲区 */
register i,j,k;
unsigned char qh,wh;
unsigned long location;
if((fp=fopen("hzk16","rb"))==NULL)
{
printf("Cant open hzk16!");
getch();
exit(0);
}
while(*s)
{
qh=*s-0xa0;
wh=*(s+1)-0xa0;
location=(94*(qh-1)+(wh-1))*32L;/* 计算汉字字模在文件中的位置 */
fseek(fp,location,SEEK_SET);
fread(buffer,32,1,fp);
for(i=0;i<16;i++)
for(j=0;j<2;j++)
for(k=0;k<8;k++)
if(((buffer[i*2+j]>>(7-k))&0x1)!=NULL)
putpixel(x+8*j+k,y+i,colour);
s+=2;
x+=16; /* 汉字间距 */
}
fclose(fp);
}
3.3:程序界面的绘制。
说明:
经分析,程序中有两部份:一部分界面是一次画好就固定不变的,而另一部分是因用户的操作而动态变化的,比如当鼠标在正弦波按钮上点击鼠标左键的时候,那么在波形绘制区就会绘制一个正弦波的图形。在这过程中又可以分解为两个部分 ,鼠标按下和鼠标松开以后程序相应的反馈动作,而这部分界面就是动态界面。
在这里就先把固定不变的部分通过一个函数完成;
数字的图形显示。
void myouttext(int x, int y,int num) /*控制输入数字 */
{
switch (num)
{
case 1 :outtextxy(x,y,"1");break;
case 0 :outtextxy(x,y,"0");break;
case 2 :outtextxy(x,y,"2");break;
case 3 :outtextxy(x,y,"3");break;
case 4 :outtextxy(x,y,"4");break;
case 5 :outtextxy(x,y,"5");break;
case 6 :outtextxy(x,y,"6");break;
case 7 :outtextxy(x,y,"7");break;
case 8 :outtextxy(x,y,"8");break;
case 9 :outtextxy(x,y,"9");break;
default :;
}
}
3.3.1;绘波区的刻度函数,
void Drowxy(int x,int y,int w,int h) /*画坐标 xy 为圆心坐标,w为一半的宽度h一半的高度*/
{ int i;
setcolor(1);
setlinestyle(0,0,3);
line(x-w,y-1,x+w,y-1);
line(x-1,y-h,x-1,y+h);
setlinestyle(0,0,1);
for(i=30;i<=h;i=i+10){line(x-w,y+i,x+w,y+i);line(x-w,y-i,x+w,y-i);};
for(i=30;i<=w;i=i+10){line(x-i,y-h,x-i,y+h);line(x+i,y-h,x+i,y+h);};
}
3.3.2;绘制程序固定不变的界面。
void Graph_face() /*画固定不变的框架 */
{ int i;
setfillstyle(1,7);
bar(0,0,639,479); /*背景 */
setfillstyle(10,7);
bar(10,10,629,469); /*背景网格 */
setfillstyle(1,7);
bar(122,20,490,265); /*画波图背景边框 */
setfillstyle(1,0);
bar(150,23,485,250); /*画波图背景*/
setcolor(7);
line(130,20,135,25);
setfillstyle(1, 8); /*画波图背景边框 */
setcolor(8);
line(488,22,488,260);
line(0,0,10,10);
line(0,479,10,469);
line(639,0,629,10);
line(629,469,639,479);
setcolor(15);line(0,0,10,10);line(0,478,10,468);line(638,1,629,9);
DrawButtonUp(20,20,95,240,7); /*left rotation button*/
setfillstyle(0,15);
/*DrRotationBtn(65,95,40);bar(65,93,85,97);line(65,95,65,75); */
DrRotationBtn(65,210,40); bar(65,208,85,212); line(65,210,65,190);
DrawButtonUp(500,20,120,240,7); /*right rotation button*/
DrRotationBtn(565,95,40);bar(565,93,585,97);line(565,95,565,75);
DrRotationBtn(565,210,40);bar(565,208,585,212);line(565,210,565,190);
setfillstyle(0,4);
bar(63,208,67,212);
bar(563,93,567,97);
bar(563,208,567,212);
setfillstyle(10,7);
bar(10,270,629,469); /*-------------------------*/
setcolor(15);
line(10,270,629,270);
setcolor(15);
line(10,270,10,469); /*画下面黑色的*/
line(10,469,629,469);
line(629,270,629,469);
line(11,360,628,360);
for(i=0;i<6;i++)
{
setfillstyle(1,0);
bar(15+i*100,280,115+i*100,350);
} /*--------------------------*/
for(i=0;i<7;i++) /*------------*/
{
DrawButtonUp(25+i*85,370,70,35,6); /*画按钮*/
} /*----------*/
for(i=0;i<4;i++) /*------------*/
{
DrawButtonUp(25+i*85,420,70,35,6); /*画按钮*/
} /*----------*/
DrawButtonUp1(535,420,70,35);
setfillstyle(1,7);
bar(11,271,628,359);
setcolor(14);
hanzi16(25,30,"模拟示波器",4);
hanzi16(35,55,"程序说明",0);
line(35,75,95,75);
hanzi16(45,80,"联系我",0);
line(45,100,90,100);
hanzi16(55,110,"退出",14);
line(55,125,85,125);
hanzi16(45,150,"调位移",0);
DrawKedu(65,210);
hanzi16(545,30,"调振幅",0);
DrawKedu(565,95);
hanzi16(545,150,"调周期",0);
DrawKedu(565,210);
hanzi16(30,380,"正弦波",11);
hanzi16(115,380,"方波",11);
hanzi16(200,380,"三角波",11);
hanzi16(285,380,"锯齿波",11);
hanzi16(370,380,"获取周期",11);
hanzi16(455,380,"随机波",11);
hanzi16(540,380,"动态波",11);
setcolor(1);
hanzi16(30,430,"监听声卡",11);
hanzi16(115,430,"无规律波",11);
hanzi16(200,430,"展宽",11);
hanzi16(285,430,"压缩",14);
/* hanzi16(370,430,"取",14);
outtextxy(385,435,"X1");
hanzi16(400,430,"坐标",14);
hanzi16(455,430,"取",14);
outtextxy(470,435,"X2");
hanzi16(485,430,"坐标",14);*/
hanzi16(560,430,"清屏",14);
for(i=0;i<5;i++) /*画信息框*/
{
DrawForm(21+i*87,276,70,75,8);
setfillstyle(1,7);
bar(21+i*87,278,89+i*87,318);
setcolor(15);
line(21+i*87,318,89+i*87,318);
/*-------------------*/
}
DrawForm(21+i*87,276,160,75,8); /*画函数表达市的边框*/
setfillstyle(1,7);
bar(21+i*87,278,179+i*87,300);
line(21+i*87,300,179+i*87,300);
hanzi16(45+i*87,280,"当前函数表达式",11);/*-------------*/
hanzi16(35,290,"振幅",0);hanzi16(37,292,"振幅",11);
hanzi16(122,290,"周期",0);hanzi16(124,292,"周期",11);
hanzi16(207,290,"频率",0); hanzi16(209,292,"频率",11);
hanzi16(285,290,"原点坡度",0);hanzi16(287,292,"原点坡度",11);
setcolor(4);
outtextxy(383,285,"X1-X2");
hanzi16(386,295,"周期",0);hanzi16(388,297,"周期",11);
setcolor(8);
for(i=0;i<120;i=i+10)
{
line(130,135+i,153,135+i);line(130,135-i,153,135-i);
}; /*画刻度*/
for(i=0;i<180;i=i+10)
{
line(320+i,250,320+i,260);
line(320-i,250,320-i,260);
};
/* bar(122,20,490,265); 画波图背景边框
setfillstyle(1,0);
bar(150,23,485,250);*/
setcolor(15);
outtextxy(130,250,"0"); /*绘波区刻度数据*/
setcolor(15);
outtextxy(122,240,"-110"); /*画数据*/
outtextxy(123,190,"-60");
outtextxy(123,130,"0");
outtextxy(123,70,"60");
outtextxy(123,20,"110");
outtextxy(150,260,"0");
outtextxy(205,255,"60");
outtextxy(265,255,"120");
outtextxy(310,255,"170");
outtextxy(370,255,"230");
outtextxy(430,255,"290");
outtextxy(455,255,"(T)");
}
3.4:动态界面需要的相关元素。
说明:
程序要达到动态的效果 那么就必须做到和用户交互,
怎么做到交互性?那么用户可以要通过相关介质输入用户想要的数据。
程序 通过接受相关数据从而给用户相应的回答,那么用户与计算机的交互是什么?
在这里程序选择的是通过获取用户的鼠标操作来完成。
怎么获取鼠标的相关操作了?
在这里通过的中断处理
3.4.1:鼠标的监听。
void getmouse(int *x,int *y,int *key)
{
union REGS inregs,outregs;
inregs.x.ax=3; /*获取鼠标位置和状态也可以用3*/
int86(0x33,&inregs,&outregs); /*中断调用*/
*x=outregs.x.cx; /*cx寄存器中存的是横坐标*/
*y=outregs.x.dx; /*dx寄存器中存的是列坐标*/
*key=outregs.x.bx; /*bx寄存器是按键状态*/
}
void visbilemouse()
{
union REGS inregs,outregs;
inregs.x.ax=0x01; /*显示鼠标*/
int86(0x33,&inregs,&outregs);
}
/*按键后,返回当前鼠标的x,y和按键状态,知道按键后才返回*/
void mouse(int *x,int *y,int *z,int smbo) /*画鼠标是利用将一个空矩形存入内存中,然后再在该空矩形中画鼠标形状*/
{
int a=0,b=0,c=0,a_old=0,b_old=0; /*a,b的值可以随便*/
int *ball; /*定义指向内存的存储图形的指针*/
ball=malloc(imagesize(a,b,a+R,b+R)); /*返回矩形的大小*/
getimage(a,b,a+R,b+R,ball); /*第一次将图形(一个空矩形)存入到内存中,内存中存入的是一个空矩形*/
/*setcolor(GREEN);
setlinestyle(0,0,1);
line(a,b,a+R,b+R/2);
line(a,b,a+R/2,b+R);
line(a+R,b+R/2,a+R/2,b+R);
line(a+R*3/4,b+R*3/4,a+R,b+R); 同样可要可不要,画鼠标*/
while(c!=1 )/*直到按键后才返回,不按键一直循环*/
{
getmouse(&a,&b,&c); /*a,为横坐标,b,为列坐标,c为按键状态*/
if(a<0) a=0; /*保证鼠标左边不出界*/
if(b<0) b=0; /*保证上面不出界*/
if(a>getmaxx()-R) a=getmaxx()-R; /*保证右边不出界*/
if(b>getmaxy()-R) b=getmaxy()-R; /*保证下边不出界*/
if(a!=a_old || b!=b_old) /*当鼠标移动时*/
{
putimage(a_old,b_old,ball,0);
/*在a_old,b_old输出图形,用来擦掉原来的鼠标*/
getimage(a,b,a+R,b+R,ball);
/*这条语句是将目前鼠标所在位置的图形存贮到ball里面试着看着有无这条语句的区别*/
/*不需要在获取了*/
if(a>153 && a<485 && b>25 && b<250)
{
setcolor(2);
line(a,b,a+15,b);
line(a,b,a,b+15);
mousedata(a,b); /*鼠标在绘波区的坐标显示*/
}
else
{
bar(485,310,525,340);
setcolor(4);
setlinestyle(0,0,1);
line(a,b,a+R,b+R/2);
line(a,b,a+R/2,b+R);
line(a+R,b+R/2,a+R/2,b+R);
line(a+R*3/4,b+R*3/4,a+R,b+R); /*画鼠标*/
};
} ;
if(c==2 && (smbo==13 ||smbo==3))smbo=0,nosound();
if (smbo==13 || smbo==3)break;
/*用于控制动态波的退出(点击鼠标右键)*/
a_old=a;b_old=b;
}/* while()结束*/
*x=a;*y=b;*z=c; /*返回按键后鼠标的位置*/
putimage(a,b,ball,0); /*将鼠标擦掉,因为存在ball里面的是一个背景为缺省状态下的一个空矩形*/
free(ball);
}
/*主要思想是通过getimage,putimage,imagesize图形的存贮一个当前的图形来擦拭掉以前的鼠标图形,也可以用清屏部分屏幕来实现*/
3.4.2:当鼠标离开按钮,程序界面的恢复!
void Huifu() /*回复 让字现实为一般颜色 */
{
DrawButtonUp1(25,420,70,35);
hanzi16(30,430,"监听声卡",11);
DrawButtonUp1(110,420,70,35);
hanzi16(115,430,"无规律波",11);
DrawButtonUp1(195,420,70,35);
hanzi16(200,430,"展宽",11);
DrawButtonUp1(280,420,70,35);
hanzi16(285,430,"压缩",14);
DrawButtonUp1(25,370,70,35);
hanzi16(30,380,"正弦波",11);
DrawButtonUp1(110,370,70,35);
hanzi16(115,380,"方波",11);
DrawButtonUp1(195,370,70,35);
hanzi16(200,380,"三角波",11);
DrawButtonUp1(280,370,70,35);
hanzi16(285,380,"锯齿波",11);
DrawButtonUp1(365,370,70,35);
hanzi16(370,380,"获取周期",11);
DrawButtonUp1(450,370,70,35);
randomize();hanzi16(455,380,"随机波",11);
DrawButtonUp1(535,370,70,35);
hanzi16(540,380,"动态波",11);
DrawButtonUp1(535,420,70,35);
hanzi16(560,430,"清屏",14);
setcolor(14);
hanzi16(35,55,"程序说明",0);
line(35,75,95,75);
hanzi16(45,80,"联系我",0);
line(45,100,90,100);
}
void Huifu_1() /*程序说明段的恢复*/
{
setcolor(14);
hanzi16(35,55,"程序说明",0);
line(35,75,95,75);
hanzi16(45,80,"联系我",0);
line(45,100,90,100);
}
3.4.3:当鼠标在旋转按钮上点击鼠标左键的效果函数!
/*x,Y为圆心坐标m_x,m_y为鼠标点击处坐标*/
int DrRtinP(int x,int y,int m_x,int m_y,int Old_x,int Old_y,int r,int back,int label) /*x,Y为圆心坐标m_x,m_y为鼠标点击处坐标。Label为标记是 那个旋转按钮*/
{ float Cosa,Sina,rr;
setcolor(15);
if(label!=0)
{
if(Old_x!=0 && Old_y!=0)
{ rr=sqrt((x-Old_x)*(x-Old_x)+(y-Old_y)*(y-Old_y));
Cosa=(Old_x-x)/rr;
Sina=(Old_y-y)/rr;
line(x+(r-15)*Cosa,y+(r-15)*Sina,x+r*Cosa,y+r*Sina);
}
else
{
line(x,y-5,x,y-20);
}
rr=sqrt((x-m_x)*(x-m_x)+(y-m_y)*(y-m_y));
Cosa=(m_x-x)/rr;
Sina=(m_y-y)/rr;
setcolor(4);
line(x+(r-15)*Cosa,y+(r-15)*Sina,x+r*Cosa,y+r*Sina);
return (acos(Cosa)*180)/PI/30*back; /*旋转按扭的返回值*/
}
else
{
if(Old_x!=0 && Old_y!=0&&(x>(x-r))&&(x<(x+r))&&(y>(y-r))&&(y<=y))
{ rr=sqrt((x-Old_x)*(x-Old_x)+(y-Old_y)*(y-Old_y));
Cosa=(Old_x-x)/rr;
Sina=(Old_y-y)/rr;
line(x+(r-15)*Cosa,y+(r-15)*Sina,x+r*Cosa,y+r*Sina);
}
else
{
/*line(x,y-5,x,y-20); */
}
if((x>(x-r))&&(x<(x+r))&&(y>(y-r))&&(y<=y))
{
rr=sqrt((x-m_x)*(x-m_x)+(y-m_y)*(y-m_y));
Cosa=(m_x-x)/rr;
Sina=(m_y-y)/rr;
setcolor(4);
line(x+(r-15)*Cosa,y+(r-15)*Sina,x+r*Cosa,y+r*Sina);
return (acos(Cosa)*180)/PI/30*back; /*旋转按扭的返回值*/
}
}
}
3.4.4:获取鼠标点击界面上的那一个按钮!
/*判断按的是那个按钮*/
int Return_button(int *x,int *y,int *z)
{
int a;
if( *x<95 && *x>25 && *y<405 && *y>370&&*z==1 )a=7;
/*当鼠标在正弦波按钮处 */
if( *x<180 && *x>110 &&*y<405 && *y>370&&*z==1 )a=8;
/*当鼠标在方波按钮处 */
if( *x<265 && *x>195 && *y<405 &&*y>370 &&*z==1)a=9;
/*当鼠标在三角波按钮处 */
if( *x<350 && *x>280 && *y<405 && *y>370 &&*z==1 )a=10;
/*当鼠标在锯齿波按钮处 */
if( *x<435 && *x>365 && *y<405 && *y>370 && *z==1)a=11;
/*当鼠标在获取周期按钮处 */
if( *x<520 && *x>450 && *y<405 && *y>370 &&*z==1)a=12;
/*当鼠标在随机波按钮处 */
if( *x<605 && *x>535 && *y<405 && *y>370 &&*z==1)a=13;
/*当鼠标在动态按钮处 */
if( *x<95 && *x>25 && *y<455 && *y>420&&*z==1)a=1;
/*当鼠标在监听声卡波按钮处 */
if( *x<180 && *x>110 &&*y<455 && *y>420&&*z==1)a=2;
/*当鼠标在无规律波按钮处 */
if( *x<265 && *x>195 &&*y<455 && *y>420&&*z==1)a=3;
/*当鼠标在展宽按钮处 */
if( *x<350 && *x>280 && *y<455 && *y>420&&*z==1)a=4;
/*当鼠标在压缩按钮处 */
if( *x<605 && *x>535 && *y<455 && *y>420 &&*z==1)a=16;/*清屏按钮*/
if(*x>153 && *x<485 && *y>25 && *y<250)a=17;
/*判断是不是在现实画波区*/
if(*x>25 && *x<105 && *y>55 && *y<135&&*z==1)a=18;
/*判断是不是在left top rotation button*/
if(*x>25 && *x<105 && *y>170 && *y<250&&*z==1)a=19;
/*判断是不是在left down rotation button*/
if(*x>525 && *x<605 &&*y>55 && *y<135&&*z==1)a=20;
/*判断是不是在right top rotation button*/
if(*x>525 && *x<605 && *y>170 && *y<250&&*z==1)a=21;
/*判断是不是在right down rotation button*/
if(*x>35 && *x<95 && *y>55 && *y<75)a=22;
/*判断是不是在程序说明处*/
if(*x>45 && *x<90 && *y>80 && *y<100)a=23;
/*判断是不是在联系我处*/
if(*x>55 && *x<85 && *y>105 &&* y<125)a=24;/*判断是不是在退出*/
return a;
}
3.5:波形图函数。
3.5.1;正弦波。
void Sinew() /*画正弦波函数 */
{
double x,bl1,bl2,bl3,bl4;
Sine_date(zf,zq,Chang_zf,Chang_zq);
setcolor(0);
for(x=0;x<=164;x++)
{
bl1=Chang_zf*sin((x+320+Chang_py)*3.14/(Chang_zq))+134;
bl2=Chang_zf*sin((x+321+Chang_py)*3.14/(Chang_zq))+134;
bl3= Chang_zf*sin((320-x+Chang_py)*3.14/(Chang_zq))+134;
bl4=Chang_zf*sin((319-x+Chang_py)*3.14/(Chang_zq))+134;
if(bl1>250)bl1=250;
if(bl2>250)bl2=250;
if(bl1<25)bl1=25;
if(bl2<25)bl2=25;
if(bl3>250)bl3=250;
if(bl4>250)bl4=250;
if(bl3<25)bl3=25;
if(bl4<25)bl4=25;
if(319-x>155)line(320-x,bl3,319-x,bl4);
line(320+x,bl1,321+x,bl2);
/* putpixel(x,zf*sin((x+py)*3.14/zq)+160,4); */
};
Drowxy(320,135,160,110); /*重画坐标*/
setcolor(4);
for(x=0;x<=164;x++)
{
bl1=zf*sin((x+320+py)*3.14/(zq))+134;
bl2=zf*sin((x+321+py)*3.14/(zq))+134;
bl3=zf*sin((320-x+py)*3.14/(zq))+134;
bl4=zf*sin((319-x+py)*3.14/(zq))+134;
if(bl1>250)bl1=250;
if(bl2>250)bl2=250;
if(bl1<25)bl1=25;
if(bl2<25)bl2=25;
if(bl3>250)bl3=250;
if(bl4>250)bl4=250;
if(bl3<25)bl3=25;
if(bl4<25)bl4=25;
if(319-x>155)line(320-x,bl3,319-x,bl4);
line(320+x,bl1,321+x,bl2);
/* putpixel(x,zf*sin((x+py)*3.14/zq)+160,4); */
};
}
效果如下
3.5.2:方波。
void RECT(float A,float T,float Dx,float Dy,float color)
{
float i,j,x,y,X,Y,dx=134,dy=130;
setcolor(color);
for(i=0;i<=360;i++)
{
x=(int)i%(int)T;
X=x+(int)(i/T)*T+dx+Dx;
if(X>150&&X<485)
{
if(fabs(x)<10e-1)
{
if(-A+dy<23&&A+dy<250)
line(X,23,X,A+dy);
else if(-A+dy>23&&A+dy>250)
line(X,-A+dy,X,250);
else if(-A+dy<23&&A+dy>250)
line(X,23,X,250);
else
line(X,-A+dy,X,A+dy);
}
else if(x>0&&x<T/2)
y=A;
else if(fabs(x-T/2)<10e-1)
{
if(-A+dy<23&&A+dy<250)
line(X,23,X,A+dy);
else if(-A+dy>23&&A+dy>250)
line(X,-A+dy,X,250);
else if(-A+dy<23&&A+dy>250)
line(X,23,X,250);
else
line(X,-A+dy,X,A+dy);
}
else if(x>T/2&&x<=T)
y=-A;
Y=y+dy;
}
if(X>150&&X<485 && Y>23&&Y<250)
line(X,Y,X+1,Y);
}
}
方波效果如下
3.5.3:三角波。
void ANGLE(float A,float T,float Dx,float Dy,float color)
{
float i,x,y,X,dx=134,dy=130;
setcolor(color);
for(i=0;i<=400;i++)
{
x=(int)i%(int)T;
if(x>=0&&x<T/2)
y=2*A/T*x-A/2+dy;
else if(x>=T/2&&x<=T)
y=-2*A/T*x+3*A/2+dy;
X=x+(int)(i/T)*T+dx+Dx;
if(X>150&&X<485 && y>23&&y<250)
line(X,y,X+1,y);
}
}
三角波效果图
3.5.4:锯齿波。
void juchibo(float A,float T,float Dx,float Dy,float color)
{
float i,x,y,X,Y,dx=134,dy=130;
setcolor(color);
for(i=0;i<=400;i++)
{
x=(int)i%(int)T;
X=x+(int)(i/T)*T+dx+Dx;
if(fabs(x)<10e-1)
{
if(X>150&&X<485 && -A/2+dy>23&&A/2+dy<250)
line(X,-A/2+dy,X,A/2+dy);
}
else if(x>0&&x<=T)
y=-A/T*x+A/2;
Y=y+dy;
if(X>150&&X<485 && Y>23&&Y<250)
line(X,Y,X+1,Y);
}
}
锯齿波效果图
3.5.5:模拟音波。
void MOliWave(int *p) /*模拟音波*/
{
int x,i;
setfillstyle(1,0);
bar(150,23,485,250);
Drowxy(320,135,160,110);
setcolor(random(6)+1);
for(i=1;i<32;i++)*(--p)=*(++p);
*p=random(200)+30;
setfillstyle(1,1);
for(i=0;i<32;i++)
{
bar(150+i*10,*p++,160+i*10,250);
};
sound(*p);
}
效果如下
3.5.6:无规律波。
void NoRuleWave(int zf,int zq) /*无规律波*/
{
double x,bl2,bl4=134;
setfillstyle(1,0);
bar(150,23,485,250);
Drowxy(320,135,160,110);
setcolor(random(6)+1);
for(x=0;x<=164;x+=zq/10)
{
bl2=random(zf)+60;
if(bl2>250)bl2=250;
if(bl2<25)bl2=25;
if(bl4>250)bl4=250;
if(bl4<25)bl4=25;
if(319-x>155)line(320-x,bl4,321-x,bl2);
line(320+x,bl4,321+x,bl2);
bl4=bl2;
/* putpixel(x,zf*sin((x+py)*3.14/zq)+160,4); */
};
}
3.6:波形图函数测量值输出。
3.6.1:正弦波的相关数据输出。
void Podu(int x,int y) /*输出坡度的*/
{
float Po,Po1,sa,sb,sc,sd,a,b;int one,two;
/* 287,292, 重这里到下面是计算和输出坡度的*/
setfillstyle(1,8);
bar(x-3,y,x+50,y+10);
Po=cos((320+py)*3.14/(zq));
if(Po<0)Po=Po*(-1);
one=(int)(Po*1000);two=one%1000;
sa=two/100,sb=two/10-sa*10;sc=two%10;
setcolor(14);
outtextxy(x,y,"0.");
myouttext(x+20,y,sa);
myouttext(x+30,y,sb);
myouttext(x+40,y,sc);
}
void Sine_date() /*画出正弦波的相关数据*/
{
int sa,sb,sc,sd,temp_zq;
if(zf<0)zf=zf*(-1);
else if (zf==0)
zq=0;
if(zq<0)zq=zq*(-1);
if(zf<0)zf=zf*(-1);
if(Chang_zq<0)Chang_zq=Chang_zq*(-1);
if(Chang_zf<0)Chang_zf=Chang_zf*(-1);
sa=Chang_zf/100,sb=Chang_zf/10-sa*10;sc=Chang_zf%10; /*画频率值*/
setcolor(0);
myouttext(35,330,sa);
myouttext(45,330,sb);
myouttext(55,330,sc);
sa=zf/100,sb=zf/10-sa*10;sc=zf%10;
setcolor(14);
myouttext(35,330,sa);
myouttext(45,330,sb);
myouttext(55,330,sc);
sa=Chang_zq*2/100,sb=Chang_zq*2/10-sa*10;sc=Chang_zq*2%10; /*画周期值*/
setcolor(0);
myouttext(122,330,sa);
myouttext(132,330,sb);
myouttext(142,330,sc);
sa=zq*2/100,sb=zq*2/10-sa*10;sc=zq*2%10;
setcolor(14);
myouttext(122,330,sa);
myouttext(132,330,sb);
myouttext(142,330,sc);
temp_zq=(int)((1000.0/(Chang_zq)));
sa=temp_zq*2/100,sb=temp_zq*2/10-sa*10,sc=temp_zq*2%10;
setcolor(0);
outtextxy(207,330,"0.");
myouttext(220,330,sa);
myouttext(230,330,sb);
myouttext(240,330,sc);
temp_zq=(int)(1000.0/(zq));
sa=temp_zq*2/100,sb=temp_zq*2/10-sa*10,sc=temp_zq*2%10;
setcolor(14);
outtextxy(207,330,"0.");
myouttext(220,330,sa);
myouttext(230,330,sb);
myouttext(240,330,sc);
}
3.7:主要操作界面及函数(主函数);
void main()
{
int x,y,z,type,smbo=0,zf=40,zq=36,py=2,*czf,*czq,*cpy,Chang_zf,Chang_zq,Chang_py,Select_bo,Anniu,old_x1=-1,old_x2=-1,Get_lb=0,Get_x1=0,Get_x2=0,Label,ZhouQi,Sa,Sb,Sc; /*smbo 是决定波的类型 默认为正弦波 Old_x 用于测试周期 画掉以前那个*/
int Old_x1=0,Old_y1=0,Old_x2=0,Old_y2=0,Old_x3=0,Old_y3=0,Old_x4=0,Old_y4=0,back_zf,back_zq,back_py,i,temp,shuru=0;
float X;
/*Get_lb用于标签第几次获取X值 label 用于让 X1 X2只画一次和只取一次值*/
back_zf=zf ,back_zq=zq,back_py=py;
/*判断是否有选择!按牛*/
for(i=0;i<34;i++)
MoliNum[i]=random(200)+50;
initgr();
settextstyle(DEFAULT_FONT,HORIZ_DIR,1);
visbilemouse();
setbkcolor(0);
setcolor(7);
Graph_face(); /*画全体固定框架 */
GET_PICCOLOR(220,200,350,330);
while(1) /*进入主程序阶段! 反映用户事件*/
{
mouse(&x,&y,&z,smbo);
if(page==0)
{
flag_copy=0;
Chang_zf=zf,Chang_zq=zq,Chang_py=py,Select_bo=0;
Anniu=Return_button(x,y,z);
switch(Anniu)
{
case 1:
Huifu();DrawButtonDown1(25,420,70,35);
hanzi16(30,430,"监听声卡",10);
smbo=1; break;
case 2:
Huifu();
DrawButtonDown1(110,420,70,35);
hanzi16(115,430,"无规律波",10);
py=py+rand()*10;
MOliWave(MoliNum);
smbo=2;
Select_bo=2;
smbo=2; break;
case 3:
Huifu();DrawButtonDown1(195,420,70,35);
hanzi16(200,430,"展宽",10);
for(X=153;X<=483;X+=0.1)
if((2000*chaZhi(X,0,100,size,13)+200)<250 )
putpixel(X,2000*chaZhi(X,0,100,size,13)+200,0);
size++;
for(X=153;X<=483;X+=0.1)
if((2000*chaZhi(X,0,100,size,13)+200)<250 )
putpixel(X,2000*chaZhi(X,0,100,size,13)+200,2);
break;
case 4:
Huifu();
DrawButtonDown1(280,420,70,35);
hanzi16(285,430,"压缩",13);
smbo=4;
for(X=153;X<=483;X+=0.1)
if((2000*chaZhi(X,0,100,size,13)+200)<250)
putpixel(X,2000*chaZhi(X,0,100,size,13)+200,0);
size--;
for(X=153;X<=483;X+=0.1)
if((2000*chaZhi(X,0,100,size,13)+200)<250 )
putpixel(X,2000*chaZhi(X,0,100,size,13)+200,2);
break;
case 7:
Huifu();
DrawButtonDown1(25,370,70,35);
hanzi16(30,380,"正弦波",10);
NewDraw();
smbo=7;
if(z==2)page=2;
Select_bo=7;
break;
case 8:Huifu();
DrawButtonDown1(110,370,70,35);
hanzi16(115,380,"方波",10);
NewDraw();
smbo=8;
if(z==2)page=2;
break;
case 9:Huifu();
DrawButtonDown1(195,370,70,35);
hanzi16(200,380,"三角波",10);
NewDraw();smbo=9;
if(z==2)page=2;
Select_bo=3;
break;
case 10:Huifu();
DrawButtonDown1(280,370,70,35);
hanzi16(285,380,"锯齿波",10);
NewDraw();
smbo=10;
if(z==2)page=2;
break;
case 11:Huifu();
DrawButtonDown1(365,370,70,35);
hanzi16(370,380,"获取周期",10);
Get_lb=1;
break;
case 12:Huifu();
DrawButtonDown1(450,370,70,35);
randomize();
hanzi16(455,380,"随机种子",10);
NewDraw();zf=random(160);
zq=random(100);
back_zf=zf;
back_zq=zq;
smbo=12;
break;
case 13:
Huifu();
DrawButtonDown1(535,370,70,35);
hanzi16(540,380,"动态波",10);
NewDraw();
smbo=13;
break;
case 16:
smbo=1;
Huifu();
DrawButtonDown1(535,420,70,35);
hanzi16(560,430,"清屏",13);
NewDraw();
break;
case 17:
if(z==1 & Get_lb==1& smbo!=13)
{
Label=0;
setcolor(0);
line(old_x1,25,old_x1,250);
line(old_x2,25,old_x2,250);
old_x1=x;
setcolor(10);
line(x,25,x,250);
Get_x1=x;
Label++;
if(Label==1)Get_lb=0;
Get_lb=2;
}
if(z==1 && Get_lb==2 && smbo!=13 )
{
temp=x-old_x1;
if(temp<0)temp=-temp;
if(temp>20)
{
Label=0;
setcolor(0);
line(old_x2,25,old_x2,250);
old_x2=x;
setcolor(5);
line(x,28,x,250);
Get_x2=x;
Label++;
if(Label==1)Get_lb=0;
ZhouQi=Get_x2-Get_x1;
if(ZhouQi<0)ZhouQi=ZhouQi*(-1);
Sa=ZhouQi/100,Sb=ZhouQi/10-Sa*10,Sc=ZhouQi%10;
if(smbo!=0)
{
setcolor(14);
setfillstyle(1,8);
bar(384,330,416,340);
myouttext(386,330,Sa);
myouttext(396,330,Sb);
myouttext(406,330,Sc);
}
if(Label==7)Get_lb=0;
Get_lb=0;
}
}
break;
case 18:break;
case 19: py=DrRtinP(65,210,x,y,Old_x4,Old_y4,20,back_py,0)*10;Old_x4=x,Old_y4=y; break;
case 20:zf=DrRtinP(565,95,x,y,Old_x1,Old_y1,20,back_zf,1);Old_x1=x,Old_y1=y; break;
case 21:zq=DrRtinP(565,210,x,y,Old_x2,Old_y2,20,back_zq,1);
if(zq==0) zq=1;Old_x2=x,Old_y2=y;break;
case 22:Huifu_1();setcolor(4);hanzi16(35,55,"程序说明",14); line(35,75,95,75);DrawSoftAny(); break;
case 23:Huifu_1();setcolor(4);hanzi16(45,80,"联系我",14);
line(45,100,90,100);system("start www.baidu.com");break;
case 24:exit(0);
}
if(smbo!=13 || Chang_zq!= zq ||Chang_zf!= zf || Chang_py!= py)
{
switch(smbo) /*选定和绘画什么波 */
{
case 2:
py=py+rand()*10;
MOliWave(MoliNum);
break;
case 7:
setlinestyle(0,0,1);
Drowxy(320,135,160,110);
Sinew(zf,zq,py,Chang_zf,Chang_zq,Chang_py);
break;
case 8:
setlinestyle(0,0,1);
Drowxy(320,135,160,110);
RECT(Chang_zf,Chang_zq,Chang_py,Chang_zf,0);
RECT(zf,zq,py,Chang_zf,10);
break;
case 9:
setlinestyle(0,0,1);
Drowxy(320,135,160,110);
ANGLE(Chang_zf,Chang_zq,Chang_py,Chang_zf,0);
ANGLE(zf,zq,py,Chang_zf,10) ;
break;
case 10:
setlinestyle(0,0,1);
Drowxy(320,135,160,110);
juchibo(Chang_zf,Chang_zq,Chang_py,Chang_zf,0);
juchibo(zf,zq,py,Chang_zf,10) ;
break;
default:;
}
Podu(zq,py,Chang_zq,Chang_py);/* 刷新坡度值*/
}
else if(smbo==13)
{
py=py+rand()*10;
hanzi16(220,40,"鼠标不见了按鼠标右键",14);
Podu(zq,py,Chang_zq,Chang_py);/* 刷新坡度值*/
Sinew(zf,zq,py,Chang_zf,Chang_zq,Chang_py);
} }
else if(page==2)
{ if(x>220&&x<350&&y>200&&y<330) ;
else if(x<95&&x>25&&y<405&&y>370&&z==2)
{
type=1;
shuru=1;
}
else if(x<180&&x>110&&y<405&&y>370&&z==2)
{type=2;
shuru=1;
}
else if(x<265&&x>195&&y<405&&y>370&&z==2)
{
type=3;
shuru=1;
}
else if(x<350&&x>280&&y<405&&y>370&&z==2)
{
type=4;
shuru=1;
}
if(shuru==1)
{
Input_Win(&zf,&zq,&py,smbo);
setfillstyle(1,0);
bar(290,235,330,255);
gotoxy(38,16);
scanf("%d",&zf);
setfillstyle(1,0);
bar(290,268,330,288);
gotoxy(38,18);
scanf("%d",&zq);
setfillstyle(1,0);
bar(290,300,330,320);
gotoxy(38,20);
scanf("%d",&py);
COPY_PICXY(220,200,350,330,1);
page=0;
shuru=0;
}
if(type==1) /*如果重新输入了正弦波的值就重画*/
{
setlinestyle(0,0,1);
NewDraw();
Sinew(zf,zq,py,Chang_zf,Chang_zq,Chang_py);
}
else if(type==2) /*如果重新输入了方波的值就重画*/
{
setlinestyle(0,0,1);
NewDraw();
RECT(Chang_zf,Chang_zq,Chang_py,Chang_zf,0);
RECT(zf,zq,py,Chang_zf,10);
}
else if(type==3) /*如果重新输入了三角波的值就重画*/
{
setlinestyle(0,0,1);
NewDraw();
ANGLE(Chang_zf,Chang_zq,Chang_py,Chang_zf,0);
ANGLE(zf,zq,py,Chang_zf,10) ;
}
else if(type==4) /*如果重新输入了锯齿波的值就重画*/
{
setlinestyle(0,0,1);
NewDraw();
juchibo(Chang_zf,Chang_zq,Chang_py,Chang_zf,0);
juchibo(zf,zq,py,Chang_zf,10) ;
}
}
}
free(MoliNum);
getch();
closegraph(); }
补充:再后面的改动中加了一个用于方便显示用户鼠标在示波区的鼠标对应的坐标,所以在后面的制作过程中加了一个用于显示鼠标位置的函数。代码如下:
mousedata(int x,int y) /*用于显示鼠标处的坐标*/
{
int sa=0,sb=0,sc=0;
outtextxy(465,310,"X:");
outtextxy(465,330,"Y:");
setfillstyle(1,8);
bar(485,310,525,340);
setcolor(15);
if (x>=320)
{
x=x-320;
sa=x/100,sb=x/10-sa*10;sc=x%10; /*画正的X 坐标*/
myouttext(495,310,sa);
myouttext(505,310,sb);
myouttext(515,310,sc);
}
else
{
x=320-x;
sa=x/100,sb=x/10-sa*10;sc=x%10; /*画的-X 坐标*/
outtextxy(485,310,"-");
myouttext(495,310,sa);
myouttext(505,310,sb);
myouttext(515,310,sc);
}
if(y>=135)
{
y=y-135;
sa=y/100,sb=y/10-sa*10;sc=y%10; /*画的-y 坐标*/
outtextxy(485,330,"-");
myouttext(495,330,sa);
myouttext(505,330,sb);
myouttext(515,330,sc);
}
else
{
y=135-y;
sa=y/100,sb=y/10-sa*10;sc=y%10; /*画正的正y 坐标*/
myouttext(495,330,sa);
myouttext(505,330,sb);
myouttext(515,330,sc); }}
示波器最终效果
登陆效果
程序主界面
程序说明
总结
通过实验得出如下总结;
(一) 设计的示波器主要的优点为:
(1) 软件开发效率高,可操作性和维护性好。
(2) 在相同的硬件条件下,可以通过修改和增加软件模块,形成新的仪器功能。
(二) 又因为知识水平有限,设计中存在着很多的不足:
影响示波器系统各个性能的因素很多,检测信号的输入,数据采样,数据分析等功能不能实现。
(三) 所设计的虚拟示波器未具有的网络功能:
网络的潮流将资源共享带入一个新的阶段,加速了虚拟仪器与网络技术相结合以及远程监控技术的发展。
示波器的发展是很值得去开阔,但已要学相关的很多知识才能去解决。
至无完美
学习永无止境
展望与发展
PC技术与嵌入式系统融合发展,虚拟仪器的功能得到进一步的发展,例如更多的嵌入式和实时功能。随着PC技术和相关技术的发展,虚拟仪器技术已成为一项前沿学科,代表着仪器发展的最新方向之一,不断的被推向各个新的领域,在新的世纪将大行其道。虚拟仪器设计已经成为测试与仪器技术发展的一个重要方向。随着高速A/D芯片和电路的进一步集成化,可以设想 在不远的将来,一台有安装虚拟仪器软件的标准微机成为一个对功能的测量仪器站,从根本上改变目前专用仪器的研制和生产方式,具有广阔的应用前景和巨大的潜在经济效益,计算机虚拟示波器的成本低,功能全,可扩充性强,较适合应用于工业测试和工业自动化及汽车、轮船、水利和医疗等领域。伴随着计算机技术的进一步发展,虚拟器的开发和研究将会获得更大的推动。
传统台式仪器是由仪器厂家设计并定义好功能的一个封闭结构,它有固定的输入输出接口和仪器操作面板,每种仪器实现一类特定的测量功能,并以确定的方式提供给用户。从一般的仪器设计模型看,一种仪器无非是由数据采集,分析处理,人机交换和显示等几部分功能模块组成的整体。因此,我们可以设想在必要的数据采集硬件和通用计算机支持下,通过软件设计实现仪器的全部功能,这就是虚拟仪器设计的核心。与传统仪器相比,虚拟仪器除了在性能、易用性、用户可制定性等方面也具有突出优势。一方面,目前我国高档台式仪器如数字示波器、频谱分析仪、逻辑分析仪等主要依靠进口,这些仪器加工工艺复杂、对制造水平要求高,生产突破有困难,采用虚拟仪器技术可以通过只采购必要的通用数据采集硬件来设计自己的仪器系统;另一方面,用户可以将一些先进的数字信号处理算法应用于虚拟仪器设计,提供传统台式仪器不具备的功能,而且完全通过软件配置实现多功能集成的仪器设计。因此,可以说虚拟仪器代表了未来测量仪器设计发展的方向。
虚拟仪器技术目前在国外发展很快,以美国国家仪器公司(NI公司)为代表的一批场商已经在市场上推出了基于虚拟仪器技术而设计的商品化仪器厂品。
示波器是在科学研究和工程设计中广泛应用的一种通用仪器。它能把肉眼看不见的电信号变换成看得见的图象,便于人们研究各种电现象的变化过程。利用示波器能观察各种不同信号幅度随时间变化的波形曲线,还可以用它测试各种不同的电量,如电压、电流、频率、相位差、调幅度等等
参考文献
《C语言程序设计案例教程》--------- 北京交通大学出版社(主编:朱健庞倩超)