1、现代计算机接口技术实验现代计算机接口技术 及MFC程序实现武汉工业学院计算机与信息工程系目 录实验1 定时与中断接口程序设计1实验2 操作PC机上的8250实现串行通信5实验3 基于DLL与HOOK技术的键盘消息拦截与读音10实验4 MFC串行通信程序设计16实验5 DirectShow接口实现视频显示与帧捕获20实验6 基于Socket接口的网络通信MFC程序设计27实验1 定时与中断接口程序设计一 实验目的1了解定时器/计数器8253、并行I/O接口8255A在PC机中的电路连接方法;2学习使用TURBO C+对8253、8255进行编程操作;3熟悉拦截PC机中断向量的TC+ 编程方法。二
2、 实验内容18253、8255在PC/XT机中的电路连接介绍1.19MHz PC机启动后,系统设置的初始状态为:芯片有关工作方式初值运行情况8253通道0#:方式3(方波发生器)计数初值:0000HOUT输出55ms方波至8259的IRQ0通道2#:?(1KHz)计数初值:?(1190)?(1KHz方波)8255PB0、PB1:方式0(简单输出)控制蜂鸣器发声。0:不发声,1:发声8259IRQ0:允许中断中断类型号:8CPU响应8号中断 表中,8253的通道2#的工作方式和计数初值未知,要求自己设置。2程序要求利用TURBO C+开发环境设计程序,实现如下功能: (1)程序启动时,要求输入定
3、时时间,以秒为单位。 (2)按秒计时,每秒到达时,在屏幕上显示当前为第几秒,同时蜂鸣器发出短促叫声; (3)当定时时间到,则显示“Time Up!”,结束程序。三 实验环境硬件环境:PC机一台;软件环境:操作系统不限,TURBO C+3.0。四 实验步骤1建立源文件启动TURBO C+3.0,建立Timer.CPP。保存到D: (学号)Timer.CPP;2设置TC工作目录选菜单Options/Directories,第1、2栏保持不变,第3、4栏填写您的文件存放目录,OK。如此,TC生成的可执行文件等将会存放到此工作目录下。样例如下:3输入源程序以下源程序仅供参考。#include /支持标
4、准输入输出,如printf()。#include /支持接口访问、中断向量操作函数#include /支持exit()函数#ifdef _cplusplus /定义C+使用的中断函数标识符。若是.C程序,则不需要 #define _CPPARGS .#else #define _CPPARGS#endifint nTick=0,sec=0,flag=0;unsigned char sys_PB,my_PB;void interrupt far (*sys_int_08)(_CPPARGS); /若是.C,则函数参数不写void interrupt far my_int_08(_CPPARGS)
5、 /若是.C,则函数参数不写/8号中断,每55ms中断一次,由8253的0号定时器定时,并向8259 IRQ0申请中断 +nTick; if(tinck=1) outportb(0x61,my_PB); /开始鸣叫 else if(tinck=3) outportb(0x61,sys_PB); /停止鸣叫 else if(nTick18) / 1second/55ms 近似等于18 flag=1; nTick=0; sec+; sys_int_08(); /调用系统的中断向量/=void main() unsigned int Time_up; printf(Please input Up T
6、ime(5-30): ); scanf(%d,&Time_up); printf(n); if(Time_up30) printf(Input Error!); 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=101101
7、10 B,通道2,先低字节,再高字节,方式3,二进制 outportb(0x42,0xa6); /low byte, outportb(0x42,0x04); /high byte,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(Timer Up!nn);outportb(
8、0x61,sys_PB); /恢复系统的PB口状态 setvect(0x08,sys_int_08); /恢复系统的中断向量4运行程序,再完成如下内容(1) 8253的通道0在程序中起什么作用?为什么在程序中没有对其进行初始化及赋初值?(2)修改8253通道0#的初值,使计时精度严格为1秒。 提示:可采用动态初值,即一秒内的每次中断采用不同的初值,使每次中断得到的时间间隔之和为1000ms。55ms的定时655351/1.19MHz(3)my_int_08()函数什么时候被调用? (4)将main()函数的最后一句注释掉,再执行,会有什么结果?假定是在纯DOS环境下执行这个程序。(5)本程序为
9、什么采用DOS环境编写程序,而不采用Windows环境?六 实验报告 实验报告是科学实验中的重要技术文档,应如实记录实验中发生的现象、处理措施和结果。实验报告的组成一般为:实验项目名称(要求严格与本指导书一致)、实验日期、场地、采用的软硬件环境,实验者;对于为什么采用此环境,必要时可作出说明。例如,本实验为什么要采用TC,而不采用VC?实验目的:具体写要做成什么,期望得出什么结果。不要照抄本指导书。实验过程:具体写操作的过程,对于源程序,不一定全部写出,但应画出模块图、流程图。核心代码可写出。特别要写出实验中碰到的问题及分析、解决办法。实验结果及分析:如实写出结果,对结果进行分析,可进一步提出
10、改进、提高的办法。实验2 操作PC机上的8250实现串行通信一 实验目的1了解8250在PC机中的电路连接方法;2学习使用TURBO C+对8250进行编程操作;3利用8259中断实现RS232串行通信。二 实验指导18250内部基本结构简介 为便于理解,以下仅给出8250内部的简化逻辑结构和主要管脚,详情请参阅有关技术资料。D7D0注: 各寄存器旁标注的十六进制数是该寄存器在PC中的I/O地址。28250内部寄存器功能简介 线路控制寄存器 LCRDLABSBSPEPSPENSTBWLS1WLS0数据位数00:5;01:610:7;11:8停止位数0:1 1:1.5或201:奇校验11:偶校验
11、0:无校验附加奇偶校验?0:不附加1:附加0:读写RBR、THR1:读写除数寄存器 线路状态寄存器 LSR0TSRETHREBIFEPEOEDR接收缓冲器满?0:未满1:满接收奇偶错?0:无错1:有错接收格式错?0:无错1:有错发送保持空?0:不空1:空发送移位器空?0:不空,正在发1:空,发完接收重叠错?0:无错;1:有错 中断允许寄存器 IER0000I0EI3EI1EI2E1:允许Modem状态改变中断1:允许接收出错中断1:允许发送保持器空中断1:允许接收缓冲器满中断 中断标识寄存器 IIR(只读)00000ID2ID1EIP00:接收出错中断01:接收缓冲器满中断10:发送保持器空中
12、断11:Modem状态改变中断有否未决中断?0:无1:有是何中断? 除数寄存器用于设置波特率。波特率=时钟频率(16除数寄存器的值)。若已知波特率,则: 除数寄存器的值=时钟频率(16波特率)。 Modem控制寄存器 MCR000LOOPOUT2OUT1RTSDTR1:环路检测(自发自收)1:数据终端就绪1:请求发送 Modem状态寄存器 MSRRLSDRIDSRCTSRLSDTERIDSRCTS 读出值为8250芯片的Modem部分4个输入引脚的状态。“”表示比较前次的读出值有改变。38250在PC/XT机中的电路连接介绍 主板上有两片8250,分别对应串口1和串口2。8250(对应COM1
13、)的端口地址为3F8H3FFH,其中断信号传到8259的IRQ4。IRQ4的中断类型码为0CH。 8250(对应COM2)的端口地址为2F8H2FFH,其中断信号传到8259的IRQ3。IRQ3的中断类型码为0BH。本实验仅操作串口1对应的8250(对应COM1),实现串行通信。82594程序要求利用TURBO C+开发环境设计程序,实现如下功能: (1)设置8250:波特率=1200,奇校验,8位数据,1停止位; 按LOOP方式工作,自发自收;允许接收中断。 (2)拦截8259 IRQ4中断,在此中断中接收数据,在程序中显示数据。 (3)将程序改为两机之间通信,一机发送,另一机接收。三 实验
14、环境硬件环境:PC机一台;串行通信终接头一个(用于一个串口自发自收);串行通信电缆一根(用于两机之间通信)。软件环境:操作系统不限,TURBO C+3.0。四 实验步骤1输入源程序(LOOP方式),自收自发实验。以下源程序仅供参考。#include #include void init_RS232(); /初始化COM1,包括8250和8259void interrupt far my_interupt(); /本程序的中断响应函数void interrupt far (*old_int_rs232)(); /指向系统原来的中断响应函数unsigned int old_IMR; /保存8259
15、中断屏蔽寄存器IMR的原值,以便程序退出时复原unsigned char input_buf1024; /定义接收缓冲区unsigned char output_buf1024= 0xa1,0xb2,0xc3,0xd4,0xe5,0xf6 ; /定义发送缓冲区及要发送的数据unsigned int input_buf_point; /指向当前存放接收数据的缓冲区位置unsigned int output_buf_point; /指向当前要发送字节的缓冲区位置int send_OK; /收发完成标志。0=收发未完成,1=收发完成int output_bytes=6; /应发送的字节数,设要发送6
16、个字节void main() int i; clrscr( ); /清屏 init_RS232( ); /设置8250、8259的初始化值 send_OK = 0; /先置为0,表示收发未完成。 for( ; ; ) printf(Press any key to send, q to exitnn); if(getch() = q) break; printf(Sending Data: ); /先把待发送的数据显示出来 for(i=0 ; i output_bytes; i+) printf(%02x , output_bufi); ; printf(n); output_buf_poin
17、t = 0; /目前已发送了0个数据 input_buf_point = 0; /目前收到0个数据 outportb(0x3f8,output_bufoutput_buf_point+); /发送第一个字符,后续字符将在前一个/字符引起的中断响应中发送; while(!send_OK) ; /等待收发完成(收发工作在中断函数中进行) printf(receving Data: ); /收发完成,把收到的数据显示出来 for(i=0 ; i output_bytes; i+) printf(%02x , input_bufi); printf(nn); outportb(0x21, old_IM
18、R); /将8259的中断屏蔽寄存器IMR复原 setvect(0x0c, old_int_rs232); /将COM1的中断向量复原void init_RS232() /8250、8259初始设置函数 int i; disable(); /由于要修改系统的中断方式,故先关中断,保证下面的操作不影响系统工作 outportb(0x3fb,0x80); /1000 0000, 写8250控制字,允许改动波特率 outportb(0x3f8,0x60); /设置波特率=1200bps. 8250的时钟=1.8432MHz,除数=0060H=92, outportb(0x3f9,0x00); /故波
19、特率=1.8432/(16*92)=0.001252Mbps=1252bps. outportb(0x3fb,0x2b); /0010 1011,再写控制字,锁定波特率,奇校验,8位数据,1停止位 outportb(0x3fc,0x13); /0001 0011,写Modem控制字,LOOP=1,RTS=1,DTS=1 outportb(0x3f9,0x05); /设置中断允许寄存器IER, 允许接收中断 old_int_rs232 = getvect(0x0c); /保存系统原中断向量。COM1的中断类型码=12 setvect(0x0c, my_interupt); /将COM1的中断向量
20、改为指向本程序中的中断函数 old_IMR = inportb(0x21); /读8259中断屏蔽寄存器IMR, 其I/O地址为21H i = old_IMR & 0xef; /允许IRQ4中断,其他中断源维持系统的原设置不变 outportb(0x21,i); outportb(0x20,0x20); /置位OCW2中的EOI,使中断服务寄存器自动清零,避免中断重复响应 enable();void interrupt my_interupt() /COM1中断服务程序 unsigned int com_state; unsigned int data; com_state = inportb(0x3fd); /读线路状态寄存器LSR com_state = com_state & 0x0007; if(com_state=0x0001) /接收器满 data = inportb(0x3f8); /读取接收缓冲器 input_bufinput_buf_point+ = data; /将读得的数据存放到接收缓冲区 if(output_buf_point =A & wParam=Z) char KeyName20,temp10; strcpy(KeyName,sound); temp0=wParam;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1