⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 -

📁 siglechip_development 单片机开发资料
💻
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0034)http://go.163.com/~czlyzhj/qdq.htm -->
<HTML><HEAD><TITLE>实 例 分 析</TITLE>
<META content="text/html; charset=gb_2312-80" http-equiv=Content-Type>
<META content="MSHTML 5.00.2314.1000" name=GENERATOR></HEAD>
<BODY background="实 例 分 析.files/bj7.jpg">
<P align=center><FONT face=宋体 size=5><B>基于打印机接口的语音型抢答器</B></FONT></P>
<P><FONT face=宋体 size=3>&nbsp;&nbsp;&nbsp; 
很多单位在开展文娱活动时有抢答一项,需要用到抢答器,普通抢答器使用通用集成电路制成,价格高、显示方式简单,性价比较差。而一般单位都有计算机,如果利用计算机就可以很方便地构成一台功能强大而价格十分低廉的抢答器。下面介绍的是笔者实际制作使用的电路。</FONT></P>
<P><FONT face=黑体><B>一、打印口工作原理简介</B></FONT></P>
<P><FONT face=宋体 size=3>&nbsp;&nbsp;&nbsp; 参照图</FONT><FONT size=3>1</FONT><FONT 
face=宋体 size=3>,</FONT><FONT size=3>PC</FONT><FONT face=宋体 
size=3>机上的打印接口共有</FONT><FONT size=3>25</FONT><FONT face=宋体 
size=3>根连线,其中</FONT><FONT size=3>18-25</FONT><FONT face=宋体 size=3>都是地线,因此实际<IMG 
alt="print1.gif (10572 字节)" height=362 src="实 例 分 析.files/print1.gif" 
width=595>共有</FONT><FONT size=3>17</FONT><FONT face=宋体 
size=3>根线,分成三类,</FONT><FONT size=3>8</FONT><FONT face=宋体 
size=3>根数据线,可进行数据输出,</FONT><FONT size=3>5</FONT><FONT face=宋体 
size=3>根状态线,输入,</FONT><FONT size=3>4</FONT><FONT face=宋体 
size=3>根控制线,输出。这三组线分别由打印口的三个寄存器控制,即</FONT><FONT size=3>378H</FONT><FONT face=宋体 
size=3>(数据口),</FONT><FONT size=3>379H</FONT><FONT face=宋体 
size=3>(状态口),</FONT><FONT size=3>37AH</FONT><FONT face=宋体 
size=3>(控制口),只要对这三个地址的寄存器读或写,就可以输入或输出数据。而对这三个地址的读写可以用</FONT><FONT 
size=3>C</FONT><FONT face=宋体 size=3>语言中的函数</FONT><FONT size=3>outportb(int 
port,int data)</FONT><FONT face=宋体 size=3>和</FONT><FONT size=3> inportb(int 
port)</FONT><FONT face=宋体 size=3>来进行,十分方便。</FONT></P>
<P><FONT face=黑体><B>二、硬件电路图</B></FONT></P>
<P><FONT face=宋体 size=3>&nbsp; </FONT></P>
<TABLE border=0 width="100%">
  <TBODY>
  <TR>
    <TD width="44%"><FONT face=宋体 size=3><IMG alt="print2.gif (3518 字节)" 
      height=240 src="实 例 分 析.files/print2.gif" width=320></FONT></TD>
    <TD width="56%"><FONT face=宋体 size=3><IMG alt="qdq.gif (5469 字节)" 
      height=405 src="实 例 分 析.files/qdq.gif" 
width=477></FONT></TD></TR></TBODY></TABLE>
<P><FONT face=宋体 size=3>使用一片廉价的八缓冲器74LS244。<BR>&nbsp;&nbsp;&nbsp; 
74LS244介绍:参考图2,74LS244是三态输出的八缓冲器,由2组、每组四路输入、输出构成。每组有一个控制端,由控制端的高或低电平决定该组数据被接通还是断开,功能表如下表所示。<BR>&nbsp;&nbsp;&nbsp; 
电路介绍(参考图3):将74LS244的控制端<IMG height=22 src="实 例 分 析.files/404.htm" width=21>和<IMG 
height=22 src="E:\Download\esource\实 例 分 析.files\404(1).htm" 
width=25>分别接到打印机控制端口的两个输出端,接到一个端口也可以,但要增加一个反相器,因控制端口有多余线可用,就分别接两根线,可以省些硬件。利用这两个端口分别接通两组中的一组,将两组的输出端对应并联起来,接入打印机的状态端口,这样就可以输入8路数据了。如再接入一片74LS244,可以把输入扩展到16路。打印口控制端的另一根线(<IMG 
height=22 src="E:\Download\esource\实 例 分 析.files\404(2).htm" 
width=63>)接入一个交流晶闸管型光耦(型号为MC3020),光耦的另一端接一个双向晶闸管和一个电灯,按图示,当该口为低电平时,指示灯亮表示可以开始抢答。</FONT></P>
<P><FONT face=黑体 size=3><B>三、程序的编制</B></FONT></P>
<P><FONT face=宋体 size=3>&nbsp;&nbsp;&nbsp; 
这个制作的核心程序编写是非常简单的,只要使打印口的控制端口的低两位分时为低电平,然后分别读入状态端口的数据,就可以判断是否有人抢答了。这部份的程序如下:</FONT></P>
<P><FONT size=3>#define CTRL_H 0x03 /*</FONT><FONT face=宋体 
size=3>第一组切入,此时第</FONT><FONT size=3>16</FONT><FONT face=宋体 size=3>脚为</FONT><FONT 
size=3>0</FONT><FONT face=宋体 size=3>,</FONT><FONT size=3>17</FONT><FONT face=宋体 
size=3>脚为</FONT><FONT size=3>1*/<BR>#define CTRL_L 0x0f /*</FONT><FONT face=宋体 
size=3>第二组切入,此时第</FONT><FONT size=3>17</FONT><FONT face=宋体 size=3>脚为</FONT><FONT 
size=3>0</FONT><FONT face=宋体 size=3>,</FONT><FONT size=3>16</FONT><FONT face=宋体 
size=3>脚为</FONT><FONT size=3>1*/<BR>for(;;)<BR>{ outportb(port_ctrl,CTRL_H); 
/*port_ctrl</FONT><FONT face=宋体 size=3>为控制端口地址,见下说明</FONT><FONT 
size=3>*/<BR>inp_data_h=inportb(port_inp); /*</FONT><FONT face=宋体 
size=3>读输入口数据</FONT><FONT size=3>*/<BR>outportb(port_ctrl,CTRL_L); 
/*</FONT><FONT face=宋体 size=3>切入第二组</FONT><FONT 
size=3>*/<BR>inp_data_l=inportb(port_inp); /*</FONT><FONT face=宋体 
size=3>读输入口数据</FONT><FONT 
size=3>*/<BR>inp_data=((inp_data_h&amp;&amp;0xf0)||(inp_data_l&gt;&gt;4); 
/*</FONT><FONT face=宋体 size=3>两次读到的数据合并</FONT><FONT 
size=3>*/<BR>if(inp_data!=0x77) /*</FONT><FONT face=宋体 size=3>高</FONT><FONT 
size=3>4</FONT><FONT face=宋体 size=3>位输入端无任何脚接地时,应读到</FONT><FONT 
size=3>7</FONT><FONT face=宋体 size=3>,请参考图</FONT><FONT size=3>1</FONT><FONT 
face=宋体 size=3>及电路图</FONT><FONT size=3>3*/<BR>break; /*</FONT><FONT face=宋体 
size=3>每组仅用高</FONT><FONT size=3>4</FONT><FONT face=宋体 size=3>位,两组合并后</FONT><FONT 
size=3>0x77</FONT><FONT face=宋体 size=3>为两次均无任何脚接地</FONT><FONT 
size=3>*/<BR>delay(10); /*</FONT><FONT face=宋体 size=3>延时</FONT><FONT 
size=3>10</FONT><FONT face=宋体 size=3>毫秒,实际可在此作一些界面变化的处理,增加美观</FONT><FONT 
size=3>*/<BR>}<BR></FONT><FONT face=宋体 size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
在实际制作中为充分利用</FONT><FONT size=3>PC</FONT><FONT face=宋体 
size=3>机的资源,充分美化抢答器,采用了全图形化的编程,并加入了声音功能。即将抢答的组数在显示器上用大字显示出,并同时利用</FONT><FONT 
size=3>PC</FONT><FONT face=宋体 
size=3>机上的声卡报出相应组数。具体程序由各人及计算机档次而定,笔者编的程序可在</FONT><FONT size=3>386</FONT><FONT 
face=宋体 size=3>机上流畅地运行。</FONT></P>
<P><FONT face=黑体><B>四、注意事项</B></FONT></P>
<P><FONT face=宋体 size=3>如果读者实际制作这个电路,还要注意以下几个问题:<BR>&nbsp;&nbsp;&nbsp; 
1.打印口地址的确定,并非每一台计算机的打印口地址都是以上所列的地址,最常见的还有278H,279H,27AH。因此针对不同的计算机自动寻找打印口很重要,在计算机的内存中存放有打印口地址,自动查找打印口可用如下程序:<BR>unsigned 
int far *fpb=(unsigned far * )0x00400008; 
/*在内存40:08H处单元中有打印地址*/<BR>port_data=*fpb; /*取打印机数据口的地址*/<BR>port_inp=*fpb+1; 
/*状态端口为数据口地址加1*/<BR>port_ctrl=*fpb+2; /*控制端口为数据端口加2*/</FONT></P>
<P><FONT face=宋体 size=3>&nbsp;&nbsp; <IMG alt="print3.gif (4307 字节)" height=240 
src="实 例 分 析.files/print3.gif" width=524></FONT></P>
<P><FONT face=宋体 size=3>&nbsp;&nbsp;&nbsp; 2. 
以上设计是基于标准的打印口设置,如果主板的打印口设计不标准,则以上编程会有问题。以笔者的调查,所找到的所有386、586兼容机(约10个不同品种的主板)及以上机均能正常工作,但486机主板较混乱,笔者找了5、6种486兼容机,没一台能用。但所有的品牌机都没有发现有这方面的问题,为谨慎起见,自制前最好对自已所用计算机的打印口检测一下,即将状态线分别接地,然后读出状态口数据,看是否与接线相符。在计算机用语音报出‘开始’后要先检测一次输入,如果已有人按下按钮,则属范规,如无人按下,再点亮指示灯,表示抢答可以开始。DOS下的声卡发声程序编起来比较麻烦,而且一定要计算机有声卡才行,如果打算让旧计算机发挥余热,而又想有声音功能,那不妨多花上十多元钱按图4做一个发声电路。这是一个D/A转换器,只要读出WAV文件的数据并逐一送往数据端口,就可以发声了,这部份程序如下:</FONT></P>
<P><FONT face=宋体 size=3>void wave(char *file) /*发声函数,参数为文件名*/<BR>{ char 
ch='\0';<BR>FILE *fp;<BR>if((fp=fopen(file,"rb"))==NULL) /*打不开文件的常规处理*/<BR>{ 
printf("File%s not found!",*file);<BR>exit(1);<BR>}<BR>while(!feof(fp)) 
/*如果未到文件尾*/<BR>{ outportb(port_data,(int)ch); /*取出数据并送往打印口数据端口*/<BR>delay(3); 
/*延时3毫秒(取决于录音时的采样速率)*/<BR>ch=fgetc(fp);<BR>}<BR>fclose(fp);<BR>}</FONT></P>
<TABLE border=0 cellPadding=4 cellSpacing=0 width="100%">
  <TBODY>
  <TR>
    <TD width="100%"><FONT face=宋体 size=3><IMG alt="print4.gif (5247 字节)" 
      height=399 src="实 例 分 析.files/print4.gif" width=402></FONT></TD></TR>
  <TR>
    <TD width="100%"><FONT face=宋体 size=3><IMG alt="print5.gif (3116 字节)" 
      height=240 src="实 例 分 析.files/print5.gif" 
width=403></FONT></TD></TR></TBODY></TABLE>
<P><FONT face=宋体 size=3>最后给出本程序的流程图,由于程序较长,不可能全部刊出,如有需要,可以和作者联系。</FONT></P>
<P><FONT color=#808000 face=隶书 size=4><STRONG>注:本文发表于《电子技术》</STRONG></FONT></P>
<P align=center><A href="http://go.163.com/~czlyzhj/fxzl.htm"><IMG alt=返回上一页 
border=0 height=55 src="实 例 分 析.files/back1.gif" width=43></A></P></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -