我正在开发一个新项目,我希望与连接到我的debian机器的FTDI建立连接。我打算用C编写代码,而不是C ++。这就是我的问题。我发现的所有示例都不完整,或者是针对c ++编译器而不是GCC编译器。
目标是与连接到FTDI的微控制器通信。为了调试我想开始构建一个能够:
的Linux应用程序是否有任何示例代码或教程来实现此目的?
如果我成功了,我会将代码放在这里,以便新观众可以使用它!
修改
就像我说的,如果我拥有它,我会发布代码,这对我有用:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#define MODEM "/dev/ttyUSB0"
#define BAUDRATE B115200
int main(int argc,char** argv)
{
struct termios tio;
struct termios stdio;
struct termios old_stdio;
int tty_fd, flags;
unsigned char c='D';
tcgetattr(STDOUT_FILENO,&old_stdio);
printf("Please start with %s /dev/ttyS1 (for example)\n",argv[0]);
memset(&stdio,0,sizeof(stdio));
stdio.c_iflag=0;
stdio.c_oflag=0;
stdio.c_cflag=0;
stdio.c_lflag=0;
stdio.c_cc[VMIN]=1;
stdio.c_cc[VTIME]=0;
tcsetattr(STDOUT_FILENO,TCSANOW,&stdio);
tcsetattr(STDOUT_FILENO,TCSAFLUSH,&stdio);
fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK); // make the reads non-blocking
memset(&tio,0,sizeof(tio));
tio.c_iflag=0;
tio.c_oflag=0;
tio.c_cflag=CS8|CREAD|CLOCAL; // 8n1, see termios.h for more information
tio.c_lflag=0;
tio.c_cc[VMIN]=1;
tio.c_cc[VTIME]=5;
if((tty_fd = open(MODEM , O_RDWR | O_NONBLOCK)) == -1){
printf("Error while opening\n"); // Just if you want user interface error control
return -1;
}
cfsetospeed(&tio,BAUDRATE);
cfsetispeed(&tio,BAUDRATE); // baudrate is declarated above
tcsetattr(tty_fd,TCSANOW,&tio);
while (c!='q'){
if (read(tty_fd,&c,1)>0){
write(STDOUT_FILENO,&c,1); // if new data is available on the serial port, print it out
printf("\n");
}
if (read(STDIN_FILENO,&c,1)>0){
write(tty_fd,&c,1);//if new data is available on the console, send it to serial port
printf("\n");
}
}
close(tty_fd);
tcsetattr(STDOUT_FILENO,TCSANOW,&old_stdio);
return EXIT_SUCCESS;
}
大多数代码来自http://en.wikibooks.org/wiki/Serial_Programming/Serial_Linux,但我也使用了下面发布的代码中的一些代码。
答案 0 :(得分:3)
使用串口处理(适用于Linux OS):
- 要打开通信,您需要一个描述符作为串口的句柄
- 设置标志以控制通信的方式
- 将命令写入此Handle(确保正确格式化输入)
- 得到答案。 (确保你要阅读你想要的信息量)
- 关闭手柄。
它看起来像这样:
int fd; // file descriptor
int flags; // communication flags
int rsl_len; // result size
char message; // message to send
char result; // result to read
flags = O_RDWR | O_NOCTTY; // Read and write, and make the job control for portability
if ((fd = open("/dev/ttyUSB1", flags)) == -1 ) {
printf("Error while opening\n"); // Just if you want user interface error control
return -1;
}
// In this point your communication is already estabilished, lets send out something
strcpy(message, "Hello");
if (rsl_len = write(fd, message, strlen(message)) < 0 ) {
printf("Error while sending message\n"); // Again just in case
return -2;
}
if (rsl_len = read(fd, &result, sizeof(result)) < 0 ) {
printf("Error while reading return\n");
return -3;
}
close(fd);
请注意,您必须关心要写什么和要读什么。 在奇偶校验控制,停止位,波特率等情况下,可以使用更多标志。
答案 1 :(得分:0)
由于gcc是C / C ++编译器,因此您无需将自己限制为纯C。
如果您喜欢编写大量样板代码,如果您真的知道自己在做什么,那么坚持使用纯C就行了。许多人错误地使用Unix API,并且很多示例代码太简单了。至少可以说,编写正确的Unix C代码有点烦人。
就个人而言,我建议不仅要使用C ++,还要使用像Qt这样的高级应用程序开发框架。 Qt 5捆绑了一个QtSerialPort模块,可以轻松枚举串行端口,配置它们,并将数据输入和输出。 Qt不会强制您使用gui模块,它可以是命令行应用程序,也可以是非交互式服务器/守护程序。
QtSerialPort也可用于Qt 4,但它没有与Qt 4捆绑在一起,你必须将它添加到你的项目中。我建议从Qt 5开始,使用它的C ++ 11支持更好。
使用Qt的代码非常简单,不会比普通英语描述长得多。以下是使用Qt 5和C ++ 11的Qt控制台应用程序。它使用core
和serialport
模块。它还handles the SIGINT
signal,以便在进程因^C
而终止之前刷新输出文件。我使用QLocalSocket
代替原始Unix API来从Unix信号处理程序进行通信,功能是相同的。
仅严格要求main
中的代码,其余的只是为了在您点击^C
时正确包装。
#include <QCoreApplication>
#include <QSerialPort>
#include <QFile>
#include <QTextStream>
#include <QLocalServer>
#include <QLocalSocket>
#include <cstdio>
#include <csignal>
QLocalSocket * xmit;
static void signalHandler(int)
{
xmit->write(" ");
xmit->flush();
}
static bool setupSignalHandler()
{
QLocalServer srv;
srv.listen("foobarbaz");
xmit = new QLocalSocket(qApp);
xmit->connectToServer(srv.serverName(), QIODevice::WriteOnly);
srv.waitForNewConnection();
QLocalSocket * receive = srv.nextPendingConnection();
receive->setParent(qApp);
qApp->connect(receive, &QLocalSocket::readyRead, &QCoreApplication::quit);
struct sigaction sig;
sig.sa_handler = signalHandler;
sigemptyset(&sig.sa_mask);
sig.sa_flags = SA_RESTART;
return ! sigaction(SIGINT, &sig, NULL);
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
setupSignalHandler();
QSerialPort port("ttyUSB1");
QFile file("file.txt");
QTextStream err(stderr, QIODevice::WriteOnly);
QTextStream out(stdout, QIODevice::WriteOnly);
if (!file.open(QIODevice::WriteOnly)) {
err << "Couldn't open the output file" << endl;
return 1;
}
if (!port.open(QIODevice::ReadWrite)) {
err << "Couldn't open the port" << endl;
return 2;
}
port.setBaudRate(9600);
QObject::connect(&port, &QSerialPort::readyRead, [&](){
QByteArray data = port.readAll();
out << data;
file.write(data);
});
out << "Use ^C to quit" << endl;
return a.exec();
}