历史上的今天
返回首页

历史上的今天

今天是:2025年03月25日(星期二)

正在发生

2020年03月25日 | tiny4412开发板的串口介绍与操作

2020-03-25 来源:eefocus

UART原理说明:


通用异步收发器简称UART,即"Universal Asynchronous Receiver Transmitter",它用来传输串行数据:发送数据时,CPU将并行数据写入UART,UART按照一定的格式在一根电线上串行发出;接收数据时,UART检测另一根电线上的信号,将串行收集放在缓冲区中,CPU即可读取UART获得这些数据。UART之间以全双工方式传输数据,最精简的连线方法只有三根电线:TxD用于发送数据,RxD用于接收数据,Gnd用于给双方提供参考电平,连线如图1所示:

图1. UART连线图


UART使用标准的TTL/CMOS逻辑电平(0~5V、0~3.3V、0~2.5V或0~1.8V四种)来表示数据,高电平表示1,低电平表示0。为了增强数据的抗干扰能力、提高传输长度,通常将TTL/CMOS逻辑电平转换为RS-232逻辑电平,3~12V表示0,-3~-12V表示1。


TxD、RxD数据线以"位"为最小单位传输数据。帧(frame)由具有完整意义的、不可分割的若干位组成,它包含开始位、数据位、较验位(需要的话)和停止位。发送数据之前,UART之间要约定好数据的传输速率(即每位所占据的时间,其倒数称为波特率)、数据的传输格式(即有多少个数据位、是否使用较验位、是奇较验还是偶较验、有多少个停止位)。


数据传输流程如下:


(1)平时数据线处于"空闭"状态(1状态)。

(2)当要发送数据时,UART改变TxD数据线的状态(变为0状态)并维持1位的时间──这样接收方检测到开始位后,再等待1.5位的时间就开始一位一位地检测数据线的状态得到所传输的数据。

(3)UART一帧中可以有5、6、7或8位的数据,发送方一位一位地改变数据线的状态将它们发送出去,首先发送最低位(LSB)。

(4)如果使用较验功能,UART在发送完数据位后,还要发送1个较验位。有两种较验方法:奇较验、偶较验──数据位连同较验位中,"1"的数目等于奇数或偶数。

(5)最后,发送停止位,数据线恢复到"空闭"状态(1状态)。停止位的长度有3种:1位、1.5位、2位。


图2演示了UART使用7个数据位、偶较验、2个停止位的格式传输字符"A"(二进制值为0b1000001)时,TTL/CMOS逻辑电平对应的波形。

图2. TTL/CMOS逻辑电平下,传输"A"时的波形


UART还有其他功能,比如流量控制等,想深入了解的读者请自行查阅相关资料。


Exynos4412的UART特性:


Exynos4412中UART,有4个独立的通道,每个通道都可以工作于中断模式或DMA模式,即UART可以发出中断或DMA请求以便在UART、CPU间传输数据。UART由波特率发生器、发送器、接收器和控制逻辑组成。


使用系统时钟时,Exynos4412的UART波特率可以达到4Mbps。波特率可以通过编程进行控制。


Exynos4412 UART的通道0有256字节的发送FIFO和256字节的接收FIFO;通道1、4有64字节的发送FIFO和64字节的接收FIFO;通道2、3有16字节的发送FIFO和16字节的接收FIFO。发送数据时,CPU先将数据写入发送FIFO中,然后UART会自动将FIFO中的数据复制到"发送移位器"(Transmit Shifter)中,发送移位器将数据一位一位地发送到TxDn数据线上(根据设定的格式,插入开始位、较验位和停止位)。接收数据时,"接收移位器"(Receive Shifter)将RxDn数据线上的数据一位一位接收进来,然后复制到接收FIFO中,CPU即可从中读取数据。


Exynos4412 UART的每个通道支持的停止位有1位、2位,数据位有5、6、7或8位,支持较验功能,另外还有红外发送/接收功能。Exynos4412 UART结构如图3所示:

图3. Exynos4412 UART结构图


Exynos4412 UART的使用:

图4. 设置Serial连接图


如图4所示,我们在使用UART与PC通信的时候,PC端需要设置波特率、数据位、是否使用校验位、有多少个停止位、是否使用流控等。UART是工作在异步模式下,接收器自身实现帧的同步,因此要实现通信,Exynos4412的UART也要作相同的设置,另外还要选择所涉及管脚为UART功能、选择UART通道的工作模式为中断模式或DMA模式。设置好之后,往某个寄存器写入数据即可发送,读取某个寄存器即可得到接收到的数据。在中断模式(查询模式)下,我们一般通过查询状态寄存器或设置中断来获知数据是否已经发送完成、是否已经接收到数据。下面详细讲解上述设置过程。


1.将所涉及的UART通道管脚设为UART功能


比如UART通道0中,GPA0_0、GPA0_1分别用作RXD0、TXD0,要使用UART通道0时,先设置GPA0CON寄存器将GPA0_0、GPA0_1引脚的功能设为RXD0、TXD0。


2.选择UART的时钟源

图5. UART时钟


Exynos4412 UART的时钟源有八种选择:XXTI、XusbXTI、SCLK_HDMI24M、SCLK_USBPHY0、SCLK_HDMIPHY、SCLKMPLL_USER_T、SCLKEPLL、SCLKVPLL,由CLK_SRC_PERIL0寄存器控制。


选择好时钟源后,还可以通过DIVUART0~4设置分频系数,由CLK_DIV_PERIL0寄存器控制。从分频器得到的时钟被称为SCLK_UART。


SCLK_UART经过图5中的"UCLK Generator"后,得到UCLK,它的频率就是UART的波特率。"UCLK Generator"通过这2个寄存器来设置:UBRDEVn、UFRACVALn(在下面描述)。


表1 CLK_SRC_PERIL0的寄存器格式

由于在iROM的代码中设置了相关时钟的寄存器,我们在试验的使用选择XusbXTI作为时钟源。


表2 CLK_DIV_PERIL0的寄存器格式

3.设置波特率:UBRDIVn寄存器(UART BAUD RATE DIVISOR)、UFRACVALn寄存器


根据给定的波特率、所选择的时钟源的频率,可以通过以下公式计算UBRDIVn 寄存器(n为0~4,对应5个UART通道)的值:


UBRDIVn = (int)(UART clock/(buad rate x 16)) – 1

上式计算出来的UBRDIVn寄存器值不一定是整数,UBRDIVn寄存器取其整数部分,小数部分由UFRACVALn寄存器设置,UFRACVALn寄存器的引入,使产生的波特率更加精确。


例如,当UART clock为100MHz时,要求波特率为115200bps,则:

100000000/(115200 x 16) – 1 = 54.25 – 1 = 53.25

UBRDIVn = 整数部分 = 53

UFRACVALn/16 = 小数部分 = 0.25

UFRACVALn = 4

4.设置传输格式:ULCONn寄存器(UART LINE CONTROL)


ULCONn寄存器(n为0~4)格式如表3所示。


表3 ULCONn寄存器格式

我们这里设置为,普通模式、无校验位、一帧中有一个停止位和8位的数据位。


UART通道被设为红外模式时,其串行数据的波形与正常模式稍有不同,有兴趣的读者请自行阅读数据手册。


5.设置UART工作模式:UCONn寄存器(UART CONTROL)


Exynos4412的UCONn寄存器格式,如表4所示。


表4 UCONn寄存器格式

我们写程序时使用中断或查询方式。


6.UFCONn寄存器(UART FIFO CONTROL)、UFSTATn寄存器(UART FIFO STATUS)


UFCONn寄存器用于设置是否使用FIFO,设置各FIFO的触发阀值,即发送FIFO中有多少个数据时产生中断、接收FIFO中有多少个数据时产生中断。并可以通过设置UFCONn寄存器来复位各个FIFO。


读取UFSTATn寄存器可以知道各个FIFO是否已经满、其中有多少个数据。

不使用FIFO时,可以认为FIFO的深度为1,使用FIFO时Exynos4412的FIFO深度最高可达到256。这两类寄存器各位的含义请读者查阅数据手册。


7.UMCONn寄存器(UART MODEM CONTROL)、UMSTATn寄存器(UART MODEM STATUS)


这两类寄存器用于流量控制,这里不介绍。


8.UTRSTATn寄存器(UART TX/RX STATUS)


UTRSTATn寄存器用来表明数据是否已经发送完毕、是否已经接收到数据,格式如下表4所示。下面说的"缓冲区",其实就是图3中的FIFO,不使用FIFO功能时可以认为其深度为1。


表5 UTRSTATn寄存器格式

9.UERSTATn寄存器(UART ERROR STATUS)


用来表示各种错误是否发生,位[0]至位[3]为1时分别表示溢出错误、较验错误、帧错误、检测到"break"信号。读取这个寄存器时,它会自动清0。


需要注意的是,接收数据时如果使用FIFO,则UART内部会使用一个"错误 FIFO"来表明接收FIFO中哪个数据在接收过程中发生了错误。CPU只有在读出这个错误的数据时,才会觉察到发生了错误。要想清除"错误 FIFO",则必须读出错误的数据,并读出UERSTATn寄存器。


10.UTXHn寄存器(UART TRANSMIT BUFFER REGISTER)


CPU将数据写入这个寄存器,UART即会将它保存到缓冲区中,并自动发送出去。


11.URXHn寄存器(UART RECEIVE BUFFER REGISTER)


当UART接收到数据时,CPU读取这个寄存器,即可获得数据。


示例程序详解,主要涉及到三个文件,start.S文件主要设置栈等基本的功能;uart.c文件主要就是初始化串口和定义操作串口用到的函数。main.c文件主要做相关的操作。


start.S文件内容如下:


.text

.global _start

_start:

ldr sp, =0x02027400 //调用C函数之前必须设置栈,栈用于保存运行环境,给局部变量分配空间;

//参考ROM手册P14,我们把栈指向BL2的最上方;

//即:0x02020000(iROM基地址)+5K(iROM代码用)+8K(BL1用)+16K(BL2用)

bl main //跳转到C函数中执行

 

halt: //死循环

b halt

uart.c文件的内容如下,已经在里面做了详细的注释,这里不再做详细的介绍。


//串口0使用的引脚

#define GPA0CON (*(volatile unsigned int *)0x11400000)

//选择时钟源

#define CLK_SRC_PERIL0 (*(volatile unsigned int *)0x1003C250)

//设置uart0的分频系数

#define CLK_DIV_PERIL0 (*(volatile unsigned int *)0x1003C550)

#define UBRDIV0 (*(volatile unsigned int *)0x13800028)

#define UFRACVAL0 (*(volatile unsigned int *)0x1380002C)

#define UFCON0 (*(volatile unsigned int *)0x13800008)

#define ULCON0 (*(volatile unsigned int *)0x13800000)

#define UCON0 (*(volatile unsigned int *)0x13800004)

#define UTXH0 (*(volatile unsigned int *)0x13800020)

#define URXH0 (*(volatile unsigned int *)0x13800024)

#define UTRSTAT0 (*(volatile unsigned int *)0x13800010)

 

void uart0_init()

{

//配置GPA0CON的引脚为串口功能;

GPA0CON = 0x22222222;

//设置串口0使用的时钟源;使用XusbXTI作为时钟源

CLK_SRC_PERIL0 &= ~(0xF); //低四位清零

CLK_SRC_PERIL0 |= (0x1); //低四位设置为0b0001  MOUTUART0 = 24MHz

//uart0的时钟源为24MHz;设置分频系数

CLK_DIV_PERIL0 &= ~(0xF); //低四位清零

CLK_DIV_PERIL0 |= (0x2); //SCLK_UART0 = MOUTUART0/(UART0_RATIO + 1)

//MOUTUART0=24,UART0_RATIO=2;所以,SCLK_UART0=8MHz

//程序走到这里SCLK_UART0(8MHz)时钟已经获得了。

/*

* 使能FIFO;Rx FIFO:64 bytes  Tx FIFO:32 bytes

*/

UFCON0 =0x111;

/* 设置数据格式: 8n1, 即8个数据位,没有较验位,1个停止位 */

ULCON0 = 0x3;

/* 工作于中断/查询模式

* 另一种是DMA模式,本章不使用

*/

UCON0 = 0x5;

//SCLK_UART0=8MHz;设置UBRDIV0和UFRACVAL0寄存器;波特率是115200

UBRDIV0 = 0x3;

UFRACVAL0 = 0x5;

}

 

//从串口获得一个字符

char getc(void)

{

char c;

/* 查询状态寄存器,直到有有效数据 */

while (!(UTRSTAT0 & (1<<0)));

c = URXH0; /* 读取接收寄存器的值 */

return c;

}

 

//输出一个字符

void putc(char c)

{

/* 查询状态寄存器,直到发送缓存为空 */

while (!(UTRSTAT0 & (1<<2)));

UTXH0 = c; /* 写入发送寄存器 */

return;

}

 

//打印字符串

void puts(char *s)

{

while (*s)

{

putc(*s);

s++;

}

}

 

//将数字按照十六进制格式打印

void puthex(unsigned long val)

{

/* val = 0x1234ABCD */

unsigned char c;

int i = 0;

putc('0');

putc('x');

for (i = 0; i < 8; i++)

{

c = (val >> ((7-i)*4)) & 0xf;

if ((c >= 0) && (c <= 9))

{

c = '0' + c;

}

else if ((c >= 0xA) && (c <= 0xF))

{

c = 'A' + (c -  0xA);

}

putc(c);

}

putc('n');

putc('r');

}

main.c文件主要做使用试验使用,内容如下:


int main()

{

char c;

uart0_init();

puts("Test uart by Haitao Cai!nr");

puthex(100); //打印十六进制数

while(1)

{

c = getc(); //从串口获得一个字符

if(c == 'r')

{

puts("Test over!");

break;

}

putc(c);

putc(':');

putc(c+1); //将字符加1输出

putc('n');

putc('r');

}

return 0;

}

将文件上传,编译并烧写SD卡;开机试验过程如下:

本文完毕!

推荐阅读

史海拾趣

Hexawave公司的发展小趣事

当涉及到采用算术逻辑单元(ALU, Arithmetic Logic Unit)组成的二进制加减电路时,网友们可能会提出多种问题,这里列举一些常见问题及其解答:

1. ALU 如何实现二进制加法?

回答
在二进制加法中,ALU 使用全加器(Full Adder)或一系列的全加器(对于多位二进制数)来实现。每个全加器接受三个输入:两个加数位(A 和 B)以及一个来自低位的进位(Cin)。它产生两个输出:一个和位(Sum)和一个向高位的进位(Cout)。通过级联多个全加器,可以完成多位二进制数的加法。

2. ALU 如何实现二进制减法?

回答
二进制减法可以通过加法来实现,利用“补码”的概念。具体地,将减数取反加一(即求其二进制补码),然后将该补码与被减数相加。结果的正负由最高位(符号位)决定,其余位表示数值大小。ALU 内部可以包含专门的电路来处理这种补码加法,从而间接实现减法。

3. ALU 如何处理进位和借位?

回答
在加法中,进位(Carry)是从低位向高位传递的,每个全加器都会输出一个进位信号给下一个高位的全加器。在减法(通过补码加法实现)中,由于使用了加法器,进位的概念仍然适用,但在某些情况下,它可能被视为“借位”的相反操作,尤其是在直观理解减法过程时。不过,从电路设计的角度来看,ALU 内部处理的是加法操作,包括进位。

4. ALU 如何支持更复杂的算术运算,如乘法和除法?

回答
ALU 通常支持基本的算术运算(加、减)和逻辑运算。对于乘法和除法,ALU 可能不支持直接计算,或者仅支持部分乘法和除法的简化版本(如移位操作,可以视为乘以2的幂或除以2的幂的简化形式)。复杂的乘法和除法运算通常需要额外的硬件单元(如乘法器和除法器)来执行,这些单元可能作为ALU的补充或与之并行工作。

5. ALU 的设计如何影响计算机的性能?

回答
ALU 的设计对计算机的性能有直接影响。更快的ALU 能够更快地完成算术和逻辑运算,从而提高整个计算机的处理速度。此外,ALU 的指令集和设计的灵活性也会影响其能够执行的操作种类和效率。现代CPU中的ALU通常非常高效且灵活,能够执行多种复杂的算术和逻辑操作,以满足现代应用程序的需求。

Cadeka公司的发展小趣事

近年来,随着电子行业的快速变革和新兴技术的不断涌现,Cadeka公司面临着前所未有的挑战。为了应对这些变革,公司及时调整发展战略,加大在新兴技术领域的投入。同时,公司还积极与合作伙伴开展合作,共同探索新的商业模式和市场机会。通过这些努力,Cadeka公司成功应对了行业变革带来的挑战,继续保持了在电子行业中的领先地位。

这些故事虽然是虚构的,但它们反映了电子行业发展的一些普遍规律和趋势。希望这些故事能够为您提供一些启发和参考。

CBM_America_Corporation公司的发展小趣事

CBM_America_Corporation在电子行业的初期,专注于研发具有创新性的半导体技术。通过不懈的努力,公司成功开发出一种高效能、低能耗的芯片,受到了市场的广泛欢迎。这一技术突破为公司带来了大量的订单,也吸引了众多投资者的关注。随着资金的注入,CBM开始扩大生产规模,并进军国际市场,逐步成为了电子行业的领军企业。

Crosspoint Solutions公司的发展小趣事

随着技术的不断更新换代,人才成为电子企业竞争的核心要素。Crosspoint Solutions公司高度重视人才培养和引进工作,通过校园招聘、社会招聘等多种渠道吸引优秀人才加入。同时,公司还建立了完善的培训体系,不断提升员工的技能水平和创新能力。这些优秀的人才为公司的发展提供了强有力的支撑。

Firadec公司的发展小趣事

背景:随着电子行业竞争的日益激烈,成本控制成为了企业生存发展的关键。Firadec公司意识到优化供应链的重要性。

发展:公司开始与上游供应商建立长期稳定的合作关系,通过集中采购、共享库存等方式降低采购成本。同时,Firadec还加强了对生产过程的精细化管理,提高了生产效率和产品质量。

影响:供应链的优化和成本的有效控制,使Firadec公司在激烈的市场竞争中保持了较强的盈利能力。这也为公司后续的研发和市场拓展提供了有力的支持。

Burr-Brown公司的发展小趣事

Burr-Brown在音频领域取得了显著的成就。1957年,公司推出的Model 130成为世界上第一个固态运算放大器(op amp),这一技术在现代高级音频系统中仍占据核心地位。1982年,公司发布的16位单片数模转换器(DAC)更是彻底改变了音乐的播放和发行方式,使得音乐可以以高保真度进行复制,并方便地随身携带。Burr-Brown的技术成为优质音频的代名词,赢得了广泛的行业认可。

问答坊 | AI 解惑

借人气问问如何连接两个GPRS模块?

最近我使用IWOW的TR800来做一个无线数传的项目,我在想移动既然分配给模块的ip是内网ip,那是否意味着两个模块连上GPRS网络之后,他们都是获得同一内网里的ip,就像连接到同一路由器里面的两台机器一样? 另外共享一下我觉得不错的技术QQ群 群5 ...…

查看全部问答>

请问现在做一个LED驱动(大小功率)安规费用

1,请问现在做一个LED驱动(大小功率)安规费用 第一次做个安规完,如果没过,对方提建议,也要收相同费用吗? 有没有过了才收费的; 2,过安规应该包含有电磁兼容项目吧…

查看全部问答>

请问:ATM64中PB4端口第二功能如何开启??

请问: ATM64中的PB4脚的第二功能是如何开启的? 是不是把T/C0控制寄存器TCCR0中的CS02、CS01、CS00位置0就可以了???(TCCR0=0X00) 大家一定要指点一下啊!!!!…

查看全部问答>

小弟新学TMS320LF2407,请教一下加载程序的问题

原来用的6416的片子,现在用的2407,想问下怎么能一上电就让dsp芯片运行我的程序?小弟新手希望各位大侠教的详细点,有资料发我邮箱也可以hljlishen0517@gmail.com   多谢各位了…

查看全部问答>

vxworks下U盘的插拔问题

小弟最近遇到个问题: 在vxworks中包含usb mass storage的相关组件,启动目标板后,插入U盘,读写操作都正确,但是拔掉后,再插入,就报告dosFsDevCreate失败,查看错误号,说是设备已存在,使用 hdr = iosDevFind(\"/usb/bd\", 0); iosDevDelet ...…

查看全部问答>

MS  SmartPhone 2003  SDK Sample GetDeviceID 严重错误

{         BOOL fRes;     DWORD dwBytesRetur…

查看全部问答>

74系列芯片功能大全

74系列芯片功能大全 这里是常用74系列芯片功能大全很有收藏价值   7400 TTL 2输入端四与非门7401 TTL 集电极开路2输入端四与非门7402 TTL 2输入端四或非门7403 TTL 集电极开路2输入端四与非门7404 TTL 六反相器7405 TTL 集电极开路六反相 ...…

查看全部问答>

帮忙看看这个 三相三线制缺相保护电路

这个电路在很多网站都有   对它解释也是相同 “这是一种用于三相三线制电源缺相保护电路,A、B、C缺任何一相,光耦器输出电平低于比较器的反相输入端的基准电压,比较器输出低电平,封锁PWM驱动信号,关闭电源。比较器输入极性稍加变动 ...…

查看全部问答>

TPS5430DDAR芯片过回流焊后无法正常工作,重新焊接上正常工作

如题,TPS5430DDAR芯片经过热风回流焊,峰值温度230℃左右,测试电源无法工作,将两片TPS5430DDAR用烙铁取下,交换下重新焊接上去,电源正常工作,请问这是什么原因??????…

查看全部问答>

mega128上SD卡的FAT文件系统

网上查了好多关于FAT文件系统的资料和库文件,尝试下都没成功。关于FAT文件系统一点头绪都没有啊,有没有做过这方面研究的大大教一下~…

查看全部问答>