昨天下午开始实验一个向串口发送和接受数据的程序,由于犯了一个很低级的错误,昨晚没搞出来。今天上午总算反应过来了,呵呵。程序在Ubuntu下用GCC编译通过。现在把代码贴在下面。
#include
#include
#include
#include
#include
void set_speed(int, int);
int main()
{
int fd,flag,wr_num=0,rd_num=0;
struct termios term;
speed_t baud_rate_i,baud_rate_o;
char send_buf[]="hello,serial!",recv_buf[20];
fd=open("/dev/ttyS0",O_RDWR|O_NONBLOCK);
if(fd==-1)
printf("can not open the COM1!\n");
else
printf("open COM1 ok!\n");
flag=tcgetattr(fd,&term);/*取得终端设备fd的属性,存放在termios类型的结构体term中*/
baud_rate_i=cfgetispeed(&term);/*从term中读取输入波特率*/
baud_rate_o=cfgetospeed(&term);/*从term中读取输出波特率*/
printf("输入波特率是%d,输出波特率是%d,文件描述符是%d\n",baud_rate_i,baud_rate_o,fd);
set_speed(fd,9600);/*设置波特率*/
flag=tcgetattr(fd,&term);/*以下三行读取设置之后的波特率,用cfgetispeed和cfgetospeed得到的波特率是一个序号,可以通过查表(表见程序后面)得到真正的波特率,比如返回13,对应的实际波特率是9600。我这里没有做转换,直接把13输出了。*/
baud_rate_i=cfgetispeed(&term);
baud_rate_o=cfgetospeed(&term);
printf("输入波特率是%d,输出波特率是%d,文件描述符是%d\n",baud_rate_i,baud_rate_o,fd);
while(1)
{
wr_num=write(fd,send_buf,sizeof(send_buf));/*先写入*/
if(wr_num>0)
printf("write success!\n");
else
printf("write fail!\n");
sleep(1);
rd_num=read(fd,recv_buf,sizeof(recv_buf));/*再读出*/
if(rd_num>0)
printf("we can read \"%s\" from the COM1.total:%d characters\n",recv_buf,rd_num);
else
printf("read fail!\n");
sleep(2);
}
}
/***下面这个set_speed的子程序是在网上别的文章中摘抄过来的,就直接调用了,省了自己编写的麻烦***/
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 fd1");
return;
}
tcflush(fd,TCIOFLUSH);
}
}
}
下面是函数cfgetispeed和cfgetospeed返回值与波特率的对应表,通过 man cfsetispeed 可以找到,虽然文档里面没有标返回值标号,但是从第一个开始按0数的话,数到13恰好就是9600,我在程序中还试过用set_speed把波特率设为4800,结果返回的是12。证明这样查表应该是正确的,但我不明白为什么不能直接返回像4800和9600这样的数,因为此前在别人的程序中看到似乎是可以直接返回的,这个地方暂时还不太明白。
B0
B50
B75
B110
B134
B150
B200
B300
B600
B1200
B1800
B2400
B4800
B9600
B19200
B38400
B57600
B115200
B230400
最后注意一点,就是我昨天晚上犯的很弱智的错误,没有连接串口的接收引脚和发送引脚。因为这个串口程序是本机自收自发的,因此一定要用一根导线之类的东西把计算机九针串口的2、3引脚连起来,否则自己发送的数据自己接受不到。如果没有导线的话,随便一个金属的物品也行(注意着点,别把电脑捅坏,也别捅错地方连了电电着自己。呵呵,不过一般应该没太大问题,但小心些总是没错的^_^)。我就是在运行程序之后,再用一个螺丝刀同时触碰这两个引脚的。
下面是程序运行结果:
========================
admin@admin-desktop:/myfiles/test$ ./serial
open COM1 ok!
输入波特率是13,输出波特率是13,文件描述符是3
输入波特率是13,输出波特率是13,文件描述符是3
write success!
read fail!(这个时候还没用螺丝刀去连收发管脚呢,因此接收不到,但发送是成功的。)
write success!
read fail!
write success!
we can read "hello,serial!" from the COM1.total:14 characters(连上了,呵呵)
write success!
we can read "hello,serial!" from the COM1.total:14 characters
write success!
we can read "hello,serial!" from the COM1.total:14 characters
你的赞赏是我坚持原创的动力
赞赏
共 0 人赞赏