编程 rs232 到 LCD (Linux)
我使用的是 pc1602f PowerTip,使用以下方案直接连接到 PC 并行端口: http://www.beyondlogic.org/parlcd/parlcd.htm
一切顺利给液晶显示屏通电并向我显示前排的黑色块,直到那时都很好,但现在我想通过并行端口发送信息。
如果你看一下这个页面,你会发现有一个源可以将信息发送到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 身份尝试并运行时,它让我崩溃
root@ubuntu:/
媒体/E80C-30D5/LCD/build #./lcd
分段错误(“核心”生成)
root@ubuntu:/media/E80C-30D5/LCD/build #
查看 dmesg 我发现了这个。
[3176.691837]液晶屏[3867]一般 保护 ip: 400cb4 sp: 7fff887ad290 错误: lcd 中的 0 [+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 #
不让它运行,可以请帮帮我吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您尝试运行的代码将无法在“现代”操作系统中运行。 Linux 和 16 位之后的 Windows 版本不允许您执行直接访问端口或内存的操作。对内存的访问通过内存管理器进行,因此您指定的地址实际上并不是您最终访问的地址;并且端口只能由属于操作系统内核一部分的设备驱动程序访问。
我不太确定,但如果您的主要目的只是通过串行端口输出一些字节,那么大部分代码都是不必要的,因为您可以简单地写入将设备驱动程序包装到端口的文件。 本文对此有更多详细信息。
如果您确实需要对串行端口芯片进行一些操作,您可以在串口迷你指南.请注意,编写自己的设备驱动程序被认为是高级的。
编辑:我刚刚注意到您的问题提到了并行端口,但代码中的端口号(3F8)是串行端口之一的端口号。提示:如果您连接的插头是 9 针端口,那么它肯定是串行端口。如果它是 25 针端口和母头(孔,而不是针),那么它可能是并行端口,如果是公头,它可能是串行端口。或者您可以测量电压:串行端口信号高达 +/- 9V 左右,而并行端口信号为 0 到 5V。
The code you're trying to run will not run in a "modern" operating system. Linux and versions of Windows after 16-bit will not let you perform operations that directly access ports or memory. Access to memory goes through a memory manager so the addresses you're specifying are not really the ones you end up accessing; and ports are accessed only by device drivers that are part of the operating system's kernel.
I'm not very sure, but if your main purpose is just to output some bytes via the serial port, then most of your code is not necessary, as you can simply write to a file that wraps the device driver to the port. There's a little more detail on this in this article.
If you really need to do bit-twiddling with the serial port chips, you can find some more information in the bottom line of this serial port mini-howto. Be warned that writing your own device driver is considered advanced.
EDIT: I just noticed your question mentions the parallel port but the port number in your code (3F8) is that for one of the serial ports. Hint: If the plug you're connecting to is a 9 pin port, then it's definitely a serial port. If it's a 25 pin port and female (holes, not pins) then it's probably a parallel port, if male it's probably a serial port. Or you could measure voltages: Serial port signals go up to +/- 9V or so, while the parallel port signals are from 0 to 5V.
我同意其他人的观点,如果可能的话,您应该写入适当的设备文件而不是直接执行 I/O。
但是,为了完整起见:
应该
另外,使用括号以避免因不正确的宏扩展而导致的错误,如下所示:
I agree with others that you should write to the appropriate device file rather than perform I/O directly, if possible.
However, for the sake of completeness:
should be
Also, use parentheses to avoid bugs that results from incorrect macro expansion, like this:
不要写入地址空间之外的地址(如果可以的话,这将使其仅适用于 PC),而只需写入文件(
/dev/lp0
,或您的 parport 所在的任何位置)即可。您的 LCD 似乎可以进行串行通信,那么为什么不使用串行端口呢?然后你的程序将写入
/dev/ttyS0
或类似的内容。Instead of writing to an address outside your address space (which would make it PC-only if it would work), just write to a file (
/dev/lp0
, or wherever your parport is) instead.Your LCD seems to talk serial, so why not use the serial port instead? Then your program would write to
/dev/ttyS0
or something similar.