2010-07-14 5 views
0

내가 직접이 기법을 사용하여 PC 병렬 포트에 연결된 pc1602f의 파워 팁을 사용하고 있습니다 : http://www.beyondlogic.org/parlcd/parlcd.htm프로그래밍 RS232 (리눅스)

모든 아니라 LCD 에너지를 공급하고 검은 색 블록으로 나에게 앞줄 같이, 그때까지는 괜찮지 만 지금은 병렬 포트를 통해 정보를 보내고 싶습니다. 당신이 페이지를 보면

당신이 액정 화면에 정보를 보낼 수있는 소스이지만, 윈도우 라이브러리를 사용하는 것을 볼 수 있습니다 : 응 :

내가 내 코드는 리눅스되기 위해 시도 둡니다.

#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); 
    } 

} 

완벽하게 컴파일하지만 루트로 그것을 시도하고 실행할 때 내가이 찾을 dmesg를 보면 나에게

[email protected]: /

media/E80C-30D5/LCD/build #./lcd

Segmentation fault (`core 'generated)

[email protected]: /media/E80C-30D5/LCD/build #

가 발생합니다.

[3176.691837] lcd [3867] general protection ip: 400cb4 sp: 7fff887ad290 error: 0 in lcd [+2000 400 000][email protected]:/media/E80C-30D5/LCD/build #

나는 *

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 # 

그것을 실행하지 마세요, 당신은 제발 도움이 될 수 있습니다 터미날 dmesg를 로그를 넣어?

답변

0

가능한 경우 I/O를 직접 수행하지 말고 적절한 장치 파일에 쓰는 것에 동의합니다.

그러나, 완전성을 위해 :

#define PORTADDRESS (0x3f8) 
#define DATA  (PORTADDRESS+0) 
#define STATUS  (PORTADDRESS+1) 
#define CONTROL  (PORTADDRESS+2) 
:

ioperm(PORTADDRESS,1,1) 

이 같은 잘못된 매크로 확장의 결과 버그를 피하기 위해

또한
ioperm(PORTADDRESS,4,1) 

, 괄호를 사용,해야합니다

+0

이 모듈은 작동하도록 모듈을 디자인하는 데 필요합니다. 항구의 다양한 부분을 완벽하게 활성화합니까? – Backglass

+0

누군가가 이미 드라이버를 작성했습니다. http://lcd-linux.sourceforge.net/가 좋은지보십시오. 또한 내 제안이 문제를 해결합니까? – Artelius

1

실행하려는 코드가 "최신"운영 체제에서 실행되지 않습니다. 16 비트 이후의 Linux 및 Windows 버전에서는 포트 나 메모리에 직접 액세스하는 작업을 수행 할 수 없습니다. 메모리에 대한 액세스는 메모리 관리자를 통해 이루어 지므로 사용자가 지정하는 주소는 실제로 사용자가 액세스하는 주소가 아닙니다. 포트는 운영 체제 커널의 일부인 장치 드라이버에서만 액세스 할 수 있습니다.

잘 모르겠지만 직렬 포트를 통해 일부 바이트를 출력하는 것이 주된 목적이라면 대부분의 코드는 필요하지 않습니다. 장치 드라이버를 래핑하는 파일에 간단히 쓸 수 있으므로 항구. 이 in this article에 대한 자세한 내용이 있습니다.

시리얼 포트 칩을 사용하여 비트 - 트위들 링을 실제로 수행해야하는 경우이 serial port mini-howto의 마지막 줄에 자세한 정보가 있습니다. 자신의 장치 드라이버 작성이 진보 된 것으로 간주된다는 경고를 받으십시오.


편집 : 나는 당신의 질문은 병렬 포트하지만 코드 (3F8)에 포트 번호를 언급 발견하는 직렬 포트 중 하나. 힌트 : 연결하려는 플러그가 9 핀 포트라면 확실히 직렬 포트입니다. 25 핀 포트와 여성 포트 (구멍이 아니라 핀이 아닌 경우)는 아마도 병렬 포트 일 것입니다. 수컷이라면 아마 직렬 포트 일 것입니다. 또는 전압을 측정 할 수 있습니다. 직렬 포트 신호는 최대 +/- 9V 정도이고 병렬 포트 신호는 0-5V입니다.

0

주소 공간 외부의 주소로 쓰는 대신 (컴퓨터가 작동 할 경우에만 PC 전용으로 설정) 파일 대신 파일 (/dev/lp0 또는 그 부분이있는 곳)에 쓰십시오.
LCD가 직렬로 연결되어있는 것처럼 보이므로 대신 직렬 포트를 사용하지 않으시겠습니까? 그런 다음 프로그램은 /dev/ttyS0 또는 비슷한 것으로 기록합니다.

+0

죄송합니다. 귀하의 LCD는 직렬로 말하는 것이 아닙니다. 나는 당신의 질문 주제에 혼란 스러웠습니다. – MattBianco

+0

uhm, LCD 장치의 커널 모듈 디자인으로 시작하지 않거나 16 진수로 느슨한 비트 워드 형식으로 코드를 디자인하십시오. – Backglass