Программирование rs232 для lcd (Linux) - PullRequest
0 голосов
/ 14 июля 2010

Я использую PowerTip pc1602f, напрямую подключенный к параллельному порту ПК, используя эту схему: http://www.beyondlogic.org/parlcd/parlcd.htm

Все хорошо, что подает питание на ЖК-дисплей и показывает мне передний ряд с черными блоками, до тех пор хорошо, ноТеперь я хочу отправить информацию через параллельный порт.

Если вы посмотрите на страницу, вы увидите, что есть источник для отправки информации на ЖК-дисплей, но использует библиотеки Windows: huh:

Я оставляю свой код попытанным стать 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: /

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

Ошибка сегментации (сгенерировано «ядро»)

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

Глядя на dmesg, я нахожу это.

[3176.691837] lcd [3867] ip: 400cb4 sp общей защиты: 7fff887ad290 ошибка: 0 в lcd [+2000 400 000] root @ ubuntu: / media / E80C-30D5 / LCD / build #

Я помещаю журнал dmesg ttyS *

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 #

Не запускайте его, вы можете мне помочь, пожалуйста?

Ответы [ 3 ]

1 голос
/ 14 июля 2010

Код, который вы пытаетесь запустить, не будет работать в «современной» операционной системе. Linux и версии Windows после 16-разрядных не позволят вам выполнять операции, которые напрямую обращаются к портам или памяти. Доступ к памяти осуществляется через диспетчер памяти, поэтому указанные вами адреса в действительности не являются теми, к которым вы в конечном итоге обращаетесь; и порты доступны только для драйверов устройств, которые являются частью ядра операционной системы.

Я не очень уверен, но если ваша основная цель - просто вывести несколько байтов через последовательный порт, тогда большая часть вашего кода не нужна, так как вы можете просто записать в файл, который упаковывает драйвер устройства в порт. Есть немного больше деталей об этом в этой статье .

Если вам действительно нужно немного поработать с микросхемами последовательного порта, вы можете найти дополнительную информацию в нижней строке этого mini-howto последовательного порта . Имейте в виду, что написание собственного драйвера устройства считается продвинутым.


РЕДАКТИРОВАТЬ: Я только что заметил, что ваш вопрос упоминает параллельный порт, но номер порта в вашем коде (3F8) для одного из последовательных портов. Подсказка: если разъем, к которому вы подключаетесь, является 9-контактным портом, то это определенно последовательный порт. Если это 25-контактный порт и гнездо (отверстия, а не контакты), то это, вероятно, параллельный порт, если разъем, это, вероятно, последовательный порт. Или вы можете измерить напряжение: сигналы последовательного порта возрастают до +/- 9 В или около того, а сигналы параллельного порта - от 0 до 5 В.

0 голосов
/ 14 июля 2010

Я согласен с другими, что вам следует записать в соответствующий файл устройства, а не выполнять ввод-вывод напрямую, если это возможно.

Однако для полноты картины:

ioperm(PORTADDRESS,1,1)

должно быть

ioperm(PORTADDRESS,4,1)

Кроме того, используйте скобки, чтобы избежать ошибок, вызванных неправильным расширением макроса, например:

#define PORTADDRESS (0x3f8)
#define DATA        (PORTADDRESS+0)
#define STATUS      (PORTADDRESS+1)
#define CONTROL     (PORTADDRESS+2)
0 голосов
/ 14 июля 2010

Вместо записи по адресу за пределами вашего адресного пространства (что сделало бы его доступным только для ПК, если бы он работал), просто вместо этого запишите в файл (/dev/lp0 или где бы вы ни находились):
Ваш ЖК-дисплейкажется, говорит последовательный, так почему бы не использовать последовательный порт вместо этого?Тогда ваша программа будет писать в /dev/ttyS0 или что-то подобное.

...