В настоящее время я пытаюсь сделать программу для чтения последовательного порта. На этот порт я получаю данные со скоростью 875000 бод. Это действительно необычно, и мне не удается его изменить. Я сделал для этого небольшую программу на C, но она не работала с 875000... Вот часть кода с программированием последовательного порта:
#include <stdio.h>
#include <stdlib.h>
#include <asm/termios.h>
#include <sys/fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include "test.h"
void read_Serial_Port(const char* DEVICE_PORT)
{
int file;
struct ktermios options;
unsigned int nCountMax = 60;
bool b;
file = open(DEVICE_PORT, O_RDONLY | O_NOCTTY | O_NDELAY);
if(file == -1){perror("Unable to open the serial port\n");}
//printf("Serial port open successful!\n");
int speed = atoi("875000");
ioctl(file, TCGETS2, &options);
options.c_ispeed = speed;
options.c_ospeed = speed;
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag |= PARENB;
options.c_cflag |= PARODD;
options.c_cflag &= ~CBAUD;
options.c_cflag |= BOTHER;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
ioctl(file, TCSETS2, &options);
//printf("Reading serial port...\n\n");
b = readMessage(file, nCountMax);
if (b == 0){printf("Error while reading serial port\n");}
//else printf("\nSerial port read successful\n");
close(file);
//printf("Serial port closed\n");
};
Решение проблемы
Наконец, я нашел еще одну тему в stackoverflow, которая завершена и решает мою проблему: как установить скорость передачи данных на 307200 в Linux?
Вот мой код с модификацией:
static int rate_to_constant(int baudrate) {
#define B(x) case x: return B##x
switch(baudrate) {
B(50); B(75); B(110); B(134); B(150);
B(200); B(300); B(600); B(1200); B(1800);
B(2400); B(4800); B(9600); B(19200); B(38400);
B(57600); B(115200); B(230400); B(460800); B(500000);
B(576000); B(921600); B(1000000);B(1152000);B(1500000);
B(2000000);B(2500000);B(3000000);B(3500000);B(4000000);
default: return 0;
}
#undef B
}
int Custom_Baudrate(const char* Device, int rate)
{
/*Declaration of all the variables needed*/
struct termios2 options;
struct serial_struct serinfo;
int file=-1;
int speed = 0;
int r=rate;
/* Open and configure serial port */
file = open(Device,O_RDWR|O_NOCTTY);
if(file==-1){printf("\nERROR: Unable to open the serial port\n\n");return 1;}
speed = rate_to_constant(r);
/*Find best Baudrate*/
if (speed == 0) {
/* Custom divisor */
serinfo.reserved_char[0] = 0;
if (ioctl(file, TIOCGSERIAL, &serinfo) < 0) file=-1;
serinfo.flags &= ~ASYNC_SPD_MASK;
serinfo.flags |= ASYNC_SPD_CUST;
serinfo.custom_divisor = ((serinfo.baud_base + (r / 2)) / r);
if (serinfo.custom_divisor < 1)
serinfo.custom_divisor = 1;
if (ioctl(file, TIOCSSERIAL, &serinfo) < 0) file=-1;
if (ioctl(file, TIOCGSERIAL, &serinfo) < 0) file=-1;
if (serinfo.custom_divisor * r!= serinfo.baud_base) {
warnx("actual baudrate is %d / %d = %f",
serinfo.baud_base, serinfo.custom_divisor,
(float)
serinfo.baud_base / serinfo.custom_divisor);
}
}
/*Set the best Baudrate (if desired baudrate is unvailable, it's set automatically at 38400)*/
fcntl(file, F_SETFL, 0);
tcgetattr(file, &options);
cfsetispeed(&options, speed?: B38400);
cfsetospeed(&options, speed?: B38400);
cfmakeraw(&options);
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~CRTSCTS;
if (tcsetattr(file, TCSANOW, &options)!= 0) file=-1;
/*Read the serial port*/
communicate_Serial_Port(file);
close(file);
return 1;
}
В этом коде вам просто нужно уточнить, какая скорость передачи данных вам нужна, и найти ближайшее значение, которое вы можете использовать. Это значение основано на «базовой скорости передачи данных» вашего устройства и ищет делитель для установки наилучшей скорости передачи данных. Тем не менее, некоторая скорость передачи всегда должна быть недоступна, поэтому эта программа поставит 38400 в качестве базы (это выбор). Я тестировал его с несколькими скоростями передачи данных, и он всегда работал.
Я новичок в stackoverflow, надеюсь, этот пост правильно ответит на вопрос.
Комментариев нет:
Отправить комментарий