当前位置:首页 > 嵌入式 > 嵌入式软件
[导读] 据通信的基本方式可分为并行通信与串行通信两种。· 并行通信是指利用多条数据传输线将一个资料的各位同时传送。它的特点是传输速度快,适用于短距离通信,但要求传

 据通信的基本方式可分为并行通信与串行通信两种。

· 并行通信是指利用多条数据传输线将一个资料的各位同时传送。它的特点是传输速度

快,适用于短距离通信,但要求传输速度较高的应用场合。

· 串行通信是指利用一条传输线将资料一位位地顺序传送。特点是通信线路简单,利用

简单的线缆就可实现通信,降低成本,适用于远距离通信,但传输速度慢的应用场合。

串口设置详解

本节主要讲解设置串口的主要方法。

如前所述,设置串口中最基本的包括波特率设置,校验位和停止位设置。串口的设置主

要是设置struct termios结构体的各成员值,如下所示:

#include

struct termio

{

unsigned short c_iflag; /* 输入模式标志 */

unsigned short c_oflag; /* 输出模式标志 */

unsigned short c_cflag; /* 控制模式标志*/

unsigned short c_lflag; /*本地模式标志 */

unsigned char c_line; /* line discipline */

unsigned char c_cc[NCC]; /* control characters */

};

在这个结构中最为重要的是c_cflag,通过对它的赋值,用户可以设置波特率、字符大小、

数据位、停止位、奇偶校验位和硬件流控等。另外c_iflag 和c_cc 也是比较常用的标志。在

此主要对这3 个成员进行详细说明。

c_cflag支持的常量名称

CBAUD 波特率的位掩码

B0 0波特率(放弃DTR)

B1800 1800波特率

B2400 2400波特率

B4800 4800波特率

B9600 9600波特率

B19200 19200波特率

B38400 38400波特率

B57600 57600波特率

B115200 115200波特率

EXTA 外部时钟率

EXTB 外部时钟率

CSIZE 数据位的位掩码

CS5 5个数据位

CS6 6个数据位

CS7 7个数据位

CS8 8个数据位

CSTOPB 2个停止位(不设则是1个停止位)

CREAD 接收使能

PARENB 校验位使能

PARODD 使用奇校验而不使用偶校验

HUPCL 最后关闭时挂线(放弃DTR)

CLOCAL 本地连接(不改变端口所有者)

LOBLK 块作业控制输出

CNET_CTSRTS 硬件流控制使能

c_iflag支持的常量名称

INPCK 奇偶校验使能

IGNPAR 忽略奇偶校验错误

PARMRK 奇偶校验错误掩码

ISTRIP 除去奇偶校验位

IXON 启动出口硬件流控

IXOFF 启动入口软件流控

IXANY 允许字符重新启动流控

IGNBRK 忽略中断情况

BRKINT 当发生中断时发送SIGINT信号

INLCR 将NL映射到CR

IGNCR 忽略CR

ICRNL 将CR映射到NL

IUCLC 将高位情况映射到低位情况

IMAXBEL 当输入太长时回复ECHO

c_cc 支持的常量名称

VINTR 中断控制,对应键为CTRL+C

VQUIT 退出操作,对应键为CRTL+Z

VERASE 删除操作,对应键为Backspace(BS)

VKILL 删除行,对应键为CTRL+U

VEOF 位于文件结尾,对应键为CTRL+D

VEOL 位于行尾,对应键为Carriage return(CR)

VEOL2 位于第二行尾,对应键为Line feed(LF)

VMIN 指定了最少读取的字符数

VTIME 指定了读取每个字符的等待时间

串口控制函数

Tcgetattr 取属性(termios结构)

Tcsetattr 设置属性(termios结构)

cfgetispeed 得到输入速度

Cfgetospeed 得到输出速度

Cfsetispeed 设置输入速度

Cfsetospeed 设置输出速度

Tcdrain 等待所有输出都被传输

tcflow 挂起传输或接收

tcflush 刷清未决输入和/或输出

Tcsendbreak 送BREAK字符

tcgetpgrp 得到前台进程组ID

tcsetpgrp 设置前台进程组ID

[color=#ff0000]完整的串口配置模板,实用!把常用的选项在函数里面列出,可大大方便用户的调试使用[/color]

int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)

{

struct termios newtio,oldtio;

/*保存测试现有串口参数设置,在这里如果串口号等出错,会有相关的出错信息*/

if ( tcgetattr( fd,&oldtio) != 0)

{

perror("SetupSerial 1");

return -1;

}

bzero( &newtio, sizeof( newtio ) );

/*步骤一,设置字符大小*/

newtio.c_cflag |= CLOCAL | CREAD;

newtio.c_cflag &= ~CSIZE;

/*设置停止位*/

switch( nBits )

{

case 7:

newtio.c_cflag |= CS7;

break;

case 8:

newtio.c_cflag |= CS8;

break;

}

/*设置奇偶校验位*/

switch( nEvent )

{

case 'O': //奇数

newtio.c_cflag |= PARENB;

newtio.c_cflag |= PARODD;

newtio.c_iflag |= (INPCK | ISTRIP);

break;

case 'E': //偶数

newtio.c_iflag |= (INPCK | ISTRIP);

newtio.c_cflag |= PARENB;

newtio.c_cflag &= ~PARODD;

break;

case 'N': //无奇偶校验位

newtio.c_cflag &= ~PARENB;

break;

}

/*设置波特率*/

switch( nSpeed )

{

case 2400:

cfsetispeed(&newtio, B2400);

cfsetospeed(&newtio, B2400);

break;

case 4800:

cfsetispeed(&newtio, B4800);

cfsetospeed(&newtio, B4800);

break;

case 9600:

cfsetispeed(&newtio, B9600);

cfsetospeed(&newtio, B9600);

break;

case 115200:

cfsetispeed(&newtio, B115200);

cfsetospeed(&newtio, B115200);[!--empirenews.page--]

break;

case 460800:

cfsetispeed(&newtio, B460800);

cfsetospeed(&newtio, B460800);

break;

default:

cfsetispeed(&newtio, B9600);

cfsetospeed(&newtio, B9600);

break;

}

/*设置停止位*/

if( nStop == 1 )

newtio.c_cflag &= ~CSTOPB;

else if ( nStop == 2 )

newtio.c_cflag |= CSTOPB;

/*设置等待时间和最小接收字符*/

newtio.c_cc[VTIME] = 0;

newtio.c_cc[VMIN] = 0;

/*处理未接收字符*/

tcflush(fd,TCIFLUSH);

/*激活新配置*/

if((tcsetattr(fd,TCSANOW,&newtio))!=0)

{

perror("com set error");

return -1;

}

printf("set done!\n");

return 0;

}

[b]串口使用详解[/b]

在配置完串口的相关属性后,就可对串口进行打开,读写操作了。其使用方式与文件操作一样,区别在于串口是一个终端设备。

[b]打开串口[/b]

fd = open( "/dev/ttyS0", O_RDWR|O_NOCTTY|O_NDELAY);

Open函数中除普通参数外,另有两个参数O_NOCTTY和O_NDELAY。

O_NOCTTY: 通知linix系统,这个程序不会成为这个端口的控制终端。

O_NDELAY: 通知linux系统不关心DCD信号线所处的状态(端口的另一端是否激活或者停止)。

然后,恢复串口的状态为阻塞状态,用于等待串口数据的读入。用fcntl函数:

fcntl(fd, F_SETFL, 0);

接着,测试打开的文件描述府是否引用一个终端设备,以进一步确认串口是否正确打开。

isatty(STDIN_FILENO);

串口的读写与普通文件一样,使用read,write函数。

read(fd,buff,8);

write(fd,buff,8);

实例

#i nclude stdio.h>

#i nclude string.h>

#i nclude sys/types.h>

#i nclude errno.h>

#i nclude sys/stat.h>

#i nclude fcntl.h>

#i nclude unistd.h>

#i nclude termios.h>

#i nclude stdlib.h>

int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)

{

struct termios newtio,oldtio;

if ( tcgetattr( fd,&oldtio) != 0) {

perror("SetupSerial 1");

return -1;

}

bzero( &newtio, sizeof( newtio ) );

newtio.c_cflag |= CLOCAL | CREAD;

newtio.c_cflag &= ~CSIZE;

switch( nBits )

{

case 7:

newtio.c_cflag |= CS7;

break;

case 8:

newtio.c_cflag |= CS8;

break;

}

switch( nEvent )

{

case 'O':

newtio.c_cflag |= PARENB;

newtio.c_cflag |= PARODD;

newtio.c_iflag |= (INPCK | ISTRIP);

break;

case 'E':

newtio.c_iflag |= (INPCK | ISTRIP);

newtio.c_cflag |= PARENB;

newtio.c_cflag &= ~PARODD;

break;

case 'N':

newtio.c_cflag &= ~PARENB;

break;

}

switch( nSpeed )

{

case 2400:

cfsetispeed(&newtio, B2400);

cfsetospeed(&newtio, B2400);

break;

case 4800:

cfsetispeed(&newtio, B4800);

cfsetospeed(&newtio, B4800);

break;

case 9600:

cfsetispeed(&newtio, B9600);

cfsetospeed(&newtio, B9600);

break;

case 115200:

cfsetispeed(&newtio, B115200);

cfsetospeed(&newtio, B115200);

break;

default:

cfsetispeed(&newtio, B9600);

cfsetospeed(&newtio, B9600);

break;

}

if( nStop == 1 )

newtio.c_cflag &= ~CSTOPB;

else if ( nStop == 2 )

newtio.c_cflag |= CSTOPB;

newtio.c_cc[VTIME] = 0;

newtio.c_cc[VMIN] = 0;

tcflush(fd,TCIFLUSH);

if((tcsetattr(fd,TCSANOW,&newtio))!=0)

{

perror("com set error");

return -1;

}

printf("set done!\n");

return 0;

}

int open_port(int fd,int comport)

{

char *dev[]={"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2"};

long vdisable;

if (comport==1)

{ fd = open( "/dev/ttyS0", O_RDWR|O_NOCTTY|O_NDELAY);

if (-1 == fd){

perror("Can't Open Serial Port");

return(-1);

}

else

printf("open ttyS0 .....\n");

}

else if(comport==2)

{ fd = open( "/dev/ttyS1", O_RDWR|O_NOCTTY|O_NDELAY);

if (-1 == fd){

perror("Can't Open Serial Port");

return(-1);

}

else

printf("open ttyS1 .....\n");

}

else if (comport==3)

{

fd = open( "/dev/ttyS2", O_RDWR|O_NOCTTY|O_NDELAY);

if (-1 == fd){

perror("Can't Open Serial Port");

return(-1);

}

else

printf("open ttyS2 .....\n");

}

if(fcntl(fd, F_SETFL, 0)0)

printf("fcntl failed!\n");

else[!--empirenews.page--]

printf("fcntl=%d\n",fcntl(fd, F_SETFL,0));

if(isatty(STDIN_FILENO)==0)

printf("standard input is not a terminal device\n");

else

printf("isatty success!\n");

printf("fd-open=%d\n",fd);

return fd;

}

int main(void)

{

int fd;

int nread,i;

char buff[]="Hello\n";

if((fd=open_port(fd,1))0){

perror("open_port error");

return;

}

if((i=set_opt(fd,115200,8,'N',1))0){

perror("set_opt error");

return;

}

printf("fd=%d\n",fd);

// fd=3;

nread=read(fd,buff,8);

printf("nread=%d,%s\n",nread,buff);

close(fd);

return;

}

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭