免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 7299 | 回复: 6

弱问一个:串口波特率咋设置 [复制链接]

论坛徽章:
0
发表于 2008-09-22 13:50 |显示全部楼层
ioctl ?
details please.

论坛徽章:
0
发表于 2008-09-22 21:07 |显示全部楼层

论坛徽章:
0
发表于 2008-09-22 21:18 |显示全部楼层
其实串口编程的实质就是多串口属性的设置。
而属性也就下面这么几个:
c_cflag Control options
c_lflag Line options
c_iflag Input options
c_oflag Output options
c_cc Control characters
c_ispeed Input baud (new interface)
c_ospeed Output baud (new interface)
关键是理解有那些属性参数可以设置以及是什么意思。

继续找资料。发现下面的经典文章,可以说基本上所有的串口编程的文章都或多或少的参考了这篇文章,《Serial Programming Guide for POSIX Operating Systems》是一定要看的,我读的是5th Edition, 3rd Revision - Updated March 11, 2003,下载地址:http://www.easysw.com/~mike/serial/index.html

当把这篇文章看完之后,基本可以解决串口的设置问题了。不过这是一个英文的版本,本人打算在暑假里把他翻译为中文版本。

关于具体的例子:
http://www.comptechdoc.org/os/li ... inux_pgcserial.html不错,很详细,不过比较复杂。
中文的《Linux Serial HOWTO 中譯版》上面就有不少,也很值得参考。

下面的是我的程序,一个串口读取,往mysql数据库写数据的程序:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include "mysql.h"



#define BAUDRATE B9600
#define DEVICE "/dev/ttyS0"
#define _POSIX_SOURCE 1
#define FALSE 0
#define TRUE 1

int insertdb(int d1, int d2, int d3, int d4) {
MYSQL connect;
int res, no1, no2, sd1, sd2;
char *query = "INSERT INTO mydata  ( stime, sno1, sno2, sdata1, sdata2 ) VALUES ( '%s', %d, %d, %x, %x)";
char *sql, *st1;
struct tm *ptr;
time_t lt;

no1 = d1;
no2 = d2;
sd1 = d3;
sd2 = d4;
lt = time(NULL);
ptr = localtime(&lt);
st1 = (char *)asctime(ptr);
st1[strlen(st1) -1 ] = '\0';
sql = (char *)malloc(255*sizeof(char));
sprintf(sql, query, st1, no1, no2, sd1, sd2);

/* debug here
printf("%c : ", st1[strlen(st1)]);
printf("%s : %d :",sql, strlen(st1));
return EXIT_SUCCESS;
*/

mysql_init(&connect);

if(mysql_real_connect(&connect, "localhost", "root", "root", "mytest", 0, NULL, 0)) {
  printf("connect success!\n");

  res = mysql_query(&connect, sql);

  if(!res) {
   printf("insert success!\n");
  } else {
   fprintf(stderr, "insert error %d: %s\n", mysql_errno(&connect), mysql_error(&connect));
   return EXIT_FAILURE;
  }

  mysql_close(&connect);
} else {
  fprintf(stderr, "connect fail!\n");
  return EXIT_FAILURE;
}

return EXIT_SUCCESS;
}

int main(void) {
int fd, res_w, res_r, i, j, k;
struct termios oldtio,newtio;
char inbuf[255];
char cbuf[4];
int buf[4];

res_w = 0;
res_r = 0;

fd = open(DEVICE, O_RDWR | O_NOCTTY ); // | O_NDELAY);
if(fd < 0) {
  perror(DEVICE);
  exit(-1);
}

tcgetattr(fd, &oldtio);

bzero(&newtio,sizeof(struct termios));

newtio.c_cflag|= (CLOCAL | CREAD);
newtio.c_cflag|=BAUDRATE;
newtio.c_cflag&=~CSTOPB;
newtio.c_cflag&=~PARENB;
newtio.c_cflag&=~CSIZE;
newtio.c_cflag|=CS8;
newtio.c_cflag&=~CRTSCTS;

newtio.c_lflag=0;

newtio.c_oflag=0;

newtio.c_cc[VMIN]=4;
newtio.c_cc[VTIME]=0;

newtio.c_iflag&=~(IXON|IXOFF|IXANY);

cfsetispeed(&newtio, BAUDRATE);
cfsetospeed(&newtio, BAUDRATE);

tcsetattr(fd, TCSANOW, &newtio);

tcflush(fd, TCIFLUSH);

         cbuf[0] = 0x00;
//  cbuf[1] = 0x00;

  j = 0;

for(k = 0; k < 4; k++) {
switch (j) {
  case 0:
  default:
   cbuf[1] = 0x00;
   j = 2;
   break;
  case 2:
   cbuf[1] = 0x02;
   j = 0;
   break;
}
   
res_w = write(fd, cbuf, 2);

/* debug here
printf("cbuf : %x %x \n", cbuf[0], cbuf[1]);
printf("buf : %x : %x : %x : %x \n", inbuf[0], inbuf[1], inbuf[2], inbuf[3]);
*/
res_r = read(fd, &inbuf, 255);

if(res_r != -1) {
  for(i = 0; i < res_r; i++) {
   buf = (int)inbuf;
   buf = buf & 0xff;
  // printf(" %x ", buf);   
  }
  printf("\n");
  if(insertdb(buf[0], buf[1], buf[2], buf[3]))
   printf("insert into db success!");
}
else {
  perror("read fail");
  exit(-1);
}// if end here
}// for end here

tcsetattr(fd, TCSANOW, &oldtio);

close(fd);
exit(0);
} // main end here

评分

参与人数 1可用积分 +15 收起 理由
bitmilong + 15 鼓勵回複

查看全部评分

论坛徽章:
0
发表于 2008-09-24 08:47 |显示全部楼层
我就是参考http://www.comptechdoc.org/os/li ... inux_pgcserial.html写了一个自己的串口终端程序。这个程序不复杂。

论坛徽章:
0
发表于 2008-09-24 11:02 |显示全部楼层
引用于“随点BBS”

Linux 串口编程(附测试程序)

概述:

串口,UART(通用异步收发器),广泛应用于各种场合,本文就Linux下的串口编程,做简单的阐述!

准备知识:

Linux的设备管理比较有意思(vxworks下也是这样),对设备的操作就仿佛是对文件的操作一样,所以

无外乎“打开”,“控制”,“读”,“写”,“关闭”等操作,对应的系统调用就是open,ioctl,read,

write,close。

数据结构分析:

在之前做过的测试和应用的基础上,感觉串口的“终端控制结构”的选项设置比较重要,在系统的

头文件<bits/termios.h>中定义,struct termios,调用tcgetattr和tcsetattr来获取和设置串口的终端属性。


  1. struct termios
  2. 31   {
  3. 32     tcflag_t c_iflag;    /* input mode flags */
  4. 33     tcflag_t c_oflag;    /* output mode flags */
  5. 34     tcflag_t c_cflag;    /* control mode flags */
  6. 35     tcflag_t c_lflag;    /* local mode flags */
  7. 36     cc_t c_line;         /* line discipline */
  8. 37     cc_t c_cc[NCCS];     /* control characters */
  9. 38     speed_t c_ispeed;    /* input speed */
  10. 39     speed_t c_ospeed;    /* output speed */
  11. 40 #define _HAVE_STRUCT_TERMIOS_C_ISPEED 1
  12. 41 #define _HAVE_STRUCT_TERMIOS_C_OSPEED 1
  13. 42   };
复制代码



  1. c_cflag:
  2.         CLOCAL  本地模式,不改变端口的所有者
  3.         CREAD  表示使能数据接收器
  4.         PARENB  表示偶校验
  5.         PARODD  表示奇校验
  6.         CSTOPB  使用两个停止位
  7.         CSIZE  对数据的bit使用掩码
  8.         CS8  数据宽度是8bit
  9. c_lflag:
  10.         ICANON  使能规范输入,否则使用原始数据(本文使用)
  11.         ECHO  回送(echo)输入数据
  12.         ECHOE  回送擦除字符
  13.         ISIG  使能SIGINTR,SIGSUSP, SIGDSUSP和 SIGQUIT 信号
  14. c_iflag:
  15.         IXON  使能输出软件控制
  16.         IXOFF  使能输入软件控制
  17.         IXANY  允许任何字符再次开启数据流
  18.         INLCR  把字符NL(0A)映射到CR(0D)
  19.         IGNCR  忽略字符CR(0D)
  20.         ICRNL  把CR(0D)映射成字符NR(0A)
  21. c_oflag:
  22.         OPOST  输出后处理,如果不设置表示原始数据(本文使用原始数据)
  23.         c_cc[VMIN]  最少可读数据
  24.         c_cc[VTIME]  等待数据时间(10秒的倍数)

复制代码


设置例子:


  1.              tcgetattr(fd, &opt);
  2. 60         tcgetattr(fd, &newOpt);
  3. 61
  4. 62         newOpt.c_cflag |= (CLOCAL | CREAD);
  5. 63         newOpt.c_cflag &= ~CBAUD;
  6. 64         newOpt.c_cflag |= (B115200 | CS8);
  7. 65
  8. 66         newOpt.c_lflag &= ~(ICANON | ISIG | NOFLSH);
  9. 67
  10. 68         newOpt.c_lflag &= ~(ECHO);
  11. 69
  12. 70         newOpt.c_lflag &= ~(ECHOE);
  13. 71
  14. 72
  15. 73         newOpt.c_oflag &= ~(OPOST | ONLCR | OCRNL);
  16. 74
  17. 75         newOpt.c_cc[VMIN]=100;
  18. 76         newOpt.c_cc[VTIME]=2;
  19. 77
  20. 78         tcflush(fd,TCIFLUSH);
  21. 79
  22. 80         ret = tcsetattr(fd, TCSANOW, &newOpt);
复制代码


comTest.rar (1.06 KB, 下载次数: 103)

评分

参与人数 1可用积分 +15 收起 理由
bitmilong + 15 鼓勵

查看全部评分

论坛徽章:
0
发表于 2008-10-06 11:55 |显示全部楼层
好感动哦

太详细了 亲亲

论坛徽章:
5
摩羯座
日期:2014-07-22 09:03:552015元宵节徽章
日期:2015-03-06 15:50:392015亚冠之大阪钢巴
日期:2015-06-12 16:01:352015年中国系统架构师大会
日期:2015-06-29 16:11:2815-16赛季CBA联赛之四川
日期:2018-12-17 14:10:21
发表于 2008-10-06 12:02 |显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP