功能:
- 调试建议按ASCII字符格式进行收发;
- 点击”Receive”按钮之后,等待接收到的字符数据,如果接收到字符数据则显示;
- 简单了解如何使用 termios 结构体和相关函数完成串口的初始化等操作;
- 关于 termios 结构体更多内容,可以参考:
https://www.softool.cn/blog-159.html
https://www.softool.cn/blog-158.html
https://www.softool.cn/blog-157.html
效果:

源码:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <gtk/gtk.h>
int serial_fd;
int init_serial();
void closeApp (GtkWidget *window, gpointer data) {
gtk_main_quit();
}
void send_button_clicked (GtkWidget *button, gpointer data) {
char buf[512];
const char *send_text = gtk_entry_get_text(GTK_ENTRY((GtkWidget *) data));
memset(buf, '\0', sizeof(buf)/sizeof(buf));
strcpy(buf,send_text);
int len = strlen(buf);
int send_number = write (serial_fd, buf, len);
}
void receive_button_clicked (GtkWidget *button, gpointer data) {
char buffer[512];
int read_number;
memset(buffer,'\0',sizeof(buffer)/sizeof(char));
if ( (read_number = read(serial_fd, buffer, 512))>0 ) {
gtk_entry_set_text(GTK_ENTRY((GtkWidget *)data), buffer);
memset(buffer,'\0',sizeof(buffer)/sizeof(char));
}
}
int main (int argc, char *argv[]) {
init_serial();
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "www.softool.cn - 串口收发");
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 200, 200);
gtk_signal_connect ( GTK_OBJECT (window), "destroy",
GTK_SIGNAL_FUNC ( closeApp), NULL);
GtkWidget *send_label = gtk_label_new("send:");
GtkWidget *receive_label = gtk_label_new("receive:");
GtkWidget *send_entry = gtk_entry_new();
GtkWidget *receive_entry = gtk_entry_new();
GtkWidget *send_button = gtk_button_new_with_label("Send");
GtkWidget *receive_button = gtk_button_new_with_label("Receive");
gtk_signal_connect (GTK_OBJECT (send_button), "clicked",
GTK_SIGNAL_FUNC(send_button_clicked), send_entry);
gtk_signal_connect (GTK_OBJECT (receive_button), "clicked",
GTK_SIGNAL_FUNC(receive_button_clicked),
receive_entry
);
GtkWidget *hbox1 = gtk_hbox_new ( TRUE, 5 );
GtkWidget *hbox2 = gtk_hbox_new ( TRUE, 5 );
GtkWidget *hbox3 = gtk_hbox_new ( TRUE, 5 );
GtkWidget *vbox = gtk_vbox_new ( FALSE, 10);
gtk_box_pack_start(GTK_BOX(hbox1), send_label, TRUE, FALSE, 5);
gtk_box_pack_start(GTK_BOX(hbox1), send_entry, TRUE, FALSE, 5);
gtk_box_pack_start(GTK_BOX(hbox2), receive_label, TRUE, FALSE, 5);
gtk_box_pack_start(GTK_BOX(hbox2), receive_entry, TRUE, FALSE, 5);
gtk_box_pack_start(GTK_BOX(hbox3), send_button, TRUE, FALSE, 5);
gtk_box_pack_start(GTK_BOX(hbox3), receive_button, TRUE, FALSE, 5);
gtk_box_pack_start(GTK_BOX(vbox), hbox1, FALSE, FALSE, 5);
gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 5);
gtk_box_pack_start(GTK_BOX(vbox), hbox3, FALSE, FALSE, 5);
gtk_container_add(GTK_CONTAINER(window), vbox);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
int OpenDev(char *Dev) {
int fd = open( Dev, O_RDWR );
if (-1 == fd) {
perror("Can't Open Serial Port");
return -1;
}
else
{
return fd;
}
}
void set_speed(int fd, int speed);
int init_serial() {
int nread;
char *dev = "/dev/ttyS1";
serial_fd = OpenDev(dev);
set_speed(serial_fd,9600);
if (set_Parity(serial_fd, 8, 1, 'N') == FALSE) {
printf("Set Parity Error\n");
exit (0);
}
return 0;
}
int speed_arr[] = {
B38400, B19200, B9600, B4800, B2400, B1200, B300,
B38400, B19200, B9600, B4800, B2400, B1200, B300,
};
int name_arr[] = {
38400, 19200, 9600, 4800, 2400, 1200, 300, 38400,
19200, 9600, 4800, 2400, 1200, 300,
};
void set_speed(int fd, int speed) {
int i;
int status;
struct termios Opt;
tcgetattr(fd, &Opt);
for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++) {
if (speed == name_arr[i]) {
tcflush(fd, TCIOFLUSH);
cfsetispeed(&Opt, speed_arr[i]);
cfsetospeed(&Opt, speed_arr[i]);
status = tcsetattr(fd, TCSANOW, &Opt);
if (status != 0) {
perror("tcsetattr fd");
return;
}
tcflush(fd,TCIOFLUSH);
}
}
}
int set_Parity(int fd, int databits,int stopbits,int parity) {
struct termios options;
if ( tcgetattr( fd,&options) != 0) {
perror("SetupSerial 1");
return(FALSE);
}
options.c_cflag &= ~CSIZE;
switch (databits) {
case 7:
options.c_cflag |= CS7;
break;
case 8:
options.c_cflag |= CS8;
break;
default:
fprintf(stderr,"Unsupported data size\n");
return (FALSE);
}
switch (parity) {
case 'n':
case 'N':
options.c_cflag &= ~PARENB;
options.c_iflag &= ~INPCK;
break;
case 'o':
case 'O':
options.c_cflag |= (PARODD | PARENB);
options.c_iflag |= INPCK;
break;
case 'e':
case 'E':
options.c_cflag |= PARENB;
options.c_cflag &= ~PARODD;
options.c_iflag |= INPCK;
break;
case 's':
case 'S':
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
break;
default:
fprintf(stderr,"Unsupported parity\n");
return (FALSE);
}
if (parity != 'n')
options.c_iflag |= INPCK;
switch (stopbits) {
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
fprintf(stderr,"Unsupported stop bits\n");
return (FALSE);
}
tcflush(fd,TCIFLUSH);
options.c_cc[VTIME] = 100;
options.c_cc[VMIN] = 0;
if (tcsetattr(fd, TCSANOW, &options) != 0) {
perror("SetupSerial 3");
return (FALSE);
}
return (TRUE);
}
作者:蟲蟲
http://blog.sina.com.cn/s/blog_6f1e688e0100mgkc.html