现代计算机接口技术实验.docx

上传人:b****4 文档编号:12197892 上传时间:2023-04-17 格式:DOCX 页数:50 大小:324.94KB
下载 相关 举报
现代计算机接口技术实验.docx_第1页
第1页 / 共50页
现代计算机接口技术实验.docx_第2页
第2页 / 共50页
现代计算机接口技术实验.docx_第3页
第3页 / 共50页
现代计算机接口技术实验.docx_第4页
第4页 / 共50页
现代计算机接口技术实验.docx_第5页
第5页 / 共50页
点击查看更多>>
下载资源
资源描述

现代计算机接口技术实验.docx

《现代计算机接口技术实验.docx》由会员分享,可在线阅读,更多相关《现代计算机接口技术实验.docx(50页珍藏版)》请在冰豆网上搜索。

现代计算机接口技术实验.docx

现代计算机接口技术实验

 

现代计算机接口技术

及MFC程序实现

 

武汉工业学院计算机与信息工程系

目录

 

实验1定时与中断接口程序设计………………………………………………………………………1

实验2操作PC机上的8250实现串行通信………………………………………………………5

实验3基于DLL与HOOK技术的键盘消息拦截与读音……………………………………10

实验4MFC串行通信程序设计…………………………………………………………………………16

实验5DirectShow接口实现视频显示与帧捕获………………………………………………20

实验6基于Socket接口的网络通信MFC程序设计…………………………………………27

 

实验1定时与中断接口程序设计

一实验目的

1.了解定时器/计数器8253、并行I/O接口8255A在PC机中的电路连接方法;

2.学习使用TURBOC++对8253、8255进行编程操作;

3.熟悉拦截PC机中断向量的TC++编程方法。

二实验内容

1.8253、8255在PC/XT机中的电路连接介绍

1.19MHz

PC机启动后,系统设置的初始状态为:

芯片

有关工作方式

初值

运行情况

8253

通道0#:

方式3(方波发生器)

计数初值:

0000H

OUT输出55ms方波至8259的IRQ0

通道2#:

(1KHz)

计数初值:

(1190)

(1KHz方波)

8255

PB0、PB1:

方式0(简单输出)

控制蜂鸣器发声。

0:

不发声,1:

发声

8259

IRQ0:

允许中断

中断类型号:

8

CPU响应8号中断

表中,8253的通道2#的工作方式和计数初值未知,要求自己设置。

2.程序要求

利用TURBOC++开发环境设计程序,实现如下功能:

(1)程序启动时,要求输入定时时间,以秒为单位。

(2)按秒计时,每秒到达时,在屏幕上显示当前为第几秒,同时蜂鸣器发出短促叫声;

(3)当定时时间到,则显示“TimeUp!

”,结束程序。

三实验环境

硬件环境:

PC机一台;

软件环境:

操作系统不限,TURBOC++3.0。

四实验步骤

1.建立源文件

启动TURBOC++3.0,建立Timer.CPP。

保存到D:

\×××(学号)\Timer.CPP;

2.设置TC工作目录

选菜单Options/Directories,第1、2栏保持不变,第3、4栏填写您的文件存放目录,OK。

如此,TC生成的可执行文件等将会存放到此工作目录下。

样例如下:

3.输入源程序

以下源程序仅供参考。

 

#include//支持标准输入输出,如printf()。

#include//支持接口访问、中断向量操作函数

#include//支持exit()函数

#ifdef__cplusplus//定义C++使用的中断函数标识符。

若是×××.C程序,则不需要

#define__CPPARGS...

#else

#define__CPPARGS

#endif

intnTick=0,sec=0,flag=0;

unsignedcharsys_PB,my_PB;

voidinterruptfar(*sys_int_08)(__CPPARGS);//若是×××.C,则函数参数不写

voidinterruptfarmy_int_08(__CPPARGS)//若是×××.C,则函数参数不写

{//8号中断,每55ms中断一次,由8253的0号定时器定时,并向8259IRQ0申请中断

++nTick;

if(tinck==1)outportb(0x61,my_PB);//开始鸣叫

elseif(tinck==3)outportb(0x61,sys_PB);//停止鸣叫

elseif(nTick>18)

{//1second/55ms近似等于18

flag=1;

nTick=0;

sec++;

}

sys_int_08();//调用系统的中断向量

}

//==========================================

voidmain()

{unsignedintTime_up;

printf("PleaseinputUpTime(5--30):

");

scanf("%d",&Time_up);

printf("\n");

if(Time_up<5||Time_up>30)

{printf("InputError!

");

exit

(1);//结束程序

}

outportb(0x63,0x82);//设置8255,PB为输入方式

sys_PB=inportb(0x61);//读取PB口,内容

my_PB=sys_PB|0x03;//将PB口低2位(PB0,PB1)置1

outportb(0x63,0x80);//设置8255,PB为输出方式

//8253通道2,产生1KHz方波,送到扬声器,使扬声器发声

outportb(0x43,0xb6);//CW=10110110B,通道2,先低字节,再高字节,方式3,二进制

outportb(0x42,0xa6);//lowbyte,

outportb(0x42,0x04);//highbyte,0x04a6=1190,f=1.19MHz,out=f/1190=1000Hz

sys_int_08=getvect(0x08);//保存系统的中断向量

setvect(0x08,my_int_08);//设置系统向量

while

(1)

{if(flag==1)

{flag=0;

printf("%d",sec);

if(sec==Time_up)break;

}

}

printf("TimerUp!

\n\n");

outportb(0x61,sys_PB);//恢复系统的PB口状态

setvect(0x08,sys_int_08);//恢复系统的中断向量

}

4.运行程序,再完成如下内容

(1)8253的通道0在程序中起什么作用?

为什么在程序中没有对其进行初始化及赋初值?

(2)修改8253通道0#的初值,使计时精度严格为1秒。

提示:

可采用动态初值,即一秒内的每次中断采用不同的初值,使每次中断得到的时间间隔之和为1000ms。

55ms的定时=65535×1/1.19MHz

(3)my_int_08()函数什么时候被调用?

(4)将main()函数的最后一句注释掉,再执行,会有什么结果?

假定是在纯DOS环境下执行这个程序。

(5)本程序为什么采用DOS环境编写程序,而不采用Windows环境?

六实验报告

实验报告是科学实验中的重要技术文档,应如实记录实验中发生的现象、处理措施和结果。

实验报告的组成一般为:

实验项目名称(要求严格与本指导书一致)、实验日期、场地、采用的软硬件环境,实验者;对于为什么采用此环境,必要时可作出说明。

例如,本实验为什么要采用TC,而不采用VC?

实验目的:

具体写要做成什么,期望得出什么结果。

不要照抄本指导书。

实验过程:

具体写操作的过程,对于源程序,不一定全部写出,但应画出模块图、流程图。

核心代码可写出。

特别要写出实验中碰到的问题及分析、解决办法。

实验结果及分析:

如实写出结果,对结果进行分析,可进一步提出改进、提高的办法。

实验2操作PC机上的8250实现串行通信

一实验目的

1.了解8250在PC机中的电路连接方法;

2.学习使用TURBOC++对8250进行编程操作;

3.利用8259中断实现RS232串行通信。

二实验指导

1.8250内部基本结构简介

为便于理解,以下仅给出8250内部的简化逻辑结构和主要管脚,详情请参阅有关技术资料。

D7…D0

注:

各寄存器旁标注的十六进制数是该寄存器在PC中的I/O地址。

2.8250内部寄存器功能简介

Ø线路控制寄存器LCR

DLAB

SB

SP

EPS

PEN

STB

WLS1

WLS0

数据位数

00:

5;01:

6

10:

7;11:

8

停止位数

0:

1

1:

1.5或2

01:

奇校验

11:

偶校验

×0:

无校验

附加奇偶校验?

0:

不附加

1:

附加

0:

读写RBR、THR

1:

读写除数寄存器

Ø线路状态寄存器LSR

0

TSRE

THRE

BI

FE

PE

OE

DR

接收缓冲器满?

0:

未满

1:

接收奇偶错?

0:

无错

1:

有错

接收格式错?

0:

无错

1:

有错

发送保持空?

0:

不空

1:

发送移位器空?

0:

不空,正在发

1:

空,发完

接收重叠错?

0:

无错;1:

有错

Ø中断允许寄存器IER

0

0

0

0

I0E

I3E

I1E

I2E

1:

允许Modem状态改变中断

1:

允许接收出错中断

1:

允许发送保持器空中断

1:

允许接收缓冲器满中断

Ø中断标识寄存器IIR(只读)

0

0

0

0

0

ID2

ID1E

IP

00:

接收出错中断

01:

接收缓冲器满中断

10:

发送保持器空中断

11:

Modem状态改变中断

有否未决中断?

0:

1:

是何中断?

Ø除数寄存器

用于设置波特率。

波特率=时钟频率÷(16×除数寄存器的值)。

若已知波特率,则:

除数寄存器的值=时钟频率÷(16×波特率)。

ØModem控制寄存器MCR

0

0

0

LOOP

OUT2

OUT1

RTS

DTR

1:

环路检测(自发自收)

1:

数据终端就绪

1:

请求发送

ØModem状态寄存器MSR

RLSD

RI

DSR

CTS

△RLSD

TERI

△DSR

△CTS

读出值为8250芯片的Modem部分4个输入引脚的状态。

“△”表示比较前次的读出值有改变。

3.8250在PC/XT机中的电路连接介绍

主板上有两片8250,分别对应串口1和串口2。

8250(对应COM1)的端口地址为3F8H~3FFH,其中断信号传到8259的IRQ4。

IRQ4的中断类型码为0CH。

8250(对应COM2)的端口地址为2F8H~2FFH,其中断信号传到8259的IRQ3。

IRQ3的中断类型码为0BH。

本实验仅操作串口1对应的8250(对应COM1),实现串行通信。

8259

4.程序要求

利用TURBOC++开发环境设计程序,实现如下功能:

(1)设置8250:

波特率=1200,奇校验,8位数据,1停止位;

按LOOP方式工作,自发自收;

允许接收中断。

(2)拦截8259IRQ4中断,在此中断中接收数据,在程序中显示数据。

(3)将程序改为两机之间通信,一机发送,另一机接收。

三实验环境

硬件环境:

PC机一台;串行通信终接头一个(用于一个串口自发自收);串行通信电缆一根(用于两机之间通信)。

软件环境:

操作系统不限,TURBOC++3.0。

四实验步骤

1.输入源程序

(LOOP方式),自收自发实验。

以下源程序仅供参考。

#include

#include

voidinit_RS232();//初始化COM1,包括8250和8259

voidinterruptfarmy_interupt();//本程序的中断响应函数

voidinterruptfar(*old_int_rs232)();//指向系统原来的中断响应函数

unsignedintold_IMR;//保存8259中断屏蔽寄存器IMR的原值,以便程序退出时复原

unsignedcharinput_buf[1024];//定义接收缓冲区

unsignedcharoutput_buf[1024]={0xa1,0xb2,0xc3,0xd4,0xe5,0xf6};//定义发送缓冲区及要发送的数据

unsignedintinput_buf_point;//指向当前存放接收数据的缓冲区位置

unsignedintoutput_buf_point;//指向当前要发送字节的缓冲区位置

intsend_OK;//收发完成标志。

0=收发未完成,1=收发完成

intoutput_bytes=6;//应发送的字节数,设要发送6个字节

voidmain()

{inti;

clrscr();//清屏

init_RS232();//设置8250、8259的初始化值

send_OK=0;//先置为0,表示收发未完成。

for(;;){

printf("Pressanykeytosend,\"q\"toexit\n\n");

if(getch()=='q')break;

printf("SendingData:

");//先把待发送的数据显示出来

for(i=0;i

printf("%02x",output_buf[i]);

};

printf("\n");

output_buf_point=0;//目前已发送了0个数据

input_buf_point=0;//目前收到0个数据

outportb(0x3f8,output_buf[output_buf_point++]);//发送第一个字符,后续字符将在前一个

//字符引起的中断响应中发送;

while(!

send_OK);//等待收发完成(收发工作在中断函数中进行)

printf("recevingData:

");//收发完成,把收到的数据显示出来

for(i=0;i

printf("\n\n");

}

outportb(0x21,old_IMR);//将8259的中断屏蔽寄存器IMR复原

setvect(0x0c,old_int_rs232);//将COM1的中断向量复原

}

voidinit_RS232()//8250、8259初始设置函数

{inti;

disable();//由于要修改系统的中断方式,故先关中断,保证下面的操作不影响系统工作

outportb(0x3fb,0x80);//10000000,写8250控制字,允许改动波特率

outportb(0x3f8,0x60);//设置波特率=1200bps.8250的时钟=1.8432MHz,除数=0060H=92,

outportb(0x3f9,0x00);//故波特率=1.8432/(16*92)=0.001252Mbps=1252bps.

outportb(0x3fb,0x2b);//00101011,再写控制字,锁定波特率,奇校验,8位数据,1停止位

outportb(0x3fc,0x13);//00010011,写Modem控制字,LOOP=1,RTS=1,DTS=1

outportb(0x3f9,0x05);//设置中断允许寄存器IER,允许接收中断

old_int_rs232=getvect(0x0c);//保存系统原中断向量。

COM1的中断类型码=12

setvect(0x0c,my_interupt);//将COM1的中断向量改为指向本程序中的中断函数

old_IMR=inportb(0x21);//读8259中断屏蔽寄存器IMR,其I/O地址为21H

i=old_IMR&0xef;//允许IRQ4中断,其他中断源维持系统的原设置不变

outportb(0x21,i);

outportb(0x20,0x20);//置位OCW2中的EOI,使中断服务寄存器自动清零,避免中断重复响应

enable();

}

voidinterruptmy_interupt()//COM1中断服务程序

{unsignedintcom_state;

unsignedintdata;

com_state=inportb(0x3fd);//读线路状态寄存器LSR

com_state=com_state&0x0007;

if(com_state==0x0001){//接收器满

data=inportb(0x3f8);//读取接收缓冲器

input_buf[input_buf_point++]=data;//将读得的数据存放到接收缓冲区

if(output_buf_point

data=output_buf[output_buf_point++];//从发送缓冲区取得要发送的数据

outportb(0x3f8,data);//发送1字节

}

elsesend_OK=1;

}

//else{//接收出错,处理略

//}

outportb(0x20,0x20);//置位8259的OCW2中的EOI位,使中断服务寄存器自动清零,避免中断重复响应

}

2.运行程序,再完成如下内容

(1)改为7位数据格式发送,观察结果。

(2)修改程序,实现两机通信。

实验3基于DLL与HOOK技术的键盘消息拦截与读音

一实验目的

1.了解MFCDLL动态连接库的编程方法;

2.了解HOOK技术和回调函数的运行机制;

3.学习MFC中加载动态连接库的方法。

二实验指导

1.HOOK的基本概念

在Windows下,当硬件或软件产生中断时,系统会发送一个消息给用户程序。

因此,用户程序一般不使用中断,而是采用拦截系统消息的方法。

为了拦截不属于本应用程序的消息,拦截程序必须得到系统的认可,由系统安装成全局运行。

HOOK即通常所说的钩子。

实际上,HOOK就是上面所说的消息拦截程序段。

通过系统调用,把它挂入系统。

每当HOOK所希望的消息发出,在没有到达目的窗口前,HOOK程序就先捕获该消息,得到控制权。

HOOK程序先处理该消息,再向系统传递该消息。

也可以丢弃该消息。

系统维护着一个HOOK链,最近安装的HOOK总放在链的开始,从而得到优先执行。

全局HOOK必须在DLL(动态连接库)中。

2.HOOK函数的形式及其安装方法

HOOK函数在程序中应为全局函数,即:

HOOK函数不应写在一个类中。

HOOK函数是一个消息响应函数,由系统调用,应以回调函数的形式出现,其格式为:

LRESULT_declspec(dllexport)_stdcallCALLBACKKeyboardProc(

intnCode,//若为HC_ACTION,说明后两参数含有击键的消息

WPARAMwParam,//虚键码

LPARAMlParam//击键的有关信息,如重复次数等

写好HOOK函数后,应进行安装,才能得到系统的回调。

安装HOOK的函数为:

HHOOKSetWindowsHookEx(

intidHook,//钩子的类型,按键为WH_KEYBOARD

HOOKPROClpfn,//钩子函数的地址

HINSTANCEhMod,//包含钩子函数的模块句柄

DWORDdwThreadId//指定监视的线程。

若为NULL,则为全局钩子

);

3.程序要求

运用MFC开发环境设计程序,实现如下功能:

(1)编写含有按键HOOK的DLL,要求当按键时,能读出按键名称

(2)编写安装DLL的应用程序。

三实验环境

硬件环境:

PC机一台;

软件环境:

WindowsXP操作系统,VC++6.0,26段声音文件A.WAV,……,Z.WAV。

四实验步骤

1.建立DLL

(1)启动VC++,选File\New,在Project选卡中按如下操作:

(2)进入MFCAppWizard_step1of1,按如下操作:

(3)在KeyHook.h文件中添加代码(见粗体字部分):

……

LRESULT_declspec(dllexport)_stdcallCALLBACKKeyboardProc(

intnCode,

WPARAMwParam,

LPARAMlParam

);

BOOL_declspec(dllexport)_stdcallinstallhook();

classCKeyHookApp:

publicCWinApp

{

……

(4)在KeyHook.cpp文件中添加代码(见粗体字部分):

#include"stdafx.h"

#include"KeyHook.h"

#include"mmsystem.h"

#ifdef_DEBUG

……

#endif

#pragmadata_seg(".SHARDAT")

staticHHOOKhkb=NULL;//定义HOOK句柄

#pragmadata_seg()

HINSTANCEhInst;//定义本实例的句柄

BOOL_declspec(dllexport)_stdcallinstallhook()//安装HOOK的函数

{

hkb=SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc,hInst,0);

returnTRUE;

}

BOOL_declspec(dllexport)UnHook()//卸载HOOK的函数

{

BOOLunhooked=UnhookWindowsHookEx(hkb);

returnunhooked;

}

LRESULT_declspec(dllexport)_stdcallCALLBACKKeyboardProc(//HOOK回调函数

IntnCode,WPARAMwParam,LPARAMlParam)

{

if(((DWORD)lParam&0x40000000)&&(HC_ACTION==nCode))

{

if(wParam>='A'&&wParam<='Z'){

charKeyName[20],temp[10];

strcpy(KeyName,"sound\\");

temp[0]=wParam;

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

当前位置:首页 > 工程科技 > 能源化工

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

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