Serial port - фокусы со скоростями (9600 != 9600)

Модератор: Модераторы разделов

Pyromaniac
Сообщения: 4
ОС: ArchLinux

Serial port - фокусы со скоростями

Сообщение Pyromaniac »

Помогите пожалуйста. Возникла задача реализовать обмен данными через serial. Разобрался вроде по великому мануалу. Все бы ничего кроме одного - я задаю скорости через cfsetspeed, пробовал также отдельно через cfsetispeed и cfsetospeed, однако реальная скорость получается раз 8-10 ниже, чем та, что я задаю. Прога опробована на двух железках - на обоих одно и то-же. Из этого я сделал вывод, что трабл в моей проге. Я чувствую, что сделал где-то глупую ошибку по незнанию или по невнимательности, но понять, в чем именно дело - не могу.

Код:

#include <stdio.h> #include <stdlib.h> #include <memory.h> #include <fcntl.h> #include <unistd.h> #include <termios.h> #include <sys/ioctl.h> int hport; void togglerts(int on) { int status; ioctl(hport,TIOCMGET,&status); status=on?(status|TIOCM_RTS):(status&(~TIOCM_RTS)); ioctl(hport,TIOCMSET,&status); } void doexchange() { togglerts(0); unsigned char data1[]={0x01,0x01,0x03,250}; write(hport,data1,4); togglerts(-1); sleep(10); togglerts(0); unsigned char data2[]={0x01,0x01,0x04,249}; write(hport,data2,4); togglerts(-1); } int main() { if((hport=open("/dev/ttyS0",O_RDWR|O_NOCTTY|O_NDELAY))==-1) { perror("Open /dev/ttyS0"); return EXIT_FAILURE; } fcntl(hport,F_SETFL,0); struct termios options; tcgetattr(hport,&options); // Baud rates to 9600 cfsetspeed(&options,B9600); // cfsetispeed(&options,B9600); // cfsetospeed(&options,B9600); // Enable receiver and set local mode options.c_cflag|=(CLOCAL|CREAD); // 8 data bits, no parity options.c_cflag&=~PARENB; options.c_cflag&=~CSTOPB; options.c_cflag&=~CSIZE; options.c_cflag|=CS8; // disable hardware flow control options.c_cflag&=~CRTSCTS; // choose raw input options.c_cflag&=~(ICANON|ECHO|ECHOE|ISIG); // disable software flow control options.c_iflag&=~(IXON|IXOFF|IXANY); // choose raw output options.c_oflag&=~OPOST; // 1s timeout options.c_cc[VMIN]=0; options.c_cc[VTIME]=10; tcsetattr(hport,TCSANOW,&options); doexchange(); return 0; }


Правка: извиняюсь, запостил не в тот раздел
Спасибо сказали:
Pyromaniac
Сообщения: 4
ОС: ArchLinux

Re: Serial port - фокусы со скоростями

Сообщение Pyromaniac »

Модераторы, перенесите в "Программирование", пожалуйста
Спасибо сказали:
Аватара пользователя
BlackStar
Сообщения: 1338
Статус: We are all Kosh
ОС: Fedora 10

Re: Serial port - фокусы со скоростями

Сообщение BlackStar »

Для начала не плохо было бы проверить результат возвращаемый функциями: tcsetattr, cfsetspeed.
LightLang Team
Спасибо сказали:
Pyromaniac
Сообщения: 4
ОС: ArchLinux

Re: Serial port - фокусы со скоростями

Сообщение Pyromaniac »

BlackStar писал(а):
18.09.2007 15:25
Для начала не плохо было бы проверить результат возвращаемый функциями: tcsetattr, cfsetspeed.


Выполнение успешное, ошибок не возвращают. При этом 4 байта идут ~230(!!!) мс.
Спасибо сказали:
edo
Сообщения: 44
ОС: debian stable/testing

Re: Serial port - фокусы со скоростями

Сообщение edo »

если терминалку подкючаешь - нормально данные видишь?
попробуй после write tcdrain и/или fsync звать.
Спасибо сказали:
Pyromaniac
Сообщения: 4
ОС: ArchLinux

Re: Serial port - фокусы со скоростями

Сообщение Pyromaniac »

edo писал(а):
12.11.2007 04:50
если терминалку подкючаешь - нормально данные видишь?
попробуй после write tcdrain и/или fsync звать.


Хехехе... Спасибо, конечно, только я эту проблему решил месяца полтора назад. Почему то через модификацию полученных через tcgetattr параметров не заработало. А если структуру инициализировать нулями, а потом задать нужные настройки все работает.
Спасибо сказали:
Аватара пользователя
sg^_^milytia
Сообщения: 8
ОС: linux, windows

Re: Serial port - фокусы со скоростями

Сообщение sg^_^milytia »

на входе задаешь имя ком порта (с проверкой на ошибку):

if ((fd=initSerial("/dev/ttyS1"))<0)
{
perror("init serial");
exit(0);
}

*******************************************************


int initSerial(const char* name)
{
struct termios oldtio, newtio; //place tor old and new port settings for keyboard teletype
int comfd = open(name, O_RDWR | O_NOCTTY | O_NONBLOCK | O_NDELAY);
if (comfd == -1) return -1;
int speed = B9600; //speed
if (tcgetattr(comfd,&newtio)) return -1; // save current port settings
bzero(&newtio, sizeof(newtio));
newtio.c_cflag = speed | CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNBRK | IGNPAR ;
newtio.c_oflag = 0;
newtio.c_lflag = 0;
newtio.c_cc[VMIN]=1;
newtio.c_cc[VTIME]=100;
tcflush(comfd, TCIOFLUSH);
if (tcsetattr(comfd,TCSANOW,&newtio) || fcntl(comfd,F_SETFL,FNDELAY)) return -1;
return comfd;
}

на выходе получаешь hadle его ..
буду рад если поможет
Спасибо сказали: