1

我正在使用 pc1602f PowerTip 使用此方案直接连接到 PC 并行端口: http ://www.beyondlogic.org/parlcd/parlcd.htm

一切都很好,可以为 LCD 供电,并用黑色块显示前排,直到那时还好,但现在我想通过并行端口发送信息。

如果您查看该页面,您会看到有一个将信息发送到 lcd 的来源,但使用的是 windows 库:呵呵:

我离开我的代码试图成为 linux。

#include <stdio.h>   
#include <string.h>  
#include <unistd.h>  
#include <fcntl.h>   
#include <errno.h>   
#include <termios.h> 
#include <stdlib.h>
#include <unistd.h>
#include <sys/io.h>
#define PORTADDRESS 0x3f8
#define DATA PORTADDRESS+0
#define STATUS PORTADDRESS+1
#define CONTROL PORTADDRESS+2

main(int argc, char **argv)
{char string[] = {"Testing 1,2,3"};

    int count;
    int len;

    char init[10];
    init[0] = 0x0F; /* Init Display */
    init[1] = 0x01; /* Clear Display */
    init[2] = 0x38; /* Dual Line / 8 Bits */

    if (ioperm(PORTADDRESS,1,1))
        fprintf(stderr, "No se puede acceder al: %x\n", PORTADDRESS), exit(1);

    outb(CONTROL, inb(CONTROL) & 0xDF); 
    outb(CONTROL, inb(CONTROL) & 0x08);


    for (count = 0; count <= 2; count++)
    {

        outb(DATA, init[count]);
        outb(CONTROL,inb(CONTROL) | 0x01); 
        sleep(20);                                 
        outb(CONTROL,inb(CONTROL) & 0xFE); 
        sleep(20);                                  
    }
    outb(CONTROL, inb(CONTROL) & 0xF7);  

    len = strlen(string);

    for (count = 0; count < len; count++)
    {
        outb(DATA, string[count]);
        outb(CONTROL,inb(CONTROL) | 0x01); 
        sleep(2);
        outb(CONTROL,inb(CONTROL) & 0xFE); 
        sleep(2);
    }

}

编译完美,但是当我想以 root 身份尝试并运行它时,它会抛出我

根@ubuntu:/

媒体/E80C-30D5/LCD/内部版本#./lcd

分段错误(`core'生成)

root@ubuntu: /media/E80C-30D5/LCD/build #

看着 dmesg 我发现了这个。

[3176.691837] lcd [3867] 一般保护 ip: 400cb4 sp: 7fff887ad290 错误: 0 in lcd [+2000 400 000]root@ubuntu: /media/E80C-30D5/LCD/build #

我把ttyS的dmesg日志*

root @ ubuntu: / media/E80C-30D5/LCD/build # dmesg | grep ttyS
[2.335717] serial8250: ttyS0 at I / O 0x3f8 (irq = 4) is a 16550A
[2.335817] serial8250: ttyS1 at I / O 0x2f8 (irq = 3) is a 16550A
[2.336100] 00:0 b: ttyS1 at I / O 0x2f8 (irq = 3) is a 16550A
[2.336207] 00:0 c: ttyS0 at I / O 0x3f8 (irq = 4) is a 16550A
root @ ubuntu: / media/E80C-30D5/LCD/build #

不要让它运行,你能帮我吗?

4

3 回答 3

1

您尝试运行的代码不会在“现代”操作系统中运行。Linux 和 16 位之后的 Windows 版本不允许您执行直接访问端口或内存的操作。对内存的访问通过内存管理器进行,因此您指定的地址并不是您最终访问的地址;端口只能由作为操作系统内核一部分的设备驱动程序访问。

我不太确定,但如果您的主要目的只是通过串口输出一些字节,那么您的大部分代码都是不必要的,因为您可以简单地写入一个将设备驱动程序包装到端口的文件。在这篇文章中有更多的细节。

如果你真的需要对串口芯片进行一些操作,你可以在这个串口mini-howto的最后一行找到更多的信息。请注意,编写自己的设备驱动程序被认为是高级的。


编辑:我刚刚注意到您的问题提到了并行端口,但您的代码中的端口号(3F8)是其中一个串行端口的端口号。提示:如果您连接的插头是 9 针端口,那么它肯定是串行端口。如果它是 25 针端口和母头(孔,而不是针脚),那么它可能是一个并行端口,如果是公头,它可能是一个串行端口。或者您可以测量电压:串行端口信号上升到 +/- 9V 左右,而并行端口信号从 0 到 5V。

于 2010-07-14T13:04:42.920 回答
0

而不是写入地址空间之外的地址(如果它可以工作,这将使其仅在 PC 上运行),只需写入文件(/dev/lp0,或您的 parport 所在的任何位置)。
你的液晶显示器似乎在说串口,那为什么不改用串口呢?然后你的程序将写入/dev/ttyS0或类似的东西。

于 2010-07-14T13:16:31.687 回答
0

我同意其他人的观点,如果可能的话,您应该写入适当的设备文件而不是直接执行 I/O。

但是,为了完整起见:

ioperm(PORTADDRESS,1,1)

应该

ioperm(PORTADDRESS,4,1)

此外,使用括号来避免错误的宏扩展导致的错误,如下所示:

#define PORTADDRESS (0x3f8)
#define DATA        (PORTADDRESS+0)
#define STATUS      (PORTADDRESS+1)
#define CONTROL     (PORTADDRESS+2)
于 2010-07-14T13:20:43.830 回答