TQ2440开发板学习纪实--- 设置UART串口,输出Hello World!
Posted smstong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TQ2440开发板学习纪实--- 设置UART串口,输出Hello World!相关的知识,希望对你有一定的参考价值。
0 串口,UART,RS232,RS485傻傻分不清
0.1 串行通信与并行通信
串口名字表示采用的通信方式为串行而不是并行。那么串行与并行的区别是啥呢?很简单,串行就是同一时刻只能传输一个bit,而并行则可以同时传输多个bits。乍一看,仿佛并行通信速度更快,而且并行的信号线越多,传输数据快。CPU的总线就是使用并行通信的,总线带宽也从8一路飙升到了目前的64。然而这是在CPU的内部,对于设备间通信而言,并行通信意味着需要更多的信号连线,更复杂的控制逻辑,设备成本飙升。所以目前外围设备通信中,串行通信才是主流。如USB就是串行通信的代表,IDE的硬盘接口也被串行的SATA取代。
串口,顾名思义,采用的串行通信,一次发送一个bit位,干净利索。
0.2 异步通信和同步通信
UART是Universal Asynchronous Receiver&Transmitter的缩写,意思是统一异步通信。这里的关键点是异步通信。那就说明还存在另一种通信方式,叫做“同步通信”。这两者到底啥区别呢?
具体看参考这篇文章。总结来说:
- 同步通信要求接收端时钟频率和发送端时钟频率一致,发送端发送连续的比特流;异步通信时不要求接收端时钟和发送端时钟同步,发送端发送完一个字节后,可经过任意长的时间间隔再发送下一个字节。
- 同步通信效率高;异步通信效率较低。
- 同步通信较复杂,双方时钟的允许误差较小;异步通信简单,双方时钟可允许一定误差。
- 同步通信可用于点对多点;异步通信只适用于点对点。
0.3 RS232 RS485
串口通信有自己工业标准,目前常用的标准有两种:一是RS232,二是RS485。他们并不兼容,各自规定了自己的电气标准,通信规范。参考这篇文章。
简单来说:
由于RS232接口标准出现较早,难免有不足之处,主要有以下四点:
(1) 接口的信号电平值较高,易损坏接口电路的芯片,又因为与TTL 电平不兼容故需使用电平转换电路方能与TTL电路连接。
(2) 传输速率较低,在异步传输时,波特率为20Kbps。
(3) 接口使用一根信号线和一根信号返回线而构成共地的传输形式,容易产生共模干扰,所以抗噪声干扰性弱。
(4) 传输距离有限,最大传输距离标准值为50英尺,实际上也只能用在50米左右。
针对RS232接口的不足,于是就不断出现了一些新的接口标准,RS-485就是其中之一,它具有以下特点:
(1) RS-485的电气特性:逻辑“1”以两线间的电压差为+(2-6) V表示;逻辑“0”以两线间的电压差为-(2-6)V表示。接口信号电平比RS-232降低了,就不易损坏接口电路的芯片,且该电平与TTL电平兼容,可方便与TTL 电路连接。
(2) RS-485的数据最高传输速率为10Mbps 。
(3) RS-485接口是采用平衡驱动器和差分接收器的组合,抗共模干能力增强,即抗噪声干扰性好。
(4) RS-485接口的最大传输距离标准值为4000英尺,实际上可达3000米,另外RS-232接口在总线上只允许连接1个收发器,即单站能力。而RS-485接口在总线上是允许连接多达128个收发器。即具有多站能力,这样用户可以利用单一的RS-485接口方便地建立起设备网络。
1 S3C2440片内串口控制器初始化理论
S3C2440片内集成了UART控制器,支持3个独立的串口。TQ2440开发板对其中的0号串口引脚连接了电平转换电路把TTL电平转换成了RS232标准的电平,并搭配了标准的DB9接头。这样就可以直接和PC的DB9接口通过串口线连接调试了。
1.1 时钟来源与波特率
串口通信需要时钟来驱动,S3C2440提供了三种时钟来源供UART控制器使用,分别是PCLK,UEXTCLK,FCLK/n。具体使用哪个时钟源通过UCONn寄存器来设置。
波特率以时钟源的频率为基础,按照固定的公式计算得出。
UBRDIVn = (时钟源频率 / (波特率X16) -1
设置波特率的寄存器为UBRDIVn。
我们的实验中,选择PCLK作为时钟源,频率为50MHz,如果要想得到115200Hz的波特率,那么就需要设置
UBRDIVn = 50,000,000 / 115200*16 -1 = 26
1.2 数据长度、停止位、校验位
这是串口通信的三要素,收发两端必须一致才能正确通信。通过ULCONn寄存器来设置。详见数据手册。
1.3 轮询方式发送一个字节的流程
需要发送数据时
(1)把数据写入UTXHn寄存器,写完成导致:
* 发送完成状态清0;
* UART硬件自动把其中的数据串行化发送出去;
* 发送完毕UTRSTATn的发送完成状态置1。
(2)循环检测发送完毕状态位,等待发送完毕退出。
1.4 轮询方式接收数据流程
接收数据也很简单
当接收到数据时,会把数据反串行化后放入URXHn寄存器中,并设置URTSTATn寄存器来通知。
(1)循环检测UTRSTATn的接收完成状态,直到其为1
(2)读取URXHn寄存器,取出收到的字节,读完成会导致:
- UTRSTATn的接收完成状态清0
2 源码
uart.c
#include "2440addr.h"
void uart_init(void)
rGPHCON &= ~(3<<4 | 3<<6);
rGPHCON |= 2<<4 | 2<<6;
rGPHUP = 0x00;
rULCON0 &= ~(0x3); /* 8 bits */
rULCON0 |= 0x3;
rULCON0 &= ~(1<<2); /* 1 stopbit */
rULCON0 &= ~(1<<5); /* no parity */
rULCON0 &= ~(1<<6); /* normal (not infrared) */
rUCON0 &= ~(3); /* open send mode */
rUCON0 |= 0x1;
rUCON0 &= ~(3<<2); /* open recv mode */
rUCON0 |= 1<<2;
rUCON0 &= ~(3<<10); /* PCLK */
rUBRDIV0 = 26; /* baud rate = 115200 */
void uart_set_baud(int baud)
if (baud == 115200 )
rUBRDIV0 = 26;
else if(baud == 9600 )
rUBRDIV0 = 325;
else
void uart_set_stopbits(int n)
if (n < 1 || n > 2) return;
if (n == 1)
rULCON0 &= ~(1<<2);
else
rULCON0 |= 0x4;
/* 0 - no, 1 - odd, 2 - even */
void uart_set_parity(int how)
if (how < 0 || how >2) return;
rULCON0 &= ~(0x7 << 3);
if (how == 0)
rULCON0 |= (0 << 3);
else if (how == 1)
rULCON0 |= (4 << 3);
else
rULCON0 |= (5 << 3);
/* n=5,6,7,8 */
void uart_set_databits(int n)
if (n<5 || n>8) return;
rULCON0 &= ~3;
switch (n)
case 5:
rULCON0 |= 0;
break;
case 6:
rULCON0 |= 1;
break;
case 7:
rULCON0 |= 2;
break;
case 8:
rULCON0 |= 3;
break;
default:
break;
/* send a byte and wait until sent. */
void uart_send_byte(unsigned char c)
rUTXH0 = c;
while ( 0 == (rUTRSTAT0 & (1<<2)) );
unsigned char uart_recv_byte()
while ( 0 == (rUTRSTAT0 & 1)) ;
return rURXH0;
void uart_send_str(char* msg)
while (*msg)
uart_send_byte(*msg++);
3 简单的打印函数
这里我们原样模拟了标准C库的函数。
3.1 putchar
注意对C字符串换行符的处理,需要转换成终端换行符序列0x0A0D。
int putchar(int c)
if(c == '\\n')
uart_send_byte(0x0A);
uart_send_byte(0x0D);
else
uart_send_byte((unsigned char)c);
return 0;
3.2 puts
int puts(const char* str)
while(*str)
putchar(*str++);
return 0;
3.3 测试代码
io_init(0);
puts("Hello, World!\\n");
4 项目源码
标签v0.6。
以上是关于TQ2440开发板学习纪实--- 设置UART串口,输出Hello World!的主要内容,如果未能解决你的问题,请参考以下文章
TQ2440开发板学习纪实--- 设置时钟频率,让CPU运行的更快
TQ2440开发板学习纪实--- 启用IRQ中断,告别低效的轮询!
TQ2440开发板学习纪实--- 设置时钟频率,让CPU运行的更快