- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试编写一个简单的应用程序来从 Keithley 6485 皮安表读取当前值,该表通过 Linux 上的串行通信 (RS232<->USB) 连接。
目前,可以通过对设备进行所有必要的初始化并发送“READ?”来检索这样的值。对它: echo "READ?">/dev/ttyUSB0
。然后如果 cat/dev/ttyUSB0
一直在监听,我得到以下输出:-2.250416E-14A,+8.320175E+03,+0.000000E+00
,of其中第一个数字是所需的值。
为了能够输出值,我使用以下代码使用 termios 库:
/*====================================================================================================*/
/* Serial Port Programming in C (Serial Port Read) */
/* Non Cannonical mode */
/*----------------------------------------------------------------------------------------------------*/
/* Program reads a string from the serial port at 9600 bps 8N1 format */
/* Baudrate - 9600 */
/* Stop bits -1 */
/* No Parity */
/*----------------------------------------------------------------------------------------------------*/
/* Compiler/IDE : gcc 4.6.3 */
/* Library : */
/* Commands : gcc -o serialport_read serialport_read.c */
/* OS : Linux(x86) (Linux Mint 13 Maya)(Linux Kernel 3.x.x) */
/* Programmer : Rahul.S */
/* Date : 21-December-2014 */
/*====================================================================================================*/
/*====================================================================================================*/
/* www.xanthium.in */
/* Copyright (C) 2014 Rahul.S */
/*====================================================================================================*/
/*====================================================================================================*/
/* Running the executable */
/* ---------------------------------------------------------------------------------------------------*/
/* 1) Compile the serialport_read.c file using gcc on the terminal (without quotes) */
/* */
/* " gcc -o serialport_read serialport_read.c " */
/* */
/* 2) Linux will not allow you to access the serial port from user space,you have to be root.So use */
/* "sudo" command to execute the compiled binary as super user. */
/* */
/* "sudo ./serialport_read" */
/* */
/*====================================================================================================*/
/*====================================================================================================*/
/* Sellecting the Serial port Number on Linux */
/* ---------------------------------------------------------------------------------------------------*/
/* /dev/ttyUSBx - when using USB to Serial Converter, where x can be 0,1,2...etc */
/* /dev/ttySx - for PC hardware based Serial ports, where x can be 0,1,2...etc */
/*====================================================================================================*/
/*-------------------------------------------------------------*/
/* termios structure - /usr/include/asm-generic/termbits.h */
/* use "man termios" to get more info about termios structure */
/*-------------------------------------------------------------*/
#include <stdio.h>
#include <fcntl.h> /* File Control Definitions */
#include <termios.h> /* POSIX Terminal Control Definitions */
#include <unistd.h> /* UNIX Standard Definitions */
#include <errno.h> /* ERROR Number Definitions */
void main(void)
{
int fd;/*File Descriptor*/
printf("\n +----------------------------------+");
printf("\n | Serial Port Read |");
printf("\n +----------------------------------+");
/*------------------------------- Opening the Serial Port -------------------------------*/
/* Change /dev/ttyUSB0 to the one corresponding to your system */
fd = open("/dev/ttyUSB0",O_RDWR | O_NOCTTY); /* ttyUSB0 is the FT232 based USB2SERIAL Converter */
// fd = open("/dev/ttyUSB0",O_RDWR | O_NOCTTY | O_NDELAY); /* ttyUSB0 is the FT232 based USB2SERIAL Converter */
/* O_RDWR - Read/Write access to serial port */
/* O_NOCTTY - No terminal will control the process */
/* Open in blocking mode,read will wait */
if(fd == -1) /* Error Checking */
printf("\n Error! in Opening ttyUSB0 ");
else
printf("\n ttyUSB0 Opened Successfully ");
/*---------- Setting the Attributes of the serial port using termios structure --------- */
struct termios SerialPortSettings; /* Create the structure */
tcgetattr(fd, &SerialPortSettings); /* Get the current attributes of the Serial port */
/* Setting the Baud rate */
cfsetispeed(&SerialPortSettings,B19200); /* Set Read Speed as 19200 */
cfsetospeed(&SerialPortSettings,B19200); /* Set Write Speed as 19200 */
/* 8N1 Mode */
SerialPortSettings.c_cflag &= ~PARENB; /* Disables the Parity Enable bit(PARENB),So No Parity */
SerialPortSettings.c_cflag &= ~CSTOPB; /* CSTOPB = 2 Stop bits,here it is cleared so 1 Stop bit */
SerialPortSettings.c_cflag &= ~CSIZE; /* Clears the mask for setting the data size */
SerialPortSettings.c_cflag |= CS8; /* Set the data bits = 8 */
SerialPortSettings.c_cflag &= ~CRTSCTS; /* No Hardware flow Control */
SerialPortSettings.c_cflag |= CREAD | CLOCAL; /* Enable receiver,Ignore Modem Control lines */
SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY); /* Disable XON/XOFF flow control both i/p and o/p */
SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG); /* Non Cannonical mode */
SerialPortSettings.c_oflag &= ~OPOST;/*No Output Processing*/
/* Setting Time outs */
SerialPortSettings.c_cc[VMIN] = 13; /* Read at least 10 characters */
SerialPortSettings.c_cc[VTIME] = 0; /* Wait indefinetly */
if((tcsetattr(fd,TCSANOW,&SerialPortSettings)) != 0) /* Set the attributes to the termios structure*/
printf("\n ERROR ! in Setting attributes");
else
printf("\n BaudRate = 19200 \n StopBits = 1 \n Parity = none");
/*------------------------------- Read data from serial port -----------------------------*/
char read_buffer[32]; /* Buffer to store the data received */
int bytes_read = 0; /* Number of bytes read by the read() system call */
int i = 0;
tcflush(fd, TCIFLUSH); /* Discards old data in the rx buffer */
bytes_read = read(fd,&read_buffer,32); /* Read the data */
printf("\n\n Bytes Rxed -%d", bytes_read); /* Print the number of bytes read */
printf("\n\n ");
for(i=0;i<13;i++) /*printing only the needed bytes*/
printf("%c",read_buffer[i]);
printf("\n +----------------------------------+\n\n\n");
close(fd); /* Close the serial port */
}
哪些输出:
+----------------------------------+
| Serial Port Read |
+----------------------------------+
ttyUSB0 Opened Successfully
BaudRate = 19200
StopBits = 1
Parity = none
Bytes Rxed -13
-2.864104E-14
+----------------------------------+
但是,为了让它能够读取值,我必须回显“READ?”每次我想知道值时,命令(或使用 write() 函数写入设备)。
我怎样才能以最优雅的方式将写入和读取写入同一个应用程序(例如,不使用命名管道),因为目前 read() 函数等待来自设备的任何东西,在此期间我可以不发送“阅读?”来自同一 C 代码的命令?
编辑:显然我的写作程序似乎不能正常工作:
端口设置:
struct termios SerialPortSettings; /* Create the structure */
tcgetattr(fd, &SerialPortSettings); /* Get the current attributes of the Serial port */
cfsetispeed(&SerialPortSettings,(speed_t)B19200); /* Set Read Speed as 19200 */
cfsetospeed(&SerialPortSettings,(speed_t)B19200); /* Set Write Speed as 19200 */
SerialPortSettings.c_cflag &= ~PARENB; /* Disables the Parity Enable bit(PARENB),So No Parity */
SerialPortSettings.c_cflag &= ~CSTOPB; /* CSTOPB = 2 Stop bits,here it is cleared so 1 Stop bit */
SerialPortSettings.c_cflag &= ~CSIZE; /* Clears the mask for setting the data size */
SerialPortSettings.c_cflag |= CS8; /* Set the data bits = 8 */
SerialPortSettings.c_cflag = ~CRTSCTS; /* No Hardware flow Control */
SerialPortSettings.c_cflag |= CREAD | CLOCAL; /* Enable receiver,Ignore Modem Control lines */
cfmakeraw(&SerialPortSettings);
tcflush(fd,TCIFLUSH);
SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY); // Disable XON/XOFF flow control both i/p and o/p
SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG); // Non Cannonical mode
SerialPortSettings.c_oflag &= ~OPOST;//No Output Processing
写作:
char write_buffer[] = "READ?"; /* Buffer containing characters to write into port */
int bytes_written = 0; /* Value for storing the number of bytes written to the port */
bytes_written = write(fd,&write_buffer,sizeof(write_buffer) -1);
printf("%s written to ttyUSB0 \n",write_buffer);
printf("%d Bytes written to ttyUSB0 \n", bytes_written);
printf("+----------------------------------+\n\n");
close(fd);/* Close the Serial port */
每当它运行时,我得到:
+----------------------------------+
| Serial Port Write |
+----------------------------------+
ttyUSB0 Opened Successfully
Attributes set
READ? written to ttyUSB0
5 Bytes written to ttyUSB0
+----------------------------------+
但是 cat/dev/ttyUSB0
似乎没有看到任何来自设备的信息。我已经检查了类似的问题:
Linux C Serial Port Reading/Writing
并且在代码中找不到大的差异 - 这会是端口设置错误的标志还是我遗漏了什么?
最佳答案
问题已解决!
显然,设备正在等待行尾终止符,这在 char write_buffer[] = "READ?";
因此,当它收到这样的命令时,总线将“挂起”,为了使其再次工作,必须再次打开端口。
这也解释了为什么 echo "READ?">/dev/ttyUSB0
命令有效 - 因为它会自动输出一个结束行终止符。
我在下面附上了工作代码 - 感谢大家的评论和帮助!
int fd; //device file id
//------------------------------- Opening the Serial Port -------------------------------
fd = open("/dev/ttyUSB0",O_RDWR | O_NOCTTY); // ttyUSB0 is the FT232 based USB2SERIAL Converter
if(fd == -1) // Error Checking
printf("Error while opening the device\n");
//---------- Setting the Attributes of the serial port using termios structure ---------
struct termios SerialPortSettings; // Create the structure
tcgetattr(fd, &SerialPortSettings); // Get the current attributes of the Serial port
// Setting the Baud rate
cfsetispeed(&SerialPortSettings,B19200); // Set Read Speed as 19200
cfsetospeed(&SerialPortSettings,B19200); // Set Write Speed as 19200
SerialPortSettings.c_cflag &= ~PARENB; // Disables the Parity Enable bit(PARENB),So No Parity
SerialPortSettings.c_cflag &= ~CSTOPB; // CSTOPB = 2 Stop bits,here it is cleared so 1 Stop bit
SerialPortSettings.c_cflag &= ~CSIZE; // Clears the mask for setting the data size
SerialPortSettings.c_cflag |= CS8; // Set the data bits = 8
SerialPortSettings.c_cflag &= ~CRTSCTS; // No Hardware flow Control
SerialPortSettings.c_cflag |= CREAD | CLOCAL; // Enable receiver,Ignore Modem Control lines
SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY); // Disable XON/XOFF flow control both i/p and o/p
SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG); // Non Cannonical mode
SerialPortSettings.c_oflag &= ~OPOST;//No Output Processing
// Setting Time outs
SerialPortSettings.c_cc[VMIN] = 13; // Read at least 10 characters
SerialPortSettings.c_cc[VTIME] = 0; // Wait indefinetly
if((tcsetattr(fd,TCSANOW,&SerialPortSettings)) != 0) // Set the attributes to the termios structure
printf("Error while setting attributes \n");
//------------------------------- Read data from serial port -----------------------------
char read_buffer[32]; // Buffer to store the data received
int bytes_read = 0; // Number of bytes read by the read() system call
int bytes_written = 0; // Number of bytes written
int i = 0;
tcflush(fd, TCIFLUSH); // Discards old data in the rx buffer
//Device intialization
char write_buffer[]="READ? \n ";
bytes_written=write(fd,&write_buffer,sizeof(write_buffer));
bytes_read = read(fd,&read_buffer,32); // Read the data
for(i=0;i<13;i++) //printing only the needed characters
printf("%c",read_buffer[i]);
close(fd); // Close the serial port
关于c - C中的串行通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42071068/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!