necromant, получилось ли у тебя решить вопрос с отправкой данных в uart по 9-битному протоколу этим способом: http://www.lothosoft.ch/thomas/libmip/markspaceparity.php ?
Приветствую всех.
Я реализую 9-битный протокол пердачи данных по последовательному интерфейсу в формате: START DATA7...DATA0 MODE STOP (Parity-bit определяет признак адреса устройств и конца сообщения). Я нашёл как устанавливать этот бит в 1 или 0 с помощью техники описанной здесь
Как ты решил вопрос с чтением данных (игнором+проверкой пришедшего бита чётности)?
У меня такой отладочный код не работает. Данные уходят, но устройства молчат, ничего от них не получаю. Логического анализатора нет, чтобы линию проверить.
#ifndef CMSPAR
#warning Your kernel does not appear to support CMSPAR. Will try anyway.
#endif
struct termios tty; // настройки порта на i/o
struct termios rtty;
...
memset (&tty, 0, sizeof tty);
memset (&rtty, 0, sizeof rtty);
cfsetospeed (&tty, B9600);
tty.c_cflag &= ~CRTSCTS; // Не использовать линию управления потоком RTS-CTS
tty.c_cflag |= CLOCAL; // Игнорируем контрольные линии модема?
tty.c_cflag &= ~CSIZE; // clean data bits
tty.c_cflag |= CS8; // set 8 data bits
tty.c_cflag &= ~CSTOPB; // set 1 stop bits by cleaning CSTOPB
tty.c_cflag |= CREAD; // Разрешает приём символов
tty.c_oflag &= ~OPOST; // Отключаем режим ввода, определяемый реализацией
tty.c_iflag &= ~IGNPAR; // Не игнорировать байты с ошибками чётности
tty.c_cflag |= PARENB; // Enable parity generation
tty.c_iflag &= ~INPCK; // Disable parity checking
tty.c_iflag |= PARMRK; // Enable in-band marking
tty.c_cflag |= CMSPAR;
if (tcsetattr (fd, TCSADRAIN, &tty) != 0) return;
void first() {
tty.c_cflag |= PARODD;
if (tcsetattr (fd, TCSADRAIN, &tty) != 0) return;
}
void next() {
tty.c_cflag &= ~PARODD;
if (tcsetattr (fd, TCSADRAIN, &tty) != 0) return;
}
void sendByte(unsigned char c) {
wbuf[0] = c;
int n = write(fd, wbuf, 1);
printf("ret = %d bytes SEND [0x%02X]\n", n, wbuf[0]);
}
unsigned char recvBytes(int wait) {
tty.c_cflag &= ~PARENB;
tty.c_cflag |= CMSPAR;
if (tcsetattr (fd, TCSADRAIN, &tty) != 0) return;
for(int k = 0; k < MAXBUF; k++) rbuf[k] = 0x55;
for(;;) {
int n = read(fd, rbuf, 1);
if (tcgetattr (fd, &rtty) != 0) {
printf("Can not get attrs\n");
break;
}
int mode = (rtty.c_cflag & PARODD) ? 1 : 0;
if (n > 0) {
printf("ret = %d bytes RECV [0x%02X] OK\n", n, rbuf[0]);
printf("ret = %d bytes RECV [0x%02X] OK mode = %d\n", n, rbuf[0], mode);
if (mode == wait)
break;
}
}
return rbuf[0];
}
Если для первого байта (ADDRESS) поставить бит чётности = 0, то устройства начинают отвечать, но иногда фризятся, и молчат. Приходится снова цепочку команд посылать, начиная с инициализации.