什么是UART
UART 通信的一些关键参数包括:
- 波特率(Baud Rate):数据传输的速率,通常以每秒位数(bps)来表示。常见的波特率有 9600、19200、38400、57600、115200 等。
- 数据位(Data Bits):每个字符包含的数据位数,通常为 7 位或 8 位。
- 停止位(Stop Bits):用于标记数据字符传输结束的位数,通常为 1 位或 2 位。
- 奇偶校验(Parity):一种用于检测数据传输错误的机制。它可以设置为无校验(None)、奇校验(Odd)、偶校验(Even)或标记校验(Mark)等。
什么是同步、异步
同步通信要求通信双方共用同一时钟信号,在总线上保持统一的时序和周期完成信息传输。
优点:可以实现高速率、大容量的数据传输,以及点对多点传输。
缺点:要求发送时钟和接收时钟保持严格同步,收发双方时钟允许的误差较小,同时硬件复杂。
而异步通信不需要时钟信号,而是在数据信号中加入开始位和停止位等一些同步信号,以便使接收端能够正确地将每一个字符接收下来,某些通信中还需要双方约定传输速率。
优点:没有时钟信号硬件简单,双方时钟可允许一定误差。
缺点:通信速率较低,只适用点对点传输。
数据的传输方向
根据数据传输方向,通信又可分为全双工、半双工和单工通信。全双工、半双工和单工通信的比较如下图所示
单工是指数据传输仅能沿一个方向,不能实现反方向传输,如校园广播。
半双工是指数据传输可以沿着两个方向,但是需要分时进行,如对讲机。
全双工是指数据可以同时进行双向传输,比如日常的打电话。
数据通信方式
串行通信的基本特征是数据逐位顺序依次传输,优点是传输线少、布线成本低、灵活度高等优点,一般用于近距离人机交互,特殊处理后也可以用于远距离,缺点就是传输速率低。
而并行通信是数据各位可以通过多条线同时传输,优点是传输速率高,缺点就是布线成本高,抗干扰能力差因而适用于短距离、高速率的通信。
通信速率
传信率:每秒钟传输的信息量,即每秒钟传输的二进制位数,单位为bit/s(即比特每秒),因而又称为比特率。
传码率:每秒钟传输的码元个数,单位为 Baud(即波特每秒),因而又称为波特率。
波特率被传输的是码元,码元是信号被调制后的概念,每个码元都可以表示一定 bit 的数据信息量。比如说,在 TTL 电平标准的通信中,用 0V 表示逻辑 0,5V 表示逻辑 1,这时候这个码元就可以表示两种状态。如果电平信号 0V、2V、4V 和 6V 分别表示二进制数 00、01、10、11,这时候每一个码元就可以表示四种状态。
由上述可以看出,码元携带一定的比特信息,所以比特率和波特率也是有一定的关系的。比特率和波特率的关系可以用以下式子表示:
其中 M 表示码元承载的信息量,也可以理解为 M 为码元的进制数。
例:波特率为 100 Baud,即每秒传输 100 个码元,如果码元采用十六进制编码(即 M=16,代入上述式子),那么这时候的比特率就是 400 bit/s。如果码元采用二进制编码(即 M=2,代入上述式子),那么这时候的比特率就是 100 bit/s。
1. 串口采用串行通信方式
因为收发数据收发时,一个时钟周期,只能收发一位数据
2. 波特率(bps:比特率,二进制/秒,比特/秒)
串口通信时,传输的速率,1s钟能够收发数据的位数
115200bps:表示1s钟可以收发 115200bit数据
波特率倒数:传输每位所需要的时间
UATR帧格式
在 UART中,传输模式为数据包形式。数据包由起始位、数据帧、奇偶校验位和停止位组成。
波形图:
1.空闲态: UART总线不在传输数据的时候,总线处于空闲状态,为高电平
2.起始信号 开始信号,串口通信的开始标志位
3.数据位 串口发送数据,先发低位,再发高位
4.奇/偶校验位:校验数据是否正确
奇校验:数据位和校验位1的个数为奇数 假设数据位0x55(0101 0101),校验位1 假设数据位0x51(0101 0001),校验位0
偶校验:数据位和校验位1的个数为偶数 假设数据位0x55(0101 0101),校验位0 假设数据位0x51(0101 0001),校验位1
5.停止信号:发送数据结束,回到高电平状态,校准时钟信号 一帧数据发送结束后,需要校准时钟信号,为什么需要校准时钟信号呢? 因为串口采用的是异步通信方式,双方都有自己独立的时钟源,虽然设置了双方的时钟源保持一致, 但是在发送数据时,每发送一帧数据时,都会产生误差,越往后,发送的数据,累计误差越大, 所以每发送一帧数据之后,需要校准时钟信
需要用到的寄存器
代码实现
#include<s3c2440.h>
void UART_init(void)
{
//配置GPH2 3的引脚功能为TXD,RXD
GPHCON &=~(0xf<<4);
GPHCON |=(0xa<<4);
// UART 线路控制寄存器
ULCON0 &=~(1<<6); //普通模式
ULCON0 &=~(0x7<<3); //无校验
ULCON0 &=~(1<<2); //1位停止位
ULCON0 |=(0x3<<0); //8位数据位
UCON0 &=~(0xf<<12); //UART 控制寄存器 清0
UCON0 |=(4<<12); //FCLK/10
UCON2 |=(1<<15); //使能FCLK/n
UCON0 |=(0x3<<10); //UART时钟选择为FCLK/n
UCON0 &=~(0xf<<0);
UCON0 |=(0x5<<0); //中断或轮询模式
UBRDIV0 =259; //UART 波特率分频寄存器 波特率9600
}
unsigned char UART_rev(void)
{
unsigned char info=0;
while(!(UTRSTAT0 & (1<<0))); // UART TX/RX 状态寄存器
info=URXH0; // UART 接收缓冲寄存器
return info;
}
void UART_send(unsigned char info)
{
while(!(UTRSTAT0&(1<<2)));
UTXH0=info; // UART 发送缓冲寄存器
}
没有缓冲区:一次发送的数据多时,会丢包
加入缓冲区后
#include<s3c2440.h>
void UART_init(void)
{
//配置GPH2 3的引脚功能为TXD,RXD
GPHCON &=~(0xf<<4);
GPHCON |=(0xa<<4);
// UART 线路控制寄存器
ULCON0 &=~(1<<6); //普通模式
ULCON0 &=~(0x7<<3); //无校验
ULCON0 &=~(1<<2); //1位停止位
ULCON0 |=(0x3<<0); //8位数据位
UCON0 &=~(0xf<<12); //UART 控制寄存器 清0
UCON0 |=(4<<12); //FCLK/10
UCON2 |=(1<<15); //使能FCLK/n
UCON0 |=(0x3<<10); //UART时钟选择为FCLK/n
UCON0 &=~(0xf<<0);
UCON0 |=(0x5<<0); //中断或轮询模式
UBRDIV0 =259; //UART 波特率分频寄存器 波特率9600
UFCON0 |=(1<<0); //使能FIFO
UFCON0 |=(1<<1); //复位RX FIFO
}
unsigned char UART_send(unsigned char*info,unsigned char len)
{
int i=0;
for(i=0;i<len;i++)
{
while(!UTRSTAT0 &(1<<2));
UTXH0=info[i];
}
return i;
}
unsigned char UART_recv(unsigned char * info, unsigned char len)
{
int i=0;
unsigned char count= UFSTAT0 &0x3f; //前5位为数据量,保留前5位
unsigned char num = (count < len) ? count : len;
for(i = 0; i < num; i++)
{
info[i] = URXH0;
}
return num;
}
加入中断、超时中断功能