如何控制外设端口:在Linux上使用C访问和写入并行端口。第一部分

用于控制PC外围设备端口的最引人注目的新兴用例之一是家庭自动化,这种技术为我们的家庭提供了无限的可能性。 家庭自动化是一个社会方面的技术学科。 我们的方法是使用一些关键短语来提高生活质量 ,扩大沟通自动化流程。 所有这一切似乎都很简单,但是这个新的家庭自动化世界固有的复杂性是令人兴奋的,让我们看看为什么。

家庭自动化是一个复杂的活动,有几个原因。 首先,家庭设备(传感器,智能家电,执行器...)的操作可以让您了解复杂的物理现象,如机械量子或光电效应。 此外,这些设备之一可以执行各种任务,而不一定只是一个简单的任务。 第二,谈论家庭自动化是在谈论由许多不总是易于互动的组件组成的系统(想象一个家庭安全系统,包括摄像机,存在检测器,通信设备,带有远程警告系统的报警器等) ...) 最后,最重要的是,它是复杂的,因为它面临着具有社会系统的技术系统的自动化。

术语定义

并口:

并行端口是计算机和外围设备之间的接口,其主要特征是数据位一起运行,一次发送一个数据包字节。 通过形成8行总线来实现每一位数据的电缆或物理通道。 通过并行端口,我们还可以控制外围设备,如灯,电机和其他设备。

网页界面:

Web界面允许用户通过Web浏览器来控制和与其设备进行交互。 这可以用于远程控制,图书馆管理,视觉反馈等诸多功能。

家庭自动化:

能够自动化家庭的所有系统的自动化,提供能源管理服务,安全,福利和通信,并且可以集成到有线或无线室内和室外通信网络中。

如何使用C中的并行端口

为了我们的主要目的,基本的家庭自动化,我们将使用并行端口来演示如何编写(或读取)一些字节来控制简单的设备。 PC ECP类型的并行端口具有母DB25型输出连接器,其图和信号如下图所示:

图1:并行端口图。 母连接器引脚。 由维基百科提供

并行端口输出

根据Centronics标准,PC的并行端口由双向8数据位通信总线和一组协议线组成。 通信线路有一个保持器,保持写入它们的最后一个值,直到新数据写入,电气特性为:

  • 高电平电压:3.3〜5V。
  • 低电平电压:0 V.
  • 最大输出电流:2.6 mA。
  • 最大输入电流:24 mA。

电压和电流可以馈送一组控制设备,如LED,继电器和固态开关。 这些缓冲器需要关闭或更高功耗的元件。

解决

标准并行端口的寻址是重要的,因为它从计算机使用的各种资源和识别目的。 标准并行端口使用三个连续的地址,通常在以下范围之一:

3BCh 3BDh 3BEh
378h 379h 37Ah
278h 279h 27Ah


该范围中的第一个地址是端口的基地址,也称为数据寄存器或只是端口地址。 第二个地址是端口的状态寄存器,第三个是控制寄存器。

EPP和ECP为每个端口预留额外的地址。 EPP通过基地址+ 7在地址+ 3的基础上添加5个寄存器,并且ECP通过基地址+ 402h在基地址+ 400h处添加三个寄存器。 对于基地址为378h,EPP寄存器为37Bh至37Fh,ECP寄存器为778h至77Fh。

DMA通道

ECP可以使用直接存储器访问(DMA)进行到并行端口的数据传输。 在DMA传输期间,CPU可以自由地执行其他操作,因此DMA传输可以导致整体更快的性能。 为了使用DMA,端口必须具有分配的DMA通道,范围为0到3。

访问Linux上的物理端口

由于PC上的端口硬件由Linux内核直接控制,所以我们必须访问与并行端口总线相关的特定头。 GCC编译器可以访问这些头,始终要牢记用户必须具有root权限以避免访问错误。 这些标题是:

  • stdio.h :“标准输入输出头”(标准头I / O)是包含宏定义,常量,C语言标准库中的函数声明执行操作,标准输入和输出的头文件,以及此类操作所需类型的定义。 出于兼容性原因,编程语言C ++(C派生)也有自己的这些函数的实现,它们使用cstdio文件头声明。 我必须使用的功能是fprintf ,如果有任何错误,它允许在终端窗口上打印。
  • stdlib.h :是通用编程语言C的标准库的头文件。它包含用于动态内存管理,过程控制等的C函数原型。 它支持C ++,它被称为cstdlib。 当我们收到错误时,我将使用的函数是退出
  • unistd.h :提供对POSIX操作系统API的访问的头文件。 在Unix系统上,由unistd.h定义的接口通常由系统调用包装器函数(如fork,pipe和I / O)(读,写,关闭等)组成。
  • sys / io.h:这个系列函数用于进行低级别的端口输入和输出。 out *功能做端口输出,in *功能做端口输入; bPostfix功能为字节宽度,w-suffix函数为word-width; 直到I / O完成后,_p-suffix功能暂停。 这个家庭功能我会用outb
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/io.h>

在Linux中,很容易访问和控制并行端口,但是,必须高度考虑根访问。 以上是本教程今天所需的所有库。

定义并行端口的内存地址

一旦包含库,我们必须定义分配给并行端口的内存地址,如上所述,第一个并行端口的默认地址为0x378。

#define base 0x378           /* parallel port base address */

如果您有任何问题尝试此地址,您应该尝试0x278。

使用数据总线作为输出端口

对于本第一部分教程,我将使用数据总线作为输出端口。 在下一章中,我们将看到如何将其用作数据输入端口,甚至用作混合端口。 在下图中,我们可以看到通过限流电阻将8个LED连接到并行端口进行控制,并行端口响应分配给地址0x378的值。 电阻的值可能在100欧姆到300欧姆之间变化,这对我们来说非常重要,因为如果我们不限制电流,我们可能损坏端口。

原理图


注意:LED的颜色不重要。

实电路



注意: 请注意并行端口连接器的处理,确保在关闭电脑之前不要断开电路。 这可能会损坏端口甚至主板。 我们不能对您的硬件设备造成任何损害

软件实现

为了我的目的,我将向您展示如何在端口中放置一些值,以及如何完成这些值的时间安排,这是一个非常简单的例程来向您展示它的工作原理。

现在我将解释控制软件中使用的所有命令和单词:

  • 第1步:如果用户具有访问端口的root权限,则为条件。 此条件命令的参数是ioperm ,它为端口地址库设置端口访问权限位。
if (ioperm(base,1,1))
  • 第2步:如果用户没有足够的权限访问并行端口,将显示访问错误,程序执行结束。
fprintf(stderr, "Access denied to %x\n", base), exit(1);
  • 第3步:如果访问被授予,则for循环将通过预定义的值在端口中给出LED的一个开关序列。 我使用的定时功能是sleep() ,它使调用线程休眠,直到参数的秒数过去。
        w=0;
        for (x=0; x=7; x++)  
            {        
            y=pow(2,w);
            outb(y, base);
            sleep(1);
            w=w+1;
               }


    当代码处理通过访问允许行时, 'fprintf(stderr,“拒绝访问%x \ n”,base),exit(1);' ,并行端口的数据引脚可用于您的处置和想象力。 在我的情况下,我只用一个简单的序列,从第一次引导到最后一次,间隔一秒,使用基数2的权力(见视频链接 )。 然而,可能性是无限的,事实上,不使用复用可以控制多达8个独立输出,多路复用输出可以增长到255种可能性。 根据应用,无论是在家庭自动化方面,我们都可以处理端口而不进行多路复用,放置适当的缓冲区来处理更高的当前负载,这将在另一个教程中稍后进行处理。


    参考文献:

    Martin H,Saez F. Domotica,Un EnfoqueSociotécnico 。 2006年6月。Ciudad Universitaria,s / n 28040-Madrid,ISBN:84-7402-335-1的Rogelio Segovia para el Desarrollo de las Telecomunicaciones。

    Axelson J. 并行端口完成。 编程,接口和使用PC的并行打印机端口 。 亚马逊股份有限公司ISBN:0-9650819-1-5

    Kerrisk M. Linux编程接口 。 Linux手册项目。 ISBN 978-1-59327-220-3

    赞(52) 打赏
    未经允许不得转载:优客志 » 系统运维
    分享到:

    觉得文章有用就打赏一下文章作者

    支付宝扫一扫打赏

    微信扫一扫打赏