嵌入式系统串口解析二进制数_如何在C程序中通过串口终端读取二进制数据?...

system("stty erase ^H);system("stty -F /dev/ttyS0 -icrnl -ixon -ixoff -opost -isig -icanon -echo");    // enter into non-canonical (raw) mode

这将是不充分的代码(以及每个POSIX约定的不良编码实践)将串行端口置于原始或非规范模式。

C和Linux中最简单的方法是使用cfmakeraw()GNU libc和uClibc库中提供的函数。使用手册页获取有关修改的termios结构成员的详细信息cfmakeraw()。

请注意,对于10位的总字符帧(假设一个停止位),cfmakeraw()将在原始模式下设置串行端口,数据长度为8位且无奇偶校验。

首选方法是保留termios结构的副本(用于程序退出时的恢复)并仅修改所需的标志位(而不是编写完整的结构成员)。

修订

适用于我的ARM SoC的代码是:#include #include #include #include #include #include #include #include #include #include #include #define SERIALPORT_IS_CONSOLEmain(){

struct termios  tty;

struct termios  savetty;

speed_t     spd;

unsigned int    sfd;

unsigned char   buf[80];

int     reqlen = 79;

int     rc;

int     rdlen;

int     pau = 0;#ifdef SERIALPORT_IS_CONSOLE

sfd = STDIN_FILENO;#else

sfd = open("/dev/ttyS1", O_RDWR | O_NOCTTY);#endif

if (sfd 

syslog(LOG_DEBUG, "failed to open: %d, %s", sfd, strerror(errno));

exit (-1);

}

syslog(LOG_DEBUG, "opened sfd=%d for reading", sfd);

rc = tcgetattr(sfd, &tty);

if (rc 

syslog(LOG_DEBUG, "failed to get attr: %d, %s", rc, strerror(errno));

exit (-2);

}

savetty = tty;    /* preserve original settings for restoration */

spd = B115200;

cfsetospeed(&tty, (speed_t)spd);

cfsetispeed(&tty, (speed_t)spd);

cfmakeraw(&tty);

tty.c_cc[VMIN] = 1;

tty.c_cc[VTIME] = 10;

tty.c_cflag &= ~CSTOPB;

tty.c_cflag &= ~CRTSCTS;    /* no HW flow control? */

tty.c_cflag |= CLOCAL | CREAD;

rc = tcsetattr(sfd, TCSANOW, &tty);

if (rc 

syslog(LOG_DEBUG, "failed to set attr: %d, %s", rc, strerror(errno));

exit (-3);

}

do {

unsigned char   *p = buf;

rdlen = read(sfd, buf, reqlen);

if (rdlen > 0) {

if (*p == '\r')

pau = 1;

syslog(LOG_DEBUG, "read: %d, 0x%x 0x%x 0x%x", \

rdlen, *p, *(p + 1), *(p + 2));

} else {

syslog(LOG_DEBUG, "failed to read: %d, %s", rdlen, strerror(errno));

}

} while (!pau);

tcsetattr(sfd, TCSANOW, &savetty);

close(sfd);

exit (0);}

编译的程序在目标板上加载和执行。

从串行通信链路的主机端,seq.bin发送包含以下内容的文件:$ od -t x1 seq.bin0000000 aa 02 fe0000003

然后在主机(运行minicom终端仿真器程序)上键入“ABC” ,然后回车。程序终止于目标,然后检查syslog:# tail /var/log/messages                                                        Sep xx xx:xx:42 atmel_soc user.info kernel: EXT3 FS on nvsram, internal journal Sep xx xx:xx:42 atmel_soc user.info kernel: EXT3-fs: mounted filesystem with or.Sep xx xx:xx:42 atmel_soc user.info kernel: kjournald starting.  Commit intervasSep xx xx:xx:18 atmel_soc auth.info login[431]: root login on 'ttyS0'           Sep xx xx:xx:04 atmel_soc user.debug syslog: opened sfd=0 for reading           Sep xx xx:xx:14 atmel_soc user.debug syslog: read: 3, 0xaa 0x2 0xfe             Sep xx xx:xx:50 atmel_soc user.debug syslog: read: 1, 0x41 0x2 0xfe              Sep xx xx:xx:51 atmel_soc user.debug syslog: read: 1, 0x42 0x2 0xfe              Sep xx xx:xx:51 atmel_soc user.debug syslog: read: 1, 0x43 0x2 0xfe              Sep xx xx:xx:52 atmel_soc user.debug syslog: read: 1, 0xd 0x2 0xfe              #

二进制数据已完整收到。

请注意,由于这是原始模式并且输入的类型字符相对较慢,因此read()返回“部分”数据和用户程序将负责将数据缓冲/组装成完整的“消息”。如果消息具有固定长度,则可以将c_cc[VMIN]成员设置为消息长度。但是,当帧同步丢失时,请注意消息帧的问题和复杂性!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值