我是用delphi的,近段却遭遇了vc,所以只好向给位高手求救了,问题其实很简单,只是我是门外汉罢了!
我有三个作cai客件的文档,大部分源码都有,各位分出一点时间帮小弟具体实现后打个包
发给我好吗?一个100分!!!
先谢谢各位了!紧急!关系着拿毕业文凭的大事啊,各位不能见死不救啊!
邮箱地址:[email protected]
文档附件如下:
用Visual C++ 开发中学物理课件
——计算机在中学物理实验教学中的应用
作  者:刘洪涛  刘登鸿   指导教师:杨先卫
(三峡大学理学院物理系972031班  宜昌 443003)摘 要  把计算机应用于物理实验教学领域,着重论述了中学物理实验中计算机模拟实验及
其相关软件的开发,通过实例论证了计算机在物理实验教学中有着广阔的应用空间,并能取得
传统教学手段不能达到的教学效果。               
关键词  Visual C++    物理实验   计算机辅助教学
一.引  言
随着社会的发展,科技的进步,学生学习的内容和信息量不断加大,知识面不断变宽,传统
的教学手段已经严重滞后。半个世纪以来,计算机技术得到了迅猛的发展,特别是上世纪90年
代发展和逐步成熟的多媒体技术已经是现代计算机中不可缺少的功能。多媒体以其图、文、色
、声并茂的形式,可进行视听一体的多种形式的形象化教学,它能将文本、图像、动画和声音
等各种信息进行综合处理和控制,使其根据需要进行有序组合、随机再现,于是,多媒体快速
应用到教学之中,成为计算机科学中的一个重要分支——计算机辅助教学(CAI),弥补了传统
教学在时间、空间方面的不足,既可替代老师进行机械、重复、繁琐的劳动,同时也可作为常
规教学的辅助手段,指导学习者自学或测试,进行求解习题、模拟实验,另外,多媒体教学所
具有的高度交互、信息量巨大、重现力强使其在现代教学中的地位日益不可代替。
本论文即是围绕计算机辅助教学,阐述其在中学物理实验教学中的应用及其CAI课件的编制。
   
二.计算机模拟物理实验
计算机在物理实验中的应用主要表现在三个方面:1)数据处理;2)计算机模拟实验;3)用
计算机采集处理数据。本文着重论述第二个方面的应用。
中学物理教学内容对学生的抽象思维能力提出了较高的要求。学生在分析问题时要借助于实
物的帮助,才能对物理现象进行抽象思维,教材中有相当内容没有与之配套的教具,有些内容
涉及微观或宏观过程,无法在课堂教学中进行演示。由于必要的直观演示不足,所以有些抽象
的物理概念、物理规律未经感性认识阶段而直接上升为抽象的理论,使得抽象思维较弱的中学
生难以认识这复杂的世界,造成了中学物理难教难学的被动局面。用微机作为辅助教学的工具
,则可充分发挥它的优势,在传统演示教具中无法涉及的地方大显身手,弥补学生直观感觉的
不足,减少其抽象思维的难度。
2.1强化直观感觉
微机由于具有彩色作图的功能,所以在演示实验中可利用图形的变化来激起学生的好奇心和
兴趣,并可补充演示实验的不足。例如,在讲解光的折射与反射时,演示实验必须在暗室进行
,学生对单缝及双缝对于干涉条纹形成所起的作用印象不深刻。若用微机来模拟双缝干涉实验
,则无须在暗室就能模拟双缝干涉的原理。学生在荧光屏上看到七条彩色纹所代表的白光,由
狭缝射入并经双缝分成两束相干光源。由于各色光的波长不同,因此在中央由七条彩色条纹组
成的白光,两边出现彩色纹,并且紫光在内红光在外。整个过程都呈现在学生的视野范围内。
光的折射与反射演示实验也和其有相似之处。它不但弥补了常规演示的不足,同时声音和色彩
也给学生留下了直观印象,使学生注意力集中,脑、眼、耳等器官同时工作,加深了感知程度
,提高了学生动态思维的能力。 
2.2建立物理模型
探索物理问题不仅要从实验出发,同时要忽略次要因素,抓住反映过程的主要因素和本质来
形成物理模型,这是研究和学习物理学的一种很重要的方法。在常规演示中,往往无法突出其
主要矛盾,学生容易被表面现象所迷惑。如布朗运动从显微镜中只能观察到花粉颗粒在非常缓
慢的移动,无法观察到它运动的原因在于液体分子对它碰撞的不均匀性。若用微机来模拟,学
生就会看到一个大的花粉颗粒在不停的受到来自各个方向小的液体分子的碰撞,花粉颗粒的移
动正是由于液体分子碰撞的结果。花粉运动的不规则性恰好反映了液体分子运动的不规则性,
使学生牢牢掌握分子杂乱无章的运动正是布朗运动的本质。因此,在一定范围内,直观、具体
有时甚至是夸张的模拟却能协助化抽象为具体,逐步建立起一个个物理模型,最大限度的发挥
学生的创造力和想象力。
2.3展现宏观或微观世界
物理学所研究的物体小到微观粒子,大到宏观天体,有些内容用普通办法无法向学生演示,
虽然可用挂图等来描述,但不能反映其动态的变化规律。在这方面微机的辅助教学是可以发挥
很大的作用的。如在讲解开普勒定律时,微机能为学生描绘一幅天体运动图像。行星绕太阳运
转时,其轨迹为椭圆,太阳位于椭圆的一个焦点上,行星和太阳的连线在相等时间内扫过的面
积相等等概念。在微观领域,可用微机来显示带电粒子在电磁场中的运动、能级的跃迁等现象
,化微观为宏观模拟,这样的演示实验形象生动、活泼,可以调动学生的注意力,使学生在轻
松、愉快的气氛中学习,极大地调动了学生探索自然的兴趣。
2.4显示实验的中间过程
有些演示实验我们一般只能看到其最后的结果,而形成结果的原理却很难反映,给学生带来
了一定困难。例如在讲解简谐运动的图像一节中,用砂漏装置演示实验,教师操作难度大,学
生观察不够直观。如果用微机模拟实验,通过动画技术、色彩与闪烁技巧、多种功能键的使用
,可以很好的体现振子运动过程中位移、回复力、加速度、速度四个矢量的变化过程及相关性
,设计的各个窗口呈动态展示,让学生从动力学、能量等不同的视角,观察简谐振动各物理量
的变化过程。简谐振动的图像,是将弹簧振子运动的实物图、位移图像、速度图像、能量图像
的形成有机的联系起来,计算机在一幅画面中演示这种有联系的连续动画,在教学过程中起到
化解难点、突出重点的作用。
2.5代替危险性较大的实验演示
原子物理中有些实验,由于条件及危险性的限制,不可能用于演示,如核裂变等实验。但如
果用微机来模拟核裂变的内容,可以看到在核裂变时不断有能量释放,使学生有一种身临其景
的感觉。
三.开发平台的介绍
3.1开发软件
随着计算机技术的飞跃发展,在教育领域中计算机辅助教学CAI课件也大量涌现,其中大部分
课件利用多媒体开发工具开发的,如Authorware、方正奥思、Powerpoint等,这些工具极大的
提高了课件开发速度,提高了工作效率,然而这种方式开发的课件,由于没有渗透数学思想和
编程思想,内容较单一,动态模拟效果差,因此我们选择了功能强大的Visual C++和Cool3D来
制作课件。
VC++是microsoft公司推出的最全面和最完善的C/C++程序开发环境,是一套软件开发工具。
它提供了一组各式各样适用C和C++编程风格的相应设计工具。它是一个彻底的程序员级的开发
环境,“可视化”的设计减少了不少的工作量。VC++是一个面向对象、界面友好的dos和Wind
ows程序开发环境。在这个集成环境中开发应用程序时,不一定要手工设计用户界面,而只需
选取菜单命令,VC++系统就会生成一个可实际运行的Windows应用程序框架。此后,程序员就
可利用基于Windows的VC++编辑器,借助Appwinzard建立面向对象的应用程序。
3.2软件环境
硬件环境: P166MHz,32M以上多媒体计算机。
软件环境: Windows 95或 Windows NT4.0及以上操作系统。
四.系统实现的主要技术
4.1封面的设计
多媒体封面一般由四部分组成:动画、图象、文字、声音。且封面应遵循的原则:在主界面
载入的同时载入。封面应清楚的显示软件名称及版本信息,在主载面载入完毕后自动卸出内存
,让出所占用的Windows资源。封面的动画由目前流行的三维文字和动画制作软件Cool3D制作
,由VC++提供系统载入函数,在主窗口载入的同时播放,标题图像由Photoshop制作,放入到
动画之后。封面窗体使用定时器控件设置Timer,在激活主窗体的Activex事件中激活定时器来
自动卸出。
设计思想:通过调用VFWH.LIB、VFW32.LIB 及MCIWNDAPI函数制作一个播放AVI影视文件的多
媒体封面。
封面位于软件的开始部分,因此多媒体控制语句应放在InitLnstance()函数中常规初始化语
句之前.
在相应文件的开始部分加入#INCLUDE”VFW.H”.由于每个文件都包含STDAFXH,所以#include
”vfw.h”语句只能放在一系列#include语句后.
实现代码:
假设已经建立了一个Player项目,则Player.cpp中Instance()函数的相应代码如下:
//CplayerApp initalization
BOOL CplayerApp::Initinstance()
     {//---------多媒体封面---------------
If (!MCIwndRegisterClass())
Renurn FALSE;
HWND m_havi;
m_havi=MCIwndCreat(NULL,AfxGetInstanceHandle();MCIWNDF_NOPLAYBAR|WSMAXIMIZE|WS_V
ISIBLE|WS_POPUP,”  路径”)
If(MCIwndUsetime(m_havi)!=0)
Return FALSE;
Long PlayTime=MCIwndGetLength(m_havi);
MCIwndPlay(m_havi);
::Sleep (PlayTime );
MCIWndDestroy(m_havi);
-------------}
4.2 框架及功能的实现(Dlg)
利用VC++基于对话框的应用程序构造出主框架,运用了标签控件、按钮控件、编辑框控件、
数字滚选控件、图片控件和静态文本控件,通过点击按钮实现界面之间的切换,模拟实验在On
Ok( )函数中实现,利用数字滚选按钮改变程序中的参数值。主框架如下图所示: 

解决方案 »

  1.   

    五. 程序源代码
    5.1  行星绕恒星运动
    void CExample1::OnOK() 
    {
    UpdateData(true);
    CWnd * graphFrame=(CWnd*)GetDlgItem(IDC_STATIC11);
      CDC * pDC=graphFrame->GetDC();
    CBrush newbrush,newbrush1;
    CBrush * oldbrush;
    CPen newpen,newpen1;
    CPen * oldpen;
      newpen.CreatePen(PS_SOLID,1,RGB(0,0,255)); 
    newpen1.CreatePen(PS_SOLID,1,RGB(0,0,0));
    newbrush.CreateSolidBrush(RGB(255,0,0));  
    newbrush1.CreateSolidBrush(RGB(0,0,0));
    oldpen=pDC->SelectObject(&newpen1);
    oldbrush=pDC->SelectObject(&newbrush1);
    pDC->Rectangle(0,0,530,545);
    oldpen=pDC->SelectObject(&newpen);
    oldbrush=pDC->SelectObject(&newbrush);
    int i,j;
    float s,p1=0.8,p2=m_mv/2,x=-80,y=-10,b=1400,A=m_mm/3,m=1,dt=0.01;
    for(i=0;i<43300;i++)
    {
    s=sqrt(x*x*A+y*A*y)*(x*A*x+y*y*A);
    p1=p1-b*x*A*dt/s;p2=p2-b*y*A*dt/s;
    x=(x*A+p1*dt/m)/A;y=(y*A+p2*dt/m)/A;
    pDC->Ellipse(250+x*A,350+y*A,x*A+254,y*A+354);
       pDC->Ellipse(250,350,270,370);
    }
    pDC->SelectObject(oldbrush);
    newbrush.DeleteObject();
    pDC->SelectObject(oldpen);
    newpen.DeleteObject();  
    }
    void CExample1::Ontext() 
    {
    CDialog::OnOK();
      Ctext1 start;
    start.DoModal();
    }
    void CExample1::CreateSpin1()
    {
     CWnd *pEdit1=GetDlgItem(IDC_EDIT1);
    m_Spin1.SetRange(5.0,10.0);
    m_Spin1.SetBuddy(pEdit1);
    TCHAR buf[32];
    int pos=m_Spin1.GetPos();
    wsprintf(buf,_T("%d"),pos);
    CWnd*  pWnd=m_Spin1.GetBuddy();
    if(pWnd!=NULL)
    pWnd->SetWindowText(buf);
    }
    5.2  简谐运动研究
    void CExample2::OnOK() 
    {
    UpdateData(true);
    CWnd * graphFrame=(CWnd*)GetDlgItem(IDC_STATIC22);
      CDC * pDC=graphFrame->GetDC();
      CBrush newbrush;
    CBrush newbrush1;
    CBrush * oldbrush;
    CPen newpen;
    CPen newpen1;
    CPen * oldpen;
      newbrush.CreateSolidBrush(RGB(255,0,0)); 
    newpen.CreatePen(PS_SOLID,1,RGB(0,255,255));
    newbrush1.CreateSolidBrush(RGB(0,0,0)); 
      newpen1.CreatePen(PS_SOLID,1,RGB(0,0,0));
    oldpen=pDC->SelectObject(&newpen1);
      oldbrush=pDC->SelectObject(&newbrush1);
    pDC->Rectangle(0,0,530,545);
      oldpen=pDC->SelectObject(&newpen);
    oldbrush=pDC->SelectObject(&newbrush);
    pDC->MoveTo(30,10); pDC->LineTo(30,140);//画坐标
    pDC->MoveTo(30,160);pDC->LineTo(30,290);
    pDC->MoveTo(30,404);pDC->LineTo(30,534);
    pDC->MoveTo(30,75); pDC->LineTo(510,75);
    pDC->MoveTo(30,225);pDC->LineTo(510,225);
    pDC->MoveTo(30,500);pDC->LineTo(510,500);
    pDC->MoveTo(25,20);
    pDC->LineTo(30,10);pDC->LineTo(35,20);//画箭头
    pDC->MoveTo(25,170); pDC->LineTo(30,160);pDC->LineTo(35,170);
    pDC->MoveTo(25,414); pDC->LineTo(30,404);pDC->LineTo(35,414);
    pDC->MoveTo(500,70); pDC->LineTo(510,75);pDC->LineTo(500,80);
      pDC->MoveTo(500,220); pDC->LineTo(510,225);pDC->LineTo(500,230);
      pDC->MoveTo(500,495); pDC->LineTo(510,500);pDC->LineTo(500,505);
    pDC->SetBkMode(TRANSPARENT);
    pDC->SetTextColor(RGB(255,255,255));
      pDC->TextOut(39,6,"x(cm)"); 
    pDC->TextOut(39,156,"v(cm/s)"); 
    pDC->TextOut(39,400,"E(J)"); 
    pDC->TextOut(510,85,"t(s)"); 
    pDC->TextOut(510,235,"t(s)");          
    pDC->TextOut(510,505,"t(s)");
      pDC->Rectangle(20,297,30,397);
    int  i,j,n;
    float   l=90,v=0,x,k=m_mk,d,x0,t=0.015,m=100,dt=0.055;
    float  s,b,w0,c1=100,c2=10,A=100,w,o=0;
    b=m_mb/m/1,w0=sqrt(k/m);
    for(i=0;i<8000;i++)

      if(b>w0)
      {
    x=c1*exp(-(b-sqrt(b*b-w0*w0))*t*i)+c2*exp(-(b+sqrt(b*b-w0*w0))*t*i); v=c1*(sqrt(
    b*b-w0*w0)-b)*exp(-(b-sqrt(b*b-w0*w0))*t*i)+c2*(-(b+sqrt(b*b-w0*w0)))*exp(-(b+sqr
    t(b*b-w0*w0))*t*i);
      }
      if(b==w0)
      {x=(c1+c2*t*i)*exp(-b*t*i);
      v=c2*exp(-b*t*i)+(c1+c2*t*i)*(-b)*exp(-b*t*i);
      }
       if(b<w0)
      { 
    w=sqrt(w0*w0-b*b);
         x=A*exp(-b*t*i)*cos(w*t*i+o);
         v=-b*A*exp(-b*t*i)*cos(w*t*i+o)-w*A*exp(-b*t*i)*sin(w*t*i+o);  
     } 
        oldpen=pDC->SelectObject(&newpen1);
        oldbrush=pDC->SelectObject(&newbrush1);
      pDC->Rectangle(31,322,500,372);
      for (j=0;j<10;j++)
    {
     d=(x+l+l)/20;
     x0=30+2*j*d;
         s=l+30+x+l;
         oldpen=pDC->SelectObject(&newpen);
         oldbrush=pDC->SelectObject(&newbrush);
     pDC->MoveTo(x0,347);pDC->LineTo(x0+d/2,337);
     pDC->LineTo(x0+1.5*d,357);pDC->LineTo(x0+2*d,347);
     pDC->Ellipse(s-14,333,s+14,361);
     }
     pDC->MoveTo(30,60);
     pDC->SetPixel(30+i*dt,75+x/1.5,255);
       pDC->MoveTo(30,180);
       pDC->SetPixel(30+i*dt,225+v/1,255);
     pDC->MoveTo(30,420);
       pDC->SetPixel(30+i*dt,500-(m*v*v/2+k*x*x/2)/3000,255);
    }
    pDC->SelectObject(oldbrush);
    newbrush.DeleteObject();
    pDC->SelectObject(oldpen);
    newpen.DeleteObject();     
    }
      

  2.   

    void CExample2::Ontext() 
    {
      CDialog::OnOK();
        Ctext2 start;
    start.DoModal();
    }
    5.3  带电粒子在电磁场中运动
    void CExample3::OnOK() 
    {
    UpdateData(true);
    CWnd * graphFrame=(CWnd*)GetDlgItem(IDC_STATIC33);
      CDC * pDC=graphFrame->GetDC();
    CPen newpen;
    CPen newpen1,newpen2;
    CBrush newbrush;
    CBrush *OldBrush;
    CPen * OldPen;
    newpen2.CreatePen(PS_SOLID,1,RGB(0,0,0));
    newbrush.CreateSolidBrush(RGB(0,0,0));
      OldPen=pDC->SelectObject(&newpen2);
      OldBrush=pDC->SelectObject(&newbrush);
    pDC->Rectangle(0,0,530,545);
    newpen.CreatePen(PS_SOLID,1,RGB(0,255,255)); 
    newpen1.CreatePen(PS_SOLID,1,RGB(255,0,0)); 
    OldPen=pDC->SelectObject(&newpen);
    pDC->MoveTo(200,300);
    pDC->LineTo (470,300);
    pDC->MoveTo(200,300);
    pDC->LineTo (200,20);
    pDC->MoveTo(200,300);
    pDC->LineTo (20,480);
    pDC->SetBkMode(TRANSPARENT);
      pDC->SetTextColor(RGB(255,255,255));
      pDC->TextOut(475,300,"y(Ey,By)"); 
    pDC->TextOut(200,15,"z(Ez,Bz)");
    pDC->TextOut(15,480,"x(Ex,Bx)"); 
       float i,m,q,V1,V2,V3,V10=10.0,V20=10.0,V30=10.0,x0=0,y0=0,z0=0,x,y,z,X,Y,dt=0
    .001;
     m=1.0;q=1.0;
       int B1=m_mbx,B2=m_mby,B3=m_mbz,E1=m_mex,E2=m_mey,E3=m_mez;
       for(i=0;i<1500;i++)
     {
       V1=V10+(V20*B3-V30*B2+E1)*dt;
         V2=V20+(-V10*B3+V30*B1+E2)*dt;
         V3=V30+(V10*B2-V20*B1+E3)*dt;
       x=x0+V1*dt; y=y0+V2*dt; z=z0+V3*dt;
    if(E1!=0)
     {
    X=y+z*sqrt(2)/2;Y=x+z*sqrt(2)/2;}
    if(E2!=0)
    {X=z+x*sqrt(2)/2;Y=y+x*sqrt(2)/2;}
    if(E3!=0)
    {X=x+y*sqrt(2)/2;Y=z+y*sqrt(2)/2;}
      X=y+z*sqrt(2)/2;Y=x+z*sqrt(2)/2;
      OldPen=pDC->SelectObject(&newpen1);
        pDC->Ellipse(198+X,298-Y,202+X,302-Y);
      V10=V1;V20=V2;V30=V3;x0=x;y0=y;z0=z;
      delay();
    }
    pDC->SelectObject(OldPen);
    pDC->SelectObject(OldBrush);
    newpen.DeleteObject();  
    newbrush.DeleteObject();  
    }
    5.4  光的反射 折射
    void CExample4::OnOK() 
    {
     UpdateData(true);
     CWnd * graphFrame=(CWnd*)GetDlgItem(IDC_STATIC44);
       CDC * pDC=graphFrame->GetDC();
     CBrush newbrush1,newbrush2;
     CBrush * oldbrush;
     CPen newpen1,newpen2,newpen3,newpen4;
     CPen newpen;
     CPen * oldpen;
       newpen2.CreatePen(PS_SOLID,2,RGB(0,0,0)); 
     newpen3.CreatePen(PS_DASH,2,RGB(255,255,255));
     newpen4.CreatePen(PS_DASH,2,RGB(0,255,255));
       newbrush1.CreateSolidBrush(RGB(0,0,0)); 
     newbrush2.CreateSolidBrush(RGB(0,255,255)); 
       newpen1.CreatePen(PS_SOLID,2,RGB(255,0,0));
       newpen.CreatePen(PS_SOLID,2,RGB(255,255,255));  
     oldpen=pDC->SelectObject(&newpen2);
       oldbrush=pDC->SelectObject(&newbrush1);
     pDC->Rectangle(0,0,530,545);
    oldpen=pDC->SelectObject(&newpen);
     float i=m_mi*2*pi/360,j,x=0,y,n1=m_mn1,n2=m_mn2,n=n2/n1;
       pDC->SetBkMode(TRANSPARENT);
       pDC->SetTextColor(RGB(255,255,255));
       pDC->MoveTo(50,250);pDC->LineTo(450,250);
    pDC->TextOut(460,240,"界面");
       oldpen=pDC->SelectObject(&newpen4);
       oldbrush=pDC->SelectObject(&newbrush2);
    pDC->Rectangle(50,254,450,545);
    oldpen=pDC->SelectObject(&newpen3);
    pDC->MoveTo(250,50);pDC->LineTo(250,450);pDC->TextOut(240,40,"法线 ");
    pDC->TextOut(50,230,"介质1");
    pDC->SetTextColor(RGB(255,0,0));
    pDC->TextOut(50,270,"介质2");
    pDC->TextOut(240,215,"i");pDC->TextOut(260,215,"j");
    pDC->TextOut(255,275,"k");
    pDC->SelectObject(newpen1);   //////折射演示
    for(j=0;j<1000;j++)
    {x++;
      if (x>=50&&x<=250)
    { y=250-((250-x)*cos(i))/sin(i);
          delay();
          pDC->MoveTo(x,y);
          y+=0.5;
          pDC->LineTo(x,y);
        }
       if(x>=250&&x<=450)
     {y=250-((x-250)*cos(i))/sin(i);
     delay();
     pDC->MoveTo(x,y);
     y+=1;
     pDC->LineTo(x,y);
     y=250+(x-250)*sqrt(1-(sin(i)/n)*(sin(i)/n))*n/sin(i);
     delay();
     pDC->MoveTo(x,y);
     y+=1;
     pDC->LineTo(x,y);
     }
    }
    pDC->SelectObject(oldpen);
    pDC->SelectObject(oldbrush);
    newpen.DeleteObject();  
    newbrush1.DeleteObject();     
    }
      

  3.   

    第二个程序:
    计算机在中学物理教学中的应用
    ——简谐振动(II)的研究
    作    者:刘玉萍   安心兰    
    指导老师:陈德彝
    单    位:三峡大学物理系(湖北·宜昌 443003)
    [摘  要]
     本文概述了计算机辅助教学(CAI)基础知识及我国CAI教学的现状,分析了多媒体CAI与传
    统教学的优势和不足,提出了解决现代教育问题的方法,着重从多个方面讨论了物理多媒体课
    件的制作原则,并以简谐振动课件制作为例,论述了计算机在中学物理教学中的应用.
    [关键词] 
    计算机辅助教学   传统教学   实验   简谐振动  课件 
    Application of Computer in Physical Instruction
    of  Middle-school
      ——Researches of Simple Harmonic Motion
    Author    Liu  Yuping    An  Xinlan     
    Tutor     Chen  Deyi 
    Address  Three Gorges University Physical Department
    Yichang City Hubei Province         443003
    Abstract
    In this article, We generally describe the basic knowledge of Computer-Assisted 
    Instruction (CAI) and the state of CAI in today china, And we analyze MCAI and tr
    aditional Instruction, respectively their advantages and disadvantages, the metho
    d to solve the problem of modern education noted .Also we discuss the make princi
    ple of physical multimedia courseware with emphasis from many angles, describe th
    e application of Computer in the Middle-school physical education, and the multim
    edia courseware example of Simple Harmonic Motion in addition.
    Key words
    Computer-Assisted Instruction   Tradition Instruction 
    Experiment     Simple Harmonic Motion     Courseware
      

  4.   

    5.2 简谐振动多媒体CAI课件制作
    (1) 运行环境
    硬件环境:586以上微机系统,内存32M以上
    软件环境:Windows95以上,Authorware5.0, Photoshop5.0  Turbo C Cool 3D
    (2)编写脚本
    本课件是为简谐振动章节教学服务的,既可用于课堂教学也可用于学生复习指导。编写脚本
    ,首先应该设计好软件的整体表现风格,既然是教学软件,则课件制作自始至终风格要统一,
    不宜太花哨;对整章的内容进行归纳总结,提炼出重点内容;围绕每一重点,设计好用哪种表
    现方式,在简谐振动的课件制作中,我们主要用动画的演示来完成;在介绍性的文字处需不需
    要伴以声音取决于课件的表现形式。
    (3)收集素材
    在编写好脚本之后,就应该着手准备素材。收集素材主要是根据脚本的内容,寻找完成项目
    所需要的对象,包括文本、声音、图片以及动画。
    制作简谐振动中学物理课件,需要的素材主要是该章节的内容,及涉及到的需要向读者展示
    的图片动画、声音等文件。故在本章末作者将附以一份完整的简谐振动教案。
    (4) 构建程序框架
    构建程序框架,其实可以和编写脚本,收集素材同步进行。在构建程序框架时,需根据整体
    要求构件出相应的程序流程,并给每个流程附以有意义的命名便于课件制作改动方便。
    5.3 简谐振动教案的编写
    [教学要求]     
    1.理解简谐运动,知道简谐运动是一种理想化模型以及在什么条件下可以把实际发生的振动
    看作简谐运动,知道研究简谐运动的意义。
    2.知道什么是振幅、周期和频率,以及周期和频率的关系。
    3.知道什么是单摆,理解在什么条件下单摆做简谐运动,掌握单摆的周期公式。
    4.理解振动图象的意义。
    5.理解简谐运动中能量转化的情况。
    6.知道阻尼振动、受迫振动和共振。
    [概念与规律]
    1.物体在某一中心位置两侧所做的往复运动叫机械运动。
    2.使物体回到平衡位置的力叫回复力,回复力是根据力的效果来命名的,它可以是各种性质
    的力,也可以是几个力的合力或某个力的分力,它不是什么特殊的力。
    3,物体在跟位移大小成正比,并且方向总指向平衡位置的力作用下的振动叫简谐振动
    其特征:F=-kx  .a=F/m=-(k/m)x
    比例常数k是由振动系统的特征所决定的。
    其中:x为以平衡位置为起点的位移矢量,加速度a的变化与F一致,在平衡位置时最小为零,
    在振动位移最大处最大,振动过程中方向总指向平衡位置,运动速度的大小与加速度的变化恰
    好相反,在平衡位置处,速度最大,在振动位移最大处,速度为零。简谐振动是变加速度运动

    4,振动物体离开平衡位置的最大距离,叫振动的振幅。                     
    5,振子由A点出发经O点运动到A,再由A点经O点回到A点,完成一次全振动。
    6.做简谐振动的物体完成一次全振动所需的时间是一定的,这个时间叫做振动的周期(T)

    7.单位时间内完成的一次全振动的次数叫做振动的频率(f)。
    8.物体的振动频率是由振动物体本身的性质决定的,与振幅无关,所以又叫做固有频率,振
    动的周期叫做固有周期。
    9.简谐振动是一种理想化的振动,一旦供给振动系统一定的能量来使它开始振动,由于机械
    能守恒,它就要以一定的振幅永不停息的振动下去。可是实际上振动系统不可避免地要受到摩
    擦和其他阻力,即受到阻尼作用,振动物体在克服外界阻力做功不断消耗能量的情况下,振幅
    会逐渐减小甚至完全停下来,这种振幅越来越小的振动叫阻尼振动。
    10。如果要使振幅不变,而一直振动下去,应不断地向它们补充损耗的机械能,以使振动物
    体的振幅不变,这种振幅不变的振动叫无阻尼振动。
    11.外力作用下偏离平衡位置后,在系统内部的弹力或重力作用下振动起来,而不再需要其
    他外力的推动,这种振动叫做自由振动。
    12.物体在周期性驱动力作用下的振动叫做受迫振动,这种周期性外力叫驱动力。物体做受
    迫振动的频率等于驱动力的频率,而跟物体的固有频率没有关系。
    13.当驱动力的频率跟物体固有频率相等的时候,受迫振动的振幅最大,这种现象叫做共振
      

  5.   

    [简谐振动实例]
    1.弹簧振子
    演示:以水平方向振动的弹簧振动为例来分析简谐振动的特性
    说明:o点是振子的平衡位置 . A点是振子的平衡位置右侧最大位置处,则A’点是振子平衡
    位置左侧最大位置处。  
    分析上述实验中弹簧振子在一次全振动过程中的位移、回复力、加速度、速度如何变化,并
    填入下表振子的运动 A     0 O     A’ A’    O O     A
    对平衡位置的位移方向怎样?大小如何变化? 方向水平向右,大小不断减小 。 方向水平向
    左,大小不断增大。 方向水平向左,大小不断减小 。 方向水平向右,大小不断增大。
    回复力的方向怎样?大小如何变化?   方向水平向左,大小不断减小 。 方向水平向右,大
    小不断增大。 方向水平向右,大小不断减小 。 方向水平向左,大小不断增大。
    加速度的方向怎样?大小如何变化? 方向水平向左,大小不断减小 。 方向水平向右,大小
    不断增大。 方向水平向右,大小不断减小 。 方向水平向左,大小不断增大。
    速度的方向怎样?大小如何变化? 方向水平向左,大小不断增大。 方向水平向左,大小不
    断减小 。 方向水平向右,大小不断增大。 方向水平向右,大小不断减小 。
    (先给出表格,让学生填写,然后给出正确答案)
    2.单摆
    单摆模型实验演示
    回复力F=-(mg/l)x摆角很小的情况下,单摆所受回复力跟位移成正比 ,方向相反,单摆做简
    谐振动。
    模拟实验:
    单摆做简谐运动的周期跟摆长的平方根成正比,跟重力加速度的平方根成反比,跟振幅,摆
    球的质量无关。T=:2  
    [扩展]  如何确定物体是否作简谐振动的基本步骤:
    i. 分析振动物体的受力情况。
    ii. 确定振动的平衡位置,找出振动的回复力 。
    iii. 比较位移和回复力的方向,写出回复力的表达式。
    讨论:一端挂有重物的弹簧悬挂起来,组成一个竖直方向的弹簧振子,它的振动是否是简谐
    振动?
    解:(1)设重物质量为m,弹簧的倔强系数为k ,质量不计。当重物位于平衡位置时,重物所
    受的合力等于零,设这时弹簧的伸长量为x
    则: kx。=mg                                [1] 
    (2)将重物向下拉一小段距离  ,放手后重物所受的合力:
                F合=K(x.+x)-mg                 [2]
    将[1]式代入[2]式则 
                F合=kx.+kx-mg=mg+kx-mg=kx       
    合力方向向上,而位移方向向下 。
    (3)重物向上运动经平衡位置O ,继续向上运动。当位移为x 时(x<x.),重物所受合力 
    F合=mg-k(x.-x)=mg-kx.+kx=kx
    合力方向向下 ,而位移方向向上。
    (4)可见重物所受的合力F=kx ,由于合力F 的大小跟位移x的大小成正比 ,方向始终相反
     ,所以可以引入负号,即F=-kx                  
    所以竖直方向的弹簧振子的振动是简谐振动  
    [简谐振动图象]
    演示简谐振动的图象
    说明:简谐振动的图象是一条正弦(或余弦)曲线,表示一个质点在各个不同时刻的位移。
    注意:振动图象不是质点的运动轨迹,它只是反映质点的位移随时间变化的规律。简谐振动
    图象反映以下几个物理量:
    (1)任意时刻振动 质点的位移;
    (2)振动A(振动物体离开平衡位置的最大 距离 )
    (3)周期T(振动物体完成一次全振动所需的时间)
    (4)任一时刻加速度 的方向(总是指向平衡位置)
    (5)任一时刻的速度
     [简谐振动的能量]
    演示能量曲线
    分析弹簧振子在振动中能量的转化情况,填写下表(填写增多,减少,不变):
    振子的运动 A       O O       A’ A’      O O       A
    能量的变化  动能 增多 减少 增多 减少
    势能 减少  增多 减少 增多
    总能 不变  不变 不变 不变
    (先给出表格,让学生填写,然后给出正确答案)
    [阻尼振动图象]
    演示阻尼振动图象,输入不同的阻尼参数 ,得出不同的图象(包括位移时间 ,速度时间 ,位移
    速度 ,能量图象).
      

  6.   

    附    录
    C语言源程序
    /*弹簧振子*/
    int gdriver=DETECT,gmode;
    initgraph(&gdriver,&gmode,"d:\\turboc2\\bgi");
    setbkcolor#include "stdio.h"
    #include "stdlib.h"
    #include "math.h"
    #include "graphics.h"
    #include "conio.h"
    #include "dos.h"
    main()
    {int i,j,arrow1[8]={500,58,510,60,500,62,500,58};
    float l=150,x,x0,q=0.01,d;
    setfillstyle(1,1);
    bar(50,210,60,270);
    line(30,60,500,60);
    drawpoly(4,arrow1);
    setfillstyle(1,WHITE);
    floodfill(505,60,WHITE);
    outtextxy(120,50,"A'");
    outtextxy(220,50,"o");
    outtextxy(320,50,"A");
    outtextxy(500,65,"x");    line(50,420,50,120);
    for(i=0;i<20000;i++){setfillstyle(1,4);
    bar(60,150,600,250);
    setlinestyle(3,0,1);
    line(116,50,116,300);
    line(216,50,216,300);
    line(316,50,316,300);
    setlinestyle(0,0,1);
    x=l+60+6+100*cos(i*q);
    d=(x-66)/20;
    for(j=0;j<10;j++)
    {x0=60+j*d*2;
    setcolor(15);
    line(x0,240,x0+d/2,230);
    line(x0+d/2,230,x0+1.5*d,250);
    line(x0+1.5*d,250,x0+2*d,240);}
    setfillstyle(1,15);
    fillellipse(x,240,6,6);
    if(x>216)
     {line(374-x/2,195,158+x/2,195);
      line(374-x/2,210,158+x/2,210);
      line(377-x/2,193,374-x/2,195);  line(377-x/2,197,374-x/2,195);
      line(155+x/2,208,158+x/2,210);  line(155+x/2,212,158+x/2,210);
      outtextxy(266,185,"F");
      outtextxy(266,200,"x");}
      else if(x<216)
     {line(58+x/2,195,274-x/2,195);
      line(58+x/2,210,274-x/2,210);
      line(271-x/2,193,274-x/2,195);  line(271-x/2,197,274-x/2,195);
      line(61+x/2,208,58+x/2,210);    line(61+x/2,212,58+x/2,210);
      outtextxy(166,185,"F");
      outtextxy(166,200,"x");}
    if(kbhit()) break;
    delay(10);
    }closegraph();
    } /*振动图象*/
    #include "stdio.h"
    #include "stdlib.h"
    #include "math.h"
    #include "graphics.h"
    #include "conio.h"
    #include "dos.h"
    main()
    {int i,j;
    float l=150,x,x0,x1,V,q=0.02,d;
    int gdriver=DETECT,gmode;
    initgraph(&gdriver,&gmode,"d:\\turboc2\\bgi");
    setbkcolor(4);
    setfillstyle(1,1);
    bar(50,210,60,270);
    for(i=0;i<2000;i++){setfillstyle(1,4);
    bar(60,200,600,280);
    x=l+60+6+100*cos(i*q);
    x1=100*cos(i*q); V=-100*sin(i*q);
    d=(x-66)/20;
    for(j=0;j<10;j++)
    {x0=60+j*d*2;
    setcolor(15);
    line(x0,240,x0+d/2,230);
    line(x0+d/2,230,x0+1.5*d,250);
    line(x0+1.5*d,250,x0+2*d,240);
    setfillstyle(1,15);
    fillellipse(x,240,6,6); line(10,120,620,120);line(10,120,10,10);
    putpixel(i/4+10,x1/2+120,9); putpixel(i/2+10,V/2+120,14);
    putpixel(x1/2+120,V/2+120,18);
    }if(kbhit()) break;
    delay(100);
    }closegraph();
    } /*位移时间、速度时间、位移速度、能量图象*/
     #include"stdio.h"
     #include"math.h"
     #include"stdlib.h"
     #include"graphics.h"
     #include"conio.h"
     #include"dos.h"
     main()
      { int i,j,n;
        float b=-0.005;
        int gdriver=DETECT,gmode;
        initgraph(&gdriver,&gmode,"");
        for(n=0;n<85;n++)
    { float l=150,x=0,v=10.0,k=1.0,d,x0,t=0.15,m=100,s,dt=0.075;
      gotoxy(1,1);
      setfillstyle(1,4);
      bar(0,0,640,480);
      b=b+0.005;
      cleardevice();
      setbkcolor(4);
      printf("Please enter resistance coefficient is:%f",b);
      setfillstyle(1,1);
      bar(10,250,20,350);
      line(30,20,30,140);outtextxy(10,20,"X");
      line(25,22,30,20);line(35,22,30,20);
      line(30,150,30,250);outtextxy(10,130,"V");
      line(25,152,30,150);line(35,152,30,150);
      line(30,355,30,460);outtextxy(10,355,"E");
      line(25,357,30,355);line(35,357,30,355);
      line(30,80,600,80);outtextxy(590,90,"t");
      line(598,85,600,80);line(598,75,600,80);
      line(30,200,600,200);outtextxy(590,210,"t");
      line(598,205,600,200);line(598,195,600,200);
      line(30,460,600,460);outtextxy(590,470,"t");
      line(598,455,600,460);line(598,465,600,460);
      line(500,230,500,370);outtextxy(490,240,"v");
      line(495,232,500,230);line(505,232,500,230);
      line(380,300,620,300);outtextxy(610,310,"x");
      line(618,305,620,300);line(618,295,620,300);
      for(i=0;i<7000;i++)
         {
     for(j=0;j<10;j++)
       {   setwritemode(1);
          x0=20+j*d*2;
          setcolor(15);
          line(x0,300,x0+d/2,290);
          line(x0+d/2,290,x0+1.5*d,310);
          line(x0+1.5*d,310,x0+2*d,300);
          setfillstyle(1,15);
          fillellipse(s,300,10,10);
       }
          for(j=0;j<10;j++)
     {
        x0=20+j*d*2;
        setcolor(15);
        line(x0,300,x0+d/2,290);
        line(x0+d/2,290,x0+1.5*d,310);
        line(x0+1.5*d,310,x0+2*d,300);
        setfillstyle(1,15);
        fillellipse(s,300,10,10);
      }
        setfillstyle(1,4);
                        bar(s-12,290,s+11,310);
       v=v-k*x*t/m-b*v*t;
         x=x+v*t;
         s=l+40+x;
         d=(s-40)/20;    putpixel(30+dt*i,80+x/2,1);
       putpixel(30+dt*i,200+v*2.5,15);
       putpixel(30+dt*i,460-(v*v*m/2+k*x*x/2)/50,2);
       putpixel(374+s/1.5,v*6+300,15);
       if(kbhit())
       {
         break;
       }
       }
    if(getch()==27)
    break;
       }
         closegraph();/*单摆*/#include"stdio.h"
    #include"dos.h"
    #include"graphics.h"
    #include"conio.h"
    #include"stdlib.h"
    #include"math.h"
    main()
    {
     int x,y,x0,y0,x2,y2,i;
     double l=400,l0=200;
     float q=0.018,q0=0.029;
     int gdriver=DETECT,gmode;
     initgraph(&gdriver,&gmode,"");
     setbkcolor(BLACK);
     for(i=0;i<20000;i++)
     {
      x=50*cos(i*q);  x0=50*cos(i*q0);
      y=sqrt((l*l-x*x));   y0=sqrt((l0*l0-x0*x0));
      line(300,50,340,50); line(140,50,180,50);
      line(320,50,x+320,y+50); line(160,50,x0+160,y0+50);
      fillellipse(x+320,y+50,6,6);    fillellipse(x0+160,y0+50,6,6);
      cleardevice();
      if(kbhit())  break;
     }
      getch();
     closegraph();
    }
      

  7.   

    第三个程序:
    交通灯管理系统
    摘要
    在系统设计中,我们应用了面向对象的思想并利用C++予以具体实现。在平台的选择上,考虑到DOS的局限性,我们选择了win32,具体利用了windows所提供的系统服务(timer),用以代替8254的使用,降低了编程的难度,同时提高了程序的可读性。并成功地达到系统需求。关键词
    C++, Timer, Object-Oniented, 8255, 8254,Traffic Light Manage概述
    1.在系统设计初期,我们考虑到程序的可扩展性,清晰地把系统分为了三层(Three-Tier)
     
    底层:负责硬件通信,初始化8255并读写端口。
    中间层:(逻辑层)负责交通灯的具体管理
    用户层:负责用户界面管理。具体地,lateralcar,arterycar类负责汽车计数和显示。cross负责
    显示十字路口,lightgroup类保存了六个light类的指针,以此来代理light类的操作(LightOn,LightDown)2.win32程序是靠事件驱动,本系统利用系统服务timer事件来驱动程序运行。具体地,我们定义了三个Timer:
    1. Timer1到达时,系统读写8255端口A,B得到用户输入的当前汽车状态。
    2. 用Timer2,Timer3来分别精确定时3秒和25秒。
    3. 当Timer2,Timer3到达时,改变lightgroup的状态,并向windows请求屏幕重画。设计要求
    1. 分两排显示6个灯
       干线:红,绿,黄
       支线:红,绿,黄
    2.用k1~k8模拟车流量
    k1~k4模拟支线车流量
    k5~k8模拟干线车流量
       发光小灯L1~L3代表支线红,黄,绿
    L4~L6代表干线红,黄,绿
    3.交通管理
    〈1〉 允许干线上车通过绿灯亮,支线红亮(相应也在CRT上显示)
    〈2〉 支线上的车N>=3,干线由绿→黄,停3秒→红
                            支线由红→绿
    〈3〉 当支线绿亮25秒后,无车来由绿→黄停3秒→红亮
    同时干线由红→绿
    〈4〉 当支线绿亮时而无车,则支线上绿→黄停3秒→红
    干线由红变绿。
      

  8.   

    资料
    一、可编程并行接口芯片8255A-5
       8255A-5应用最广的可并行接口芯片之一,它是8255和8255A的改进型产品,除在时间上有所缩短,使之能适应更高的工作频率外,其他参数基本相同,下面将介绍期基本功能及初始化编程。
    1. 外设接口部分
       这部分有A、B、C三个8位的端口寄存器,通过24根口线PA7~PA0 、PB7~PB0、PC7~PC0与外部设备相连。其中C口又分上半部和下半部。这24根口线都是双向三态结构,A、B、C三端的工作方式和输入\输出状态可通过程序来选择。
        8255工作在方式0下其三个端口A、B、C都作为基本的输入\输出口,都有输入的缓冲和输出的锁存功能。
    2.微机接口部分
    这部分主要是保证微处理器对8255的编程、监视和提供数据通道。
    数据缓冲器  这是一个8位的双向三态缓冲器,所有的数据输入输出及控制信息都是通过它传送的。
    读写控制逻辑  有6根线控制线,控制8255的内部各种操作。其具体控制过程见硬件课本。
    3初始化编程
      8255的工作方式和接口功能是cpu通过把控制写入控制积存器来实现,通常把这个过程叫初始化编程,简称初始化。
       8255的方式控制字规定了各个口的工作方式和输入\输出状态。由于本实验的只用了0方式,所以初始化程序非常简单,如下程序清单:
    MOV  DX , 20BH
    MOV  AL , 10000010b
    OUT  DX , AL 
     其中 A 、B、C分别0方式下的输出、输入、输出状态。二、定时器
    TIMER
    A timer is an internal routine that repeatedly measures a specified interval, in milliseconds
    About Timers 
    Each time the specified interval (or time-out value) for a timer elapses, the system notifies the window associated with the timer. Because the accuracy of a timer depends on the system clock rate and how often the application retrieves messages from the message queue, the time-out value is only approximate. 
    Using Timers
    Creating a timer 
    The following example uses the SetTimer function to create two timers. The first timer is set for every 10 seconds, the second for every 5 minutes. // Set two timers. 
    SetTimer(hwnd,             // handle to main window 
        IDT_TIMER1,            // timer identifier 
        10000,                 // 10-second interval 
        (TIMERPROC) NULL);     // no timer callback 
     
    SetTimer(hwnd,             // handle to main window 
        IDT_TIMER2,            // timer identifier 
        300000,                // 5-minute interval 
        (TIMERPROC) NULL);     // no timer callback 
    To process the WM_TIMER messages generated by these timers, add a WM_TIMER case statement to the window procedure for the hwnd parameter. 
    case WM_TIMER: 
        switch (wParam) 
        { 
            case IDT_TIMER1: 
                // Process the 10-second timer.  
                return 0; 
             case IDT_TIMER2: 
                // Process the 5-minute timer. 
                return 0; 
        } 
    An application can also create a timer whose WM_TIMER messages are processed not by the main window procedure but by an application-defined callback function, as in the following code sample, which creates a timer and uses the callback function MyTimerProc to process the timer's WM_TIMER messages. // Set the timer. 
    SetTimer(hwnd,                // handle to main window 
        IDT_TIMER3,               // timer identifier 
        5000,                     // 5-second interval 
        (TIMERPROC) MyTimerProc); // timer callback 
    The calling convention for MyTimerProc must be based on the TimerProc callback function.Destroying a timer
    Applications should use the KillTimer function to destroy timers that are no longer necessary. The following example destroys the timers identified by the constants IDT_TIMER1, IDT_TIMER2, and IDT_TIMER3. // Destroy the timers. 
     
    KillTimer(hwnd, IDT_TIMER1); 
    KillTimer(hwnd, IDT_TIMER2); 
    KillTimer(hwnd, IDT_TIMER3); The KillTimer function destroys the specified timer. BOOL KillTimer(
      HWND hWnd,          // handle to window
      UINT_PTR uIDEvent   // timer identifier
    );
    Parameters
    hWnd 
    [in] Handle to the window associated with the specified timer. This value must be the same as the hWnd value passed to the SetTimer function that created the timer. 
    uIDEvent 
    [in] Specifies the timer to be destroyed. If the window handle passed to SetTimer is valid, this parameter must be the same as the uIDEvent value passed to SetTimer. If the application calls SetTimer with hWnd set to NULL, this parameter must be the timer identifier returned by SetTimer. 
    Return Values
    If the function succeeds, the return value is nonzero.If the function fails, the return value is zero. To get extended error information, call GetLastError. Res
    The KillTimer function does not remove WM_TIMER messages already posted to the message queue. 
    Using timer functions to create a mousetrap Timer Reference 
    Timer Messages
    The following message is used with timers.WM_TIMER 
    The WM_TIMER message is posted to the installing thread's message queue when a timer expires. The message is posted by the GetMessage or PeekMessage function. A window receives this message through its WindowProc function. LRESULT CALLBACK WindowProc(
      HWND hwnd,       // handle to window
      UINT uMsg,       // WM_TIMER
      WPARAM wParam,   // timer identifier
      LPARAM lParam    // timer callback (TIMERPROC)
    );
    Parameters
    wParam 
    Specifies the timer identifier. 
    lParam 
    Pointer to an application-defined callback function that was passed to the SetTimer function when the timer was installed. 
    Return Values
    An application should return zero if it processes this message. Res
    You can process the message by providing a WM_TIMER case in the window procedure. Otherwise, the default window procedure will call the TimerProc callback function specified in the call to the SetTimer function used to install the timer.
      

  9.   

    程序说明
    一、系统逻辑实现
    switch (nIDEvent) 
    {
    case 0:
    {
    int artery=0;
        int lateral=0;
    //check8255(artery,lateral);//与硬件通信部分,检测8255端口
    //〈1〉默认情况允许干线上车通过绿灯亮,支线红亮(相应也在CRT上显示)
    if ((m_nLateralCars!=lateral)||(m_nArteryCars!=artery))//汽车数改变?
    {
    m_nLateralCars=lateral;
    m_nArteryCars=artery;
    m_pLateralCar->SetCarNum(m_nLateralCars);
    m_pArteryCar->SetCarNum(m_nArteryCars);
    //〈2〉 支线上的车N>=3,干线由绿→黄,停3秒→红 支线由红→绿
    if ((m_nLateralCars>=3)&&m_bArtery) //支线车数>=3且支线未通,
    {
    m_pLightGroup->arterylightYellowOn();
    SetTimer(3,3000,0);
    }
    //〈4〉 当支线绿亮时而无车,则支线上绿→黄停3秒→红 干线由红变绿。
    if ((!m_bArtery)&&(m_nLateralCars==0))//支线通时主线来车,支线无车,取消25秒的支线时间
    {
    pMainFrame->KillTimer(m_Timer1);
    m_pLightGroup->laterallightYellowOn();
    SetTimer(3,3000,0);
    }
    }
    }
    break; case 3:
    {
    if (m_bArtery)
    {
    KillTimer(m_Timer3);
    m_Timer3=-1;
    m_pLightGroup->arterylightRedOn();
    m_pLightGroup->laterallightGreenOn();
    m_bArtery=false;

    if (m_Timer1!=1) {
    SetTimer(1,1000,0);
    m_nTimeCount=0;
    }
    }
    else
    {
    pMainFrame->KillTimer(m_Timer3);
    m_Timer3=-1;
    m_pLightGroup->laterallightRedOn();
    m_pLightGroup->arterylightGreenOn();
    m_bArtery=true;
    I; }
    }
    break; case 1:  
    {

    // 〈3〉 当支线绿亮25秒后,无车来由绿→黄停3秒→红亮 同时干线由红→绿
    if (m_nTimeCount>=25)//25秒时间到了
    {
    pMainFrame->KillTimer(m_Timer1);
    if(!m_bArtery)
    {
    if(m_nArteryCars!=0) //主干道有车
    {
    m_pLightGroup->laterallightYellowOn();
    SetTimer(3,3000,0);
                    }
    else
    {
    if(m_nLateralCars==0)//支线没车
    {
    m_pLightGroup->laterallightYellowOn();
    SetTimer(3,3000,0);
    }
    }
         }
    }
    }
    break; }
    }二.类说明
    //class light;//单个灯
    //class lightgroup;//交通灯组,共六个灯,分别表示干线和直线的交通灯
    //class cross;//马路
    //class car; //汽车
    //class arterycars : public car;//干线汽车
    //class lateralcars : public car;//直线汽车light
        light(CPoint,int,int,CDC*); void LightDown(); void LightOn();
    CPoint centre; //灯的圆心坐标 int r; int color; CDC* hdc;
    lightgroup
    lightgroup(CPoint,int); void draw(CDC *);        //显示函数 void laterallightYellowDown(); void laterallightYellowOn(); void laterallightGreenDown(); void laterallightGreenOn(); void laterallightRedDown(); void laterallightRedOn(); void arterylightYellowDown(); void arterylightGreenDown(); void arterylightRedDown(); void arterylightYellowOn(); void arterylightGreenOn(); void arterylightRedOn();
    light * arterylightRed; light * arterylightGreen; light * arterylightYellow; light * laterallightRed; light * laterallightGreen; light * laterallightYellow; CPoint m_mid;//灯组的中点坐标 int m_ra;    //灯的半径 bool b_arterylightRed; bool b_arterylightGreen; bool b_arterylightYellow; bool b_laterallightRed; bool b_laterallightGreen; bool b_laterallightYellow;car
    car(); void SetCarNum(int); virtual void  draw(CDC*);
    int IDB; int xlen; int ylen; CPoint pos; int count;
    arterycars : public car
    arterycars(int Xlen,int Ylen,CPoint p,int bitmap); ~arterycars(); virtual void draw(CDC*);lateralcars : public car
    lateralcars(int Xlen,int Ylen,CPoint p,int bitmap); ~lateralcars(); virtual void draw(CDC*);
    cross
    cross(CPoint,CPoint,CPoint,CPoint,CDC*); ~cross(); void display();
    CPoint p1,p2,p3,p4; CDC* pdc;
    设计问题
    在设计过程中,我们遇到了不少的问题和困难。
    首先,因为我们对win32环境下的GUI编程不够熟悉,在界面设计方面比较吃力。特别是对于当前设备上下文(DC)的对象生存期的问题,事实上各个地方的DC是不相同的。我们的处理方法是把绘图工作集中在OnPaint函数里。
    其次,考虑到程序的并发性,我们没有使用任何软件延时和程序循环结构。完全依靠三个定时器(Timer)驱动。
    第三,在调试过程中,我们遇到8255不能正常工作的情况,走了不少弯路。最后想到利用简单的汇编程序检查8255,发现系统8255已经坏掉,并不是我们程序的问题。心得体会
    附主要程序片断
    1.element.cpp/*************************************/
    /* element.cpp
    /* 交通灯的各种元素类的实现
    /* 前视声名在element.h中
    /* 2002-6-12
    /*************************************/
    #include "stdafx.h"
    #include "element.h"
    /*************************************/
    /* 单个灯类实现
    /*
    /************************************/
    light::light(CPoint p,int ra,int col,CDC* dc)
    {
    centre=p;
    hdc=dc;
    r=ra;
    color=col;
    CPen newpen(PS_SOLID, 1, RGB(0, 0, 0));
    CPen* oldpen= dc->SelectObject(&newpen);
    dc->Ellipse(CRect(p.x-r,p.y-r,p.x+r,p.y+r));
    dc->SelectObject(oldpen);
    }light::~light()
    {
    }void light::LightOn()
    {
    CBrush newbrush(color);
    CBrush* oldbrush=hdc->SelectObject(&newbrush);
    hdc->Ellipse(CRect(centre.x-r,centre.y-r,centre.x+r,centre.y+r));
    hdc->SelectObject(oldbrush);
    }void light::LightDown()
    {
    hdc->Ellipse(CRect(centre.x-r,centre.y-r,centre.x+r,centre.y+r));
    }/*************************************/
    /* 交通灯组类实现
    /*
    /************************************///lightgroup(CPoint p,int ra)
    //入口:
    //CPoint p 灯组的中心坐标
    //int ra 每个灯的半径
    lightgroup::lightgroup(CPoint p,int ra)
    {

    m_mid.x=p.x;m_mid.y=p.y;
    m_ra=ra;
    b_arterylightRed=false;
    b_arterylightGreen=true;
    b_arterylightYellow=false;
    b_laterallightRed=true;
    b_laterallightGreen=false;
    b_laterallightYellow=false;
    }lightgroup::~lightgroup()
    {
    }//draw按照各个灯的情况绘制灯
    //入口:当前的绘图DC
    void lightgroup::draw(CDC *dc)
    { CPoint tem,p;
    p.x=m_mid.x;p.y=m_mid.y;
    int ra=m_ra; tem.x=p.x;tem.y=p.y;//根据灯的半径和灯组的相对坐标计算arterylightGreen灯的坐标
    p.x+=2*ra;p.y-=ra;
    arterylightGreen=new light(p,ra,RGB(0,255,0),dc);//画灯
    if (b_arterylightGreen) //灯的状态?
    arterylightGreen->LightOn();
    else arterylightGreen->LightDown();
    //以下各灯的操作类似 p.x=tem.x;p.y=tem.y;
        p.x-=2*ra;p.y-=ra;
    arterylightRed=new light(p,ra,RGB(255,0,0),dc);
    if (b_arterylightRed) arterylightRed->LightOn();
    else arterylightRed->LightDown();
      

  10.   

    p.x=tem.x;p.y=tem.y;
    p.y-=ra;
    arterylightYellow=new light(p,ra,RGB(255,255,0),dc);
    if (b_arterylightYellow) arterylightYellow->LightOn();
    else arterylightYellow->LightDown(); p.x=tem.x;p.y=tem.y;
    p.x+=2*ra;p.y+=ra;
    laterallightGreen=new light(p,ra,RGB(0,255,0),dc);
    if (b_laterallightGreen) laterallightGreen->LightOn();
    else laterallightGreen->LightDown(); p.x=tem.x;p.y=tem.y;
    p.x-=2*ra;p.y+=ra;
    laterallightRed=new light(p,ra,RGB(255,0,0),dc);
    if (b_laterallightRed) laterallightRed->LightOn();
    else laterallightRed->LightDown(); p.x=tem.x;p.y=tem.y;
    p.y+=ra;
    laterallightYellow=new light(p,ra,RGB(255,255,0),dc);
    if (b_laterallightYellow) laterallightYellow->LightOn();
    else laterallightYellow->LightDown();
    }void lightgroup::arterylightRedOn()
    {
    b_arterylightRed=true;
    arterylightGreenDown();
    arterylightYellowDown();
    }
    void lightgroup::arterylightGreenOn()
    {
    b_arterylightGreen=true;
    arterylightRedDown();
    arterylightYellowDown();
    }
    void lightgroup::arterylightYellowOn()
    {
    b_arterylightYellow=true;
    arterylightGreenDown();
    arterylightRedDown();
    }
    void lightgroup::laterallightRedOn()
    {
    b_laterallightRed=true;
    laterallightGreenDown();
    laterallightYellowDown();
    }
    void lightgroup::laterallightGreenOn()
    {
    b_laterallightGreen=true;
    laterallightRedDown();
    laterallightYellowDown();
    }
    void lightgroup::laterallightYellowOn()
    {
    b_laterallightYellow=true;
    laterallightGreenDown();
    laterallightRedDown();
    }
    void lightgroup::arterylightRedDown()
    {
    b_arterylightRed=false;
    }
    void lightgroup::arterylightGreenDown()
    {
    b_arterylightGreen=false;
    }
    void lightgroup::arterylightYellowDown()
    {
    b_arterylightYellow=false;
    }
    void lightgroup::laterallightRedDown()
    {
    b_laterallightRed=false;
    }
    void lightgroup::laterallightGreenDown()
    {
    b_laterallightGreen=false;
    }
    void lightgroup::laterallightYellowDown()
    {
    b_laterallightYellow=false;
    }/*************************************/
    /* 马路类实现
    /*
    /************************************/
    cross::cross(CPoint t1,CPoint t2,CPoint t3,CPoint t4,CDC* dc)
    {
    p1=t1;p2=t2;p3=t3;p4=t4;
    pdc=dc;
    }
    cross::~cross()
    {
    }
    void cross::display()
    {
    CPen newpen(PS_SOLID, 5, RGB(0, 0, 0));
    CPen* oldpen= pdc->SelectObject(&newpen);
    pdc->MoveTo(p2.x,p1.y);
    pdc->LineTo(p2.x,p2.y); pdc->MoveTo(p1.x,p2.y);
    pdc->LineTo(p2.x,p2.y); pdc->MoveTo(p3.x,p1.y);
    pdc->LineTo(p3.x,p2.y); pdc->MoveTo(p3.x,p2.y);
    pdc->LineTo(p4.x,p2.y); pdc->MoveTo(p1.x,p3.y);
    pdc->LineTo(p2.x,p3.y); pdc->MoveTo(p2.x,p3.y);
    pdc->LineTo(p2.x,p4.y); pdc->MoveTo(p3.x,p3.y);
    pdc->LineTo(p4.x,p3.y); pdc->MoveTo(p3.x,p3.y);
    pdc->LineTo(p3.x,p4.y);

    pdc->SelectObject(oldpen);}
    /*************************************/
    /* 汽车类实现
    /*
    /************************************/
    car::~car()
    {
    }
    car::car()
    {
    count=0;
    }
    void car::SetCarNum(int CarNum)
    {
    count=CarNum;
    }void car::draw(CDC* dc)
    {
    }/**********************/
    //arterycars class
    arterycars::arterycars(int Xlen,int Ylen,CPoint p,int bitmap)
    {
    IDB=bitmap;
    xlen=Xlen;
    ylen=Ylen;
    pos=p;
    }
    arterycars::~arterycars()
    {
    }
    void arterycars::draw(CDC* dc)
    {
    CBitmap bitmap;
    CDC dcmemory;
    bitmap.LoadBitmap(IDB);
    dcmemory.CreateCompatibleDC(dc);
    dcmemory.SelectObject(&bitmap);
    for(int i=0;i<count;i++)
    {
    dc->BitBlt(i*xlen+pos.x,pos.y,xlen,ylen,&dcmemory,0,0,SRCCOPY);
    }
    }
    /****************************************/
    //lateralcars
    lateralcars::lateralcars(int Xlen,int Ylen,CPoint p,int bitmap)
    {
    IDB=bitmap;
    xlen=Xlen;
    ylen=Ylen;
    pos=p;

    }
    lateralcars::~lateralcars()
    {
    }
    void lateralcars::draw(CDC* dc)
    {
    CBitmap bitmap;
    CDC dcmemory;
    bitmap.LoadBitmap(IDB);
    dcmemory.CreateCompatibleDC(dc);
    dcmemory.SelectObject(&bitmap);
    for(int i=0;i<count;i++)
    {
    dc->BitBlt(pos.x,pos.y-i*ylen,xlen,ylen,&dcmemory,0,0,SRCCOPY);
    }
    }
    2. ChildView.cpp
    // ChildView.cpp : implementation of the CChildView class
    //#include "stdafx.h"
    #include "traffic.h"
    #include "ChildView.h"
    #include<conio.h>
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif/////////////////////////////////////////////////////////////////////////////
    // CChildViewCChildView::CChildView()
    {
    m_ScanTimer=0;//扫描定时器
    m_Timer3=-1;//3秒定时器
    m_Timer1=-1;
    m_nTimeCount=0;
    m_nLateralCars=0;//支线汽车数
    m_nArteryCars=0;//主线汽车数
    m_bArtery=true;
    int artery=-1;
    int lateral=-1;

    }CChildView::~CChildView()
    {
    }
      

  11.   

    void CChildView::check8255(int& a, int& l)
    {
    BYTE data,tem;
    a=l=0;
    __asm
    {   
    mov dx,209h;
    in  al,dx;
    mov data,al;
    }

        //data=_inp(520);
    _outp(520,data);//520=208h
    tem=data&15;
    int x=1;
    for(int i=0;i<4;i++)
    {
    if(tem&x)
    {
    l++;
    }
    x=x*2;
    }
    tem=data&240;

    for (i=0;i<4;i++)
    {
    if(tem&x)
    {
    a++;
    }
    x*=2;
    }
    }
    BEGIN_MESSAGE_MAP(CChildView,CWnd )
    //{{AFX_MSG_MAP(CChildView)
    ON_WM_PAINT()
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    /////////////////////////////////////////////////////////////////////////////
    // CChildView message handlersBOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) 
    {
    if (!CWnd::PreCreateWindow(cs))
    return FALSE; cs.dwExStyle |= WS_EX_CLIENTEDGE;
    cs.style &= ~WS_BORDER;
    cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, 
    ::LoadCursor(NULL, IDC_ARROW), HBRUSH(COLOR_WINDOW+1), NULL); m_pLightGroup=new lightgroup(CPoint(300,150),20);
    m_pArteryCar=new arterycars(87,39,CPoint(200,247),IDB_car);
    m_pLateralCar=new lateralcars(87,39,CPoint(110,161),IDB_car);
    // _outp(523,153);//init 8255
    __asm
    {
    mov dx,20bh;
    mov al,10000010b
    out dx,al; }
    return TRUE;
    }void CChildView::OnPaint() 
    {
    CPaintDC dc(this); // device context for painting cross *pCross=new cross(CPoint(0,0),CPoint(100,200),CPoint(200,350),CPoint(640,480),&dc);
    pCross->display(); //绘制马路

    m_pLightGroup->draw(&dc); //绘制交通灯
    m_pArteryCar->draw(&dc);
    m_pLateralCar->draw(&dc);
    CString sztemp;
    sztemp="主线灯";
    ShowText(sztemp,&dc,6,CPoint(380,110));
    sztemp="支线灯";
    ShowText(sztemp,&dc,6,CPoint(380,150));
    if (m_nTimeCount>0)
    {
    sztemp.Format("支线计时:%d",m_nTimeCount);
    ShowText(sztemp,&dc,8,CPoint(240,50));
    }// car* pcar=parterycar; //绘制汽车
    // pcar= new arterycars(50,100,CPoint(100,0),IDB_BITMAP1);//绘制主线汽车
    // pcar->draw(&dc);
    // Do not call CWnd::OnPaint() for painting messages
    }
    void CChildView::OnTimer(UINT nIDEvent,CWnd *pMainFrame)
    {
    switch (nIDEvent) 
    {
    case 0:
    {
    pMainFrame->KillTimer(0);
    artery=lateral=-1;
    check8255(artery,lateral);//与硬件通信部分

    if ((m_nLateralCars!=lateral)||(m_nArteryCars!=artery))//汽车数改变?
    {
    m_nLateralCars=lateral;
    m_nArteryCars=artery;
    m_pLateralCar->SetCarNum(m_nLateralCars);
    m_pArteryCar->SetCarNum(m_nArteryCars);
    InvalidateRect(NULL,true); if ((m_nLateralCars>=3)&&m_bArtery) //支线车数>=3且支线未通
    {
    m_pLightGroup->arterylightYellowOn();
    InvalidateRect(NULL,true);
    if (m_Timer3!=3) m_Timer3=pMainFrame->SetTimer(3,3000,0);
    }

    if ((!m_bArtery)&&(m_nLateralCars==0))//支线通时支线无车,取消25秒的支线时间
    {
    m_nTimeCount=0;
    pMainFrame->KillTimer(m_Timer1);
    m_Timer1=-1;
    m_pLightGroup->laterallightYellowOn();
    if (m_Timer3!=3) m_Timer3=pMainFrame->SetTimer(3,3000,0);
    }
    }
    m_ScanTimer=pMainFrame->SetTimer(0,200,0);
    }
    break; case 3:
    {
    if (m_bArtery)
    {
    pMainFrame->KillTimer(m_Timer3);
    m_Timer3=-1;
    m_pLightGroup->arterylightRedOn();
    m_pLightGroup->laterallightGreenOn();
    m_bArtery=false;
    InvalidateRect(&CRect(CPoint(240,100),CPoint(360,210)),true);
    if (m_Timer1!=1) {
    m_Timer1=pMainFrame->SetTimer(1,1000,0);
    m_nTimeCount=0;
    }
    }
    else
    {
    pMainFrame->KillTimer(m_Timer3);
    m_Timer3=-1;
    m_pLightGroup->laterallightRedOn();
    m_pLightGroup->arterylightGreenOn();
    m_bArtery=true;
    InvalidateRect(&CRect(CPoint(240,50),CPoint(460,210)),true); }
    }
    break; case 1:  
    {
    m_nTimeCount++; if (m_nTimeCount>=25)//25秒时间到了
    {
    m_nTimeCount=0;
    pMainFrame->KillTimer(m_Timer1);
    m_Timer1=-1;
    if(!m_bArtery)
    {
    m_pLightGroup->laterallightYellowOn();
     InvalidateRect(&CRect(CPoint(240,50),CPoint(460,210)),true);
    m_Timer3=pMainFrame->SetTimer(3,3000,0);
            

         }
    }
    InvalidateRect(&CRect(CPoint(240,50),CPoint(460,150)),true); }
    break; }
    }
      

  12.   

    /******************************************/
    /*显示字串
    /*入口:
    /* CString sztext要显示的字符串
    /* CDC *pDC 绘图pdc
    /* int nFont 字体大小
    /* CPoint point 字符串的左上角坐标
    /*******************************************/
    void CChildView::ShowText(CString sztext,CDC *pDC,int nFont,CPoint point)
    {
    TEXTMETRIC tm;
    CFont fonttext;
    CSize sizetext;
    fonttext.CreateFont(-nFont*5,0,0,0,400,false,false,0,ANSI_CHARSET,
    OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
    DEFAULT_PITCH|FF_SWISS,"Arial");
    CFont * pOldFont=(CFont *)pDC->SelectObject(&fonttext);
    pDC->GetTextMetrics(&tm);
    sizetext=pDC->GetTextExtent(sztext);
    pDC->TextOut(point.x,point.y,sztext);
    pDC->SelectObject(pOldFont);
    }