Инициализация COM порта
COM порт в Linux представляет собой файл устройства. Типичное расположение такого файла\dev\ttySx
для обычного COM порта или \dev\ttyUSBx
дляUSB-RS переходника, где x = 0,1,2...
Встречаются также
\dev\ttyOSx
и др.Для начала работы COM порт необходимо открыть:
int F_ID = -1; open("\dev\ttyUSB0", O_RDWR | O_NOCTTY); if(F_ID == -1) { std::cout << strerror(errno) << std::endl; }Если
F_ID
отличается от -1
, значит COM порт открыт успешнои можно переходить к его настройке.
Чтение текущих настроек:
struct termios options; /*структура для установки порта*/ tcgetattr(F_ID, &options); /*читает пораметры порта*/Установка скорости:
cfsetispeed(&options, B57600); /*установка скорости порта*/ cfsetospeed(&options, B57600); /*установка скорости порта*/Установка таймаутов чтения:
options.c_cc[VTIME] = 20; /*Время ожидания байта 20*0.1 = 2 секунды */ options.c_cc[VMIN] = 0; /*минимальное число байт для чтения*/Установка других полезных (необходимых) параметров:
options.c_cflag &= ~PARENB; /*бит четности не используется*/ options.c_cflag &= ~CSTOPB; /*1 стоп бит */ options.c_cflag &= ~CSIZE; /*Размер байта*/ options.c_cflag |= CS8; /*8 бит*/ options.c_lflag = 0; options.c_oflag &= ~OPOST; /*Обязательно отключить постобработку*/ options.c_iflag = 0; options.c_iflag &= ~ (INLCR | IGNCR | ICRNL);Сохранение параметров:
tcsetattr(F_ID, TCSANOW, &options);
Чтение и отправка данных
Прочитать данные из COM порта:
unsigned char buff[16] = {0}; int size = 8; int n = read(F_ID, buff, size);Отправить в COM порт:
unsigned char buff[4] = {1,2,3,4}; int size = 4; int n = write(F_ID, buff, size);
Завершение работы
После того, как работа с COM портом будет завершена, его необходимо закрыть:close(F_ID); F_ID = -1;
Дополнительные возможности
Кроме сигналов TX и RX в COM порте присутствуют дополнительные сигналы,например: RTS, CTS и т.д
иногда с ними необходимо работать.
Установка RTS:
int status; ioctl(F_ID, TIOCMGET, &status); status |= TIOCM_RTS; ioctl(F_ID, TIOCMSET, &status);Очистка RTS:
int status; ioctl(F_ID, TIOCMGET, &status); status &= ~TIOCM_RTS; ioctl(F_ID, TIOCMSET, &status);
В итоге получаем набор функций
#include <fcntl.h> #include <termios.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <sys/ioctl.h>
#include <unistd.h> int F_ID = -1; /*---------------------------------------------------------------------------- Открыть COM порт COM_name: путь к устройству, например: /dev/ttyS0 или /dev/ttyUSB0 - для USB speed: скорость, например: B9600, B57600, B115200 ----------------------------------------------------------------------------*/ bool openPort(const char *COM_name,speed_t speed) { F_ID = open(COM_name, O_RDWR | O_NOCTTY); if(F_ID == -1) { char *errmsg = strerror(errno); printf("%s\n",errmsg); return false; } struct termios options; /*структура для установки порта*/ tcgetattr(F_ID, &options); /*читает пораметры порта*/ cfsetispeed(&options, speed); /*установка скорости порта*/ cfsetospeed(&options, speed); /*установка скорости порта*/ options.c_cc[VTIME] = 20; /*Время ожидания байта 20*0.1 = 2 секунды */ options.c_cc[VMIN] = 0; /*минимальное число байт для чтения*/ options.c_cflag &= ~PARENB; /*бит четности не используется*/ options.c_cflag &= ~CSTOPB; /*1 стоп бит */ options.c_cflag &= ~CSIZE; /*Размер байта*/ options.c_cflag |= CS8; /*8 бит*/ options.c_lflag = 0; options.c_oflag &= ~OPOST; /*Обязательно отключить постобработку*/ tcsetattr(F_ID, TCSANOW, &options); /*сохронения параметров порта*/ return true; } /*---------------------------------------------------------------------------- Прочитать данные из COM порта buff - буфер для принятых данных size - количество запрашиваемых байт ----------------------------------------------------------------------------*/ int readData(unsigned char *buff,int size) { int n = read(F_ID, buff, size); if(n == -1) { char *errmsg = strerror(errno); printf("%s\n",errmsg); } return n; } /*---------------------------------------------------------------------------- Отправить в COM порт данные buff - буфер данных для отправки size - количество отправляемых байт ----------------------------------------------------------------------------*/ int sendData(unsigned char* buff,int len) { int n = write(F_ID, buff, len); if(n == -1) { char *errmsg = strerror(errno); printf("%s\n",errmsg); } return n; } /*---------------------------------------------------------------------------- Закрыть COM порт ----------------------------------------------------------------------------*/ void closeCom(void) { close(F_ID); F_ID = -1; return; } /*---------------------------------------------------------------------------- Установить RTS ----------------------------------------------------------------------------*/ void setRTS() { int status; ioctl(F_ID, TIOCMGET, &status); status |= TIOCM_RTS; ioctl(F_ID, TIOCMSET, &status); } /*---------------------------------------------------------------------------- Очистить RTS ----------------------------------------------------------------------------*/ void clrRTS() { int status; ioctl(F_ID, TIOCMGET, &status); status &= ~TIOCM_RTS; ioctl(F_ID, TIOCMSET, &status); } /*---------------------------------------------------------------------------- Пример использования ----------------------------------------------------------------------------*/ int main() { bool res = openPort("\dev\ttyUSB0",B9600); if(!res) { printf("Невозможно открыть COM порт\n"); return 0; } unsigned char buff[8] = {0,1,2,3,4,5,6,7}; sendData(buff,8); int s = readData(rbuff,4); if(s < 4) { printf("Нет ответа\n"); return 0; } /* Наш код */ return 0; }
А можно ли работать с портом не с помощью функций open(), close(), и т. д., а с помощью fopen(),fclose(), т. е. не через файловый дескриптор, а через указатель FILE*?
ОтветитьУдалитьНе знаю, не пробовал. Но в этом случае не понятно, что делать с настройками скорости и четности
Удалитьtcsetattr(F_ID, TCSANOW, &options);
Этот комментарий был удален автором.
ОтветитьУдалитьСлэши обратные... Виндузятник детектед :D
ОтветитьУдалить