Инициализация 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
ОтветитьУдалить