如何设置linux启动时的51串口波特率设置?

uart_01 linux下设置串口,(波特率,流控等)进行 的读写操作。 -Unix program 238万源代码下载-
&文件名称: uart_01
& & & & &&]
&&所属分类:
&&开发工具: Unix_Linux
&&文件大小: 9 KB
&&上传时间:
&&下载次数: 108
&&提 供 者:
&详细说明:linux下设置串口,(波特率,流控等)进行串口的读写操作。-Set serial port under linux, (baud rate, flow control, etc.) serial port read and write operations.
文件列表(点击判断是否您需要的文件,如果是垃圾请在下面评价投诉):
&&uart_01\uart.c&&.......\typedefs.h&&.......\main.c&&.......\Makefile&&.......\test&&.......\uart.h&&.......\project_includes.h&&uart_01
&近期下载过的用户:
&相关搜索:
&输入关键字,在本站238万海量源码库中尽情搜索:
&[] - linux下读写串口,包括参数的设置,以及如何进行读写
&[] - 串口通信工具含字符、文件发送和接收,流控功能
&[] - linux 串口初始化,波特率,数据位,停止位,数据流控制,
&[] - QNX 系统下的串口通讯控制程序,可以根据自己的想法进行修改
&[] - Linux下串口终端程序,ANSI C编写,一个简单的串口终端程序,可以在linux下连接嵌入式设备的串口终端,类似minicom和超级终端。
&[] - linux 下的超级终端 minicom ,早期版本的
redhat系列使用
&[] - 很好的,可供爱好者参考的
&[] - CSDN LINUX专家fudan_abc的《Linux内核修炼之道》精华版之方法论
&[] - 针对好多 Linux爱好者对内核很有兴趣却无从下口, 本文旨在介绍一种解读linux
内核源码的入门方法,而不是解说 linux复杂的内核机制。
&[] - LINUX下串口调试工具Linux串口设置及编程_Linux编程_Linux公社-Linux系统门户网站
你好,游客
Linux串口设置及编程
来源:Linux社区&
作者:Linux
用户常见的数据通信的基本方式可分为并行通信和串行通信。
并行通信是指利用多条数据传输线将一个资料的各位同时传送。特点是传输速度快,适用于短距离通信,但要求传输速度较高的应用场合。
串行通信是指利用一条传输线将资料一位位的顺序传送。特点是通信线路简单,利用简单的线缆就可以实现通信,减低成本,适用于远距离通信,但传输速度慢的应用场合。常用的串口有RS-232-C接口(全称是“数据终端设备(DTE)和数据通讯设备(DCE)之间串行二进制数据交换接口技术标准”)。
UART控制器:可以工作在Interrupt(中断)模式或者DMA(直接内存访问)模式。据有16字节的FIFO(先入先出寄存器),支持最高波特率可达到230.4Kbps。
UART操作:资料发送、资料接收、产生中断、产生波特率、Loopback模式、红外模式及自动流控制模式。
串口设置包括:波特率、起始位数量、数据位数量、停止位数量和流控协议。在此可以配置波特率为115200、起始位为1b、数据位8b、停止位1b和无流控制协议。
串口一、串口二对应设备名依次是“/dev/ttyS0”、“/dev/ttyS1”。
在Linux下对串口的读写可以使用简单的“read”、“write”函数完成,不同的是需要对串口的其它参数另作设置。
6.4.2 串口设置详情
串口设置主要是设置struct termios结构体成员值:
#include&termios.h&
Struct termio
&&&&&& unsigned short c_&&&&&&&&& /*输入模式标志*/
&&&&&& unsigned short c_&&&&&&&& /*输出模式标志*/
&&&&&& unsigned short c_&&&&&&&& /*控制模式标志*/
&&&&&& unsigned short c_&&&&&&&&&& /*本地模式标志*/
unsigned short c_&&&&&&&&&& /*line discipline*/
unsigned short c_cc[NCC];&& /*control characters*/
通过对c_cflag的赋值,可以设置波特率、字符大小、数据位、停止位、奇偶校验位和硬件流控等。
设置串口属性基本流程:
1.&&&&&& 保存原先串口配置
为了安全起见和以后调试程序方便,可先保存原先串口的配置,使用函数tcgetattr(fd,&oldtio)。该函数得到与fd指向对象的相关参数,并将它们保存于lodtio引用的termios结构中。该函数可以测试配置是否正确、该串口是否可用等。调试成功,函数返回0,失败,函数返回-1.
if(tcgetattr(fd,&oldtio)!=0)
&&&&&&& perror(“SetupSerial 1”);
&&&&&&& return -1;
2.&&&&&& 激活选项有CLOCAL和CREAD
CLOCAL和CREAD分别用于本地连接和接受使能,通过位掩码的方式激活这两个选项。
Newtio.c_cflag |= CLOCAL | CREAD;
3.&&&&&& 设置波特率
设置波特率的函数主要有cfsetispeed和cfsetospeed。
cfsetispeed(&newtio,B115200);
cfsetospeed(&newtio,B115200);
一般地用户需要将输入输出函数的波特率设置成一样的。这几个函数在成功时返回0,失败-1。
4.&&&&&& 设置字符大小
没有现成可用函数,需要位掩码。一般先去除数据位中的位掩码,再重新按要求设置。
options.c_cflag &= ~CSIZE; /*mask the character size bits*/
options.c_cflag |= CS8;
5.&&&&&& 设置奇偶校验位
先激活c_cflag中的校验位使能标志PARENB和是否要进行偶校验,同时还要激活c_iflag中的奇偶校验使能。如使能奇校验时,代码如下:
newtio.c_cflag |= PARENB;
newtio.c_cflag |=PARODD;
newtio.c_iflag |= (INPCK | ISTRIP);
而使能偶校验代码为:
newtio.c_iflag |= (INPCK | ISTRIP);
newtio.c_cflag |= PARENB;
newtio.c_cflag &= ~PAROOD;
6.&&&&&& 设置停止位
通过激活c_cflag中的CSTOPB而实现的。若停止位为1,则清除CSTOPB,若停止位为0,则激活CSTOPB。下面是停止位为1时的代码:
newtio.c_cflag &= ~CSTOPB;
7.&&&&&& 设置最少字符和等待时间
在对接收字符和等待时间没有特别要求的情况下,可以将其设置为0:
newtio.c_cc[VTIME] =0;
newtio.c_cc[VMIN]=0;
8.&&&&&& 处理要写入的引用对象
在串口重新设置之后,在之前要写入的引用对象要重新处理,可调用函数tcflush(fd,queue_selector)来处理要写入引用的对象。对于为传输的数据,或收到但未读取的数据,其处理方法取决于queue_selector的值。
Queue_selector可能取值:
TCIFLUSH:刷新收到的数据但不读
TCOFLUSH:刷新写入的数据但不传送
TCIOLFLUSH:同时刷新收到的数据但不读,并且刷新写入的数据但不传送
本例采用一:
tcflush(fd, TCIFLUSH)
9.&&&&&& 激活配置
用到函数tcsetattr:
函数原型:tcsetattr(fd,OPTION,&newtio);
这里的newtio就是termios类型的变量,OPTION可能的取值如下:
TCSANOW:改变的配置立即生效
TCSADRAIN:改变的配置在所有写入fd的输出都结束后生效
TCSAFLUSH:改变的配置自爱所有写入fd引用对象的输出都被结束后生效,所有已接受但为读入的输入都在改变发生前丢弃。
该函数调用成功返回0,失败-1.
if((tcsetattr(fd,TCSANOW,&newtio))!=0)
&&&&&& perror(“com set error”);
&&&&&& return -1;
/*串口配置的完整函数,为了函数的通用性,通常将常用的选项都在函数中列出,可大大方便以后用户的调试使用*/int set_opt(int fd,int nSpeed,int nBits,char nEvent,int nStop){struct termios newtio,/*保存测试现有串口参数设置,在这里如果串口号等出错,会有相关的出错信息*/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;&&&case 8:&&& newtio.c_cflag |=CS8;&&&}/*设置奇偶校验位*/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;case 'N'://无奇偶校验位&& newtio.c_cflag &= ~PARENB;&&}/*设置波特率*/switch(nSpeed){case 2400:&& cfsetispeed(&newtio,B2400);&& cfsetospeed(&newtio,B2400);&&case 4800:&& cfsetispeed(&newtio,B4800);&& cfsetospeed(&newtio,B4800);&&case 9600:&& cfsetispeed(&newtio,B9600);&& cfsetospeed(&newtio,B9600);&&case 115200:&& cfsetispeed(&newtio,B115200);&& cfsetospeed(&newtio,B115200);&&case 460800:&& cfsetispeed(&newtio,B460800);&& cfsetospeed(&newtio,B460800);&&default:&& cfsetispeed(&newtio,B9600);&& cfsetospeed(&newtio,B9600);&&}/*设置停止位*/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;}
相关资讯 & & &
& (05/28/:04)
& (05/27/:01)
& (05/27/:12)
& (05/27/:03)
& (05/27/:50)
& (05/27/:27)
图片资讯 & & &
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款如何设置linux启动时的串口波特率?
这是linux启动时串口打印的信息(MIPS开发板),波特率是57600,怎么样把波特率改为115200呢?
已有帐号?
无法登录?
社交帐号登录君,已阅读到文档的结尾了呢~~
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
Linux下串口编程所要知道的那些事
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口如何在S3C2440上linux操作系统下将串口的波特率提高以致921600
首先声明,CSDN中藏龙卧虎,说不定就出来个大牛,所以请各位大牛批评指正
& & & & 在说说我做的这个事情,其实听起来很简单,就是把串口的波特率提上去,硬件环境呢,就是采用飞凌的TE2440-II(比较古老了,大家勿喷)操作系统是linux2.6.28,大家都知道,正常情况下,linux下串口波特率最高到115200,因为我们特殊需要的原因,需要把波特率提高到至少460800,当然最理想的结果就是波特率达到921600,大的背景就是这个样子了。
然后先考究硬件,看看在硬件上到底能不能满足我们的要求,主控芯片S3C2440,在UART一章说在系统时钟下,波特率最高可达115200,然后注释中说如果Pclk达到60M,可以实现921600,我就按他说的,将主频提高,顺便将pclk提高到了60M,发现921600根本实现不了,230400波特率虽然能通,但是错误率很高,根本无法用,然后我又尝试着将Pclk提高到了70M,通过这种饮鸩止渴的方式,波特率可以提高到230400并且稳定传输,但是更高的波特率则无法实现,而Pclk不能无限提高,因为我们开发板还连接了触摸屏,在Pclk70M的情况下,触摸屏经常重启,说明这个方案不可行,所以就pass掉了,下面简单说一下我怎么更改的系统时钟Fclk,Hclk,Pclk。这三个时钟的关系以及计算方法我就不赘述了,我主要参考博客http://blog.csdn.net/dong_zhihong/article/details/8469269进行修改
1)首先找到bootloader中 INC文件夹下的Option.inc文件,打开以后,找到如下代码段,这段代码就是主频400M时对应的M,P和S值设置,需要更改主频的话更改其中相应的数值几个(后来我发现,其实这个地方不改也行,因为最终起作用的是第二步)
CLKDIV_VAL EQU5 ;1:4:8 M_MDIV EQU
127 ;127 M_PDIV EQU
2 ;2 [ CPU_SEL =
M_SDIV EQU
1 ; 2440A | M_SDIV EQU
0 ; 2440X ] ]
2)找到u2440mon.c,然后在main()函数中找到如下代码,修改case2中的mpll_val = (92&&12)|(1&&4)|(1);这一行(为啥修改这一行?因为在这个switch代码有个j=2),其中三个数分别代表M,P,S。这才是决定主频的关键。
switch(j) { case 0:
//240 key = 14; mpll_val = (112&&12)|(4&&4)|(1);
//320 key = 14; mpll_val = (72&&12)|(1&&4)|(1);
//400 key = 14; mpll_val = (92&&12)|(1&&4)|(1);
//420!!! key = 14; mpll_val = (97&&12)|(1&&4)|(1);
default: key = 14; mpll_val = (92&&12)|(1&&4)|(1);
3)然后再 2440lib.c文件中,找到&ChangeClockDivider()函数,这个函数是控制分频比的,代码如下,这两个一个控制h_div,一个控制p_div。其中case 18: hdivn=2;这一行控制H分频,具体怎么改可以参考手册。
switch(hdivn_val) { case 11: hdivn=0; case 12: hdivn=1; case 13: case 16: hdivn=3; case 14:& case 18: hdivn=2; }
switch(pdivn_val) { case 11: pdivn=0; case 12: pdivn=1; }
只需以上三步,就可以更改系统主频以及分频比,得到自己想要的Fclk和Pclk。
然后再说说我把上一个方案否定了以后,再仔细阅读芯片手册,发现串口的时钟源可以有三种方式获得:pclk,fclk/n,exclk,而且手册上说采用外部时钟的话,可以做到更高的波特率,但是这需要更改硬件,从指定那个引脚引入一个时钟,然后还要更改驱动程序,所以放弃了,所以只剩下一个路可以走,就是采用fclk/n的方式作为串口的时钟源,因为fclk频率很高,所以时钟源提高了,就可以把波特率提上来。然后就开始看linux内核源代码,因为串口的驱动早就集成到了linux内核之中,然后我就跳进了一个大坑。
其实串口本身的驱动并不复杂,如果裸机开发的话我感觉不难(强调一下,这个串口的裸机开发我没有做过,请做过的人不要喷我),因为串口被封装到了linux系统中,并且是层层封装,最终被封装成了tty的形式,所以我就从tty的驱动看起,抽丝剥茧,从里面寻找蛛丝马迹,
首先发现了s3c2440.c这个文件,通过调试得知,初始化的时候调用了其中的s3c2440_serial_init()函数,刚开始以为在这个文件中就这个函数有用,其实后来才知道,这个文件中的s3c2440_serial_getsource()和s3c2440_serial_setsource()在驱动中多次被调用。
然后考虑到,在上位机设置波特率的时候,调用的是系统函数cfsetispeed(),后经调试得知,这个函数调用了Samsung.c这个文件中的s3c24xx_serial_set_termios()这个函数,所有与串口相关的配置都与这个函数有关,因此锁定了方向,只要从这个函数中找到与波特率以及时钟源相关的语句,更改成我想要的即可,而这个函数又调用了很多子函数,但真正与波特率及时钟源相关的函数就是如下几句
/* * Ask the core to calculate the divisor for us. */
baud = uart_get_baud_rate(port, termios, old, 0, );
if (baud == 38400 && (port-&flags & UPF_SPD_MASK) == UPF_SPD_CUST) quot = port-&custom_ else quot = s3c24xx_serial_getclk(port, &clksrc, &clk, baud);
/* check to see if we need &to change clock source */
if (ourport-&clksrc != clksrc || ourport-&baudclk != clk) { s3c24xx_serial_setsource(port, clksrc); if (ourport-&baudclk != NULL && !IS_ERR(ourport-&baudclk)) { clk_disable(ourport-&baudclk); ourport-&baudclk &= NULL; }
clk_enable(clk);
ourport-&clksrc = ourport-&baudclk = }
其中,uart_get_baud_rate()函数用于计算出上位机程序到设置的波特率的值,经我调试得知,上位机波特率从都可以被准确的计算出来;所以这个函数跳过,然后看最后那个if语句,这个语句的作用是产看目前的时钟源是否与设置的时钟源相同,如果不相同,则按照设置的时钟源进行更改,这里面还涉及linux下的关于管理时钟的一个结构体clk结构体,参照博客http://blog.chinaunix.net/uid--id-3208153.html以及/view/13b4c686b9d528ea80c77904.html我找到了linux下的mach-smdk2440.c这个文件,这个文件中定义了串口所用的clk结构体,这也是linux系统启动时对串口的初始化配置结构体都在这,但是我更改过这个地方,让他初始化配置是首选fclk作为串口的时钟源,但是我发现这并没有效果,所以继续寻找中。
这样就剩下一个函数可以考虑了,s3c24xx_serial_getclk(),进入这个函数你会发现,这个函数是对串口时钟及波特率一个全面的配置,进入这个函数中,就有个结构体tmp_clksrc,这个结构体很关键,他的内容如下:
static struct s3c24xx_uart_clksrc tmp_clksrc = { .name = &pclk&, .min_baud
= 0, .max_baud
= 0, .divisor
从这个名字中就可以看出,它把串口的时钟源内定成为了pclk,这也是罪魁祸首,但是当我把name更改为fclk时,整个系统就无法启动了,包括前面说的更改mach-smdk2440.c中初始化配置,也是无法启动,后来在配置串口是做了一个判断,当波特率低于200000时,才有系统源配置不变,当波特率高于200000时,不在采用tmp_clksrc这个结构体,而是采用我自己定义的一个结构体,当然就是把name改成fclk,发现虽然只是能够更改 里面部分参数的时钟源,而正在的时钟源还是pclk,说明我的更改根本么有生效,由于这个linux调用太庞杂了,我就抱着试试看的态度,也是没有办法的办法,在配置完串口时钟的代码之后,添加了如下几行代码,直接更改S3C2440的寄存器,我知道这样做是很不“道德”的,而且很容易引起系统混乱,但是我只是这么试试,没想到还真的有用。
在 samsung.c文件中添加
if (baud &= 200000) { printk(&baud &= 200000 @-------------samsung.c\n&); __raw_writel(0x1fc5,S3C24XX_VA_UART0 + S3C2410_UCON); __raw_writel(0x0fc5,S3C24XX_VA_UART1 + S3C2410_UCON); __raw_writel(0x8fc5,S3C24XX_VA_UART2 + S3C2410_UCON); __raw_writel(32,S3C24XX_VA_UART0 + S3C2410_UCON+0x24);//保证控制台的波特率还是115200用于显示 __raw_writel(3,S3C24XX_VA_UART1 + S3C2410_UCON+0x24);//921600 //__raw_writel(3,S3C24XX_VA_UART1 + S3C2410_UCON+0x24); }
上面这段代码经我多次试验得到的,因为一开始用的系统主时钟fclk为400M,这样算出来UBRDIV1分频应该为3,但是这样的话错误率比较高,还是导致无法传输,至此我终于明白手册上为什么说pclk在60M 可以实现921600了,因为用60M时钟计算的话,分频UBRDIV1为3.069,最接近整数3,所以在这个错误率下可以实现921600的波特率传输,所以我将系统时钟fclk设置为420M,其中MDIV=97,PDIV=1,SDIV=1,而ucon0=0x1fc5,ucon1=0x0fc5,ucon2=0x8fc5,这样n=1+6=7,所以串口的时钟源为fclk/n=60M,可以得到精确的921600波特率,所以实现我刚开始的目标,其实要实现其他的波特率也可以,比如460800,计算后主时钟fclk(尽量算出的分频UBRDIV1最贴近整数),然后就可以实现了。
在这还有个小想法,提高串口波特率,还可以使用USB转串口,因为USB转串口可以实现921600,而linux中以及集成了USB转串口的驱动,只需要在调用串口的那个open函数中改为调用USB转串口的节点即可,当然,这个方案我没有试,因为我们就一个USB口,而且还被占用了,所以希望有需要的朋友可以试一下。
我想问一下,和s3c2440连接的环境是什么,是不是linux?我在linux下没有找到支持921600的串口工具,如果你知道的话麻烦告知。感谢!!
我想问一下,和s3c2440连接的环境是什么,是不是linux?我在linux下没有找到支持921600的串口工具,如果你知道的话麻烦告知。感谢!!
& 2012 - 2014 &
&All Rights Reserved. &
/*爱悠闲图+*/
var cpro_id = "u1888441";
/*爱悠闲底部960*75*/
var cpro_id = "u1888128";

我要回帖

更多关于 linux 获取串口波特率 的文章

 

随机推荐