Part4:串口(UART)通信原理与硬件编程

0 写在前面
以下内容针对“S3C2440”这款ARM9芯片。虽然不同硬件的操作(寄存器)不同,但是UART原理是相通的。
因此,把重点放在UART的原理及如何理清硬件操作流程!换句话说,重在硬件操作
流程思维的培养,即演绎能力。即使后面讲到I2C、SPI等协议编程时,掌握这种演绎能力至关重要。

下面主要讲解UART的原理以及通过UART通信协议实现一个最基本的数据收发操作
1 UART的原理
说起串口,大家比较耳熟能详。而UART:Universal Asynchronous Receiver/Transmitter  通用异步收发器。
对于UART理解,抓住两个词:异步  收发
异步:表明通信双方可任意时刻收发数据
收发:表明彼此具有同时收发功能,而不受各自干扰。
再来看看硬件连接图:

UART硬件连接图

很简单,对不对?只需三根线,发送对应接收即可
这也是UART广泛使用的原因:简单、稳定

接着,通信双方如何收发数据呢?即UART的通信协议是怎样的?
回想串口通信前的参数设置:波特率、开始位、停止位、校验位、数据位等,这些跟UART通信协议息息相关。
即理解了它们,UART的通信就不难理解了。
波特率(Baud rate):约定彼此收发数据的频率,即每1bit所占时间的约定
开始位(Start bits):数据位传输前标识位,表明后面的是数据位
数据位(Data bits):指明发送/接收数据的位数
校验位(Parity):判断接收的数据是否正确,这在以前常使用,而现在基本不用检验位了(因为现在通信更稳定了,数据出错率很低)
停止位(Stop bits):数据位结束的标志,也是为下一次传输做好准备

如下图UART通信参数设置:(流控一般不用,默认关闭)

UART通信参数图解

补充一点:串口数据收发是串行的,即位流方式
OK,有了上面一些概念的理解,来看看收发时序图,捋一捋整个通信过程

UART时序图

补充一点:检验位:奇/偶校验。即数据位 + 检验位 中 1 的个数位奇数/偶数 。只具备接收数据检测,不具备矫正
分析一下:
发送:开始位 --> data[0] -->data[1] --> data[2].......-->data[7] --->[校验位] --> 停止位
接收:在每个bit中间采样并量化读取,即接收顺序为:data[0] --> data[1] --> ....-->data[7]

拓展一点:逻辑电平1/0的划分是相对的,即高低电平根据实际采样电压的范围量化为1或0
如TTL/CMOS门电路和RS232的高低电平划分相反,如下图

TTL-RS-232逻辑电平时序图

2 UART通信编程
接着,有了以上对UART原理的基本理解,那如何编程实现通信呢?
这里以S3C2440这款ARM9芯片为例,编写UART通信代码实现基本的数据收发。
提醒一点:重在理清UART编程时的操作流程,即掌握了套路,换成其它芯片也适用。
1)明确硬件收发流程
对于S3C2440这款芯片,UART方块图如下

UART方块图

2)理清编程步骤与项目组成
uart.c 函数内容
	1>串口初始化函数: void uart0_init(void)
		a) 设置引脚用于串口
		b) 设置波特率
		c) 设置数据格式(数据位、校验位等)
	2>发送数据函数 :int putchar(char c)
	3>接收数据函数 :int getchar(void) 
uart.h
	上面三个函数的声明
main.c : 程序主入口,进行串口初始化后,接收终端输入并回显
start.S: 设置堆栈后调用main函数
Makefile:管理项目的构建(编译+链接)

3)写代码
uart.c 文件内容如下:
/* uart0_init: 串口初始化*/
void uart0_init()
{
	/* 1.设置引脚用于串口 */
	/* GPH2,3 用于TxD0, RxD0*/
	GPHCON &= ~((3<<4) | (3<<6));  // 清空GPHCON中GPH2,3对应位
	GPHCON |= ((2<<4) | (2<<6));   // 设置GPH2,3分别为TxD0, RxD0
	GPHUP  &= ~((1<<2) | (1<<3));  // 默认拉高电平

	/* 2.设置波特率:115200 */
	/* UBRDIVn = (int)( UART clock / ( buad rate x 16) ) –1
	*  UART CLOCK = 50 MHz
	* UBRDIVn = (int)(50000000 / (115200 x 16 )) -1 = 26
	*/
	UCON0 = 0x00000005; /* 选择时钟源PCLK,中断/查询模式 */
	UBRDIV0 = 26;

	/* 3.设置数据格式 */
	ULCON0 = 0x00000003;	/* 8n1: 8个数据位,无校验位,1个停止位*/
}
/* putchar: 发送一个字节数据 */
int putchar(int c)
{
	while(!(UTRSTAT0 & (1<<2)));  // 等待发送移位器为空
	UTXH0 = (unsigned char)c;
}
/* getchar: 接收一个字节数据 */
int getchar(void)
{
	while(!(UTRSTAT0 & (1<<0)));  // 等待接收移位器满
	return URXH0;
}
/* puts: 发送一个字符串 */
int puts(const char* s)
{
	while(*s)
	{
		putchat(*s);
		s++;
	}
}
uart.h文件
#ifndef _UART_H
#define _UART_H

void uart0_init();
int putchar(int c);
int getchar(void);
int puts(const char*s);

#endif
main.c文件:
#include "s3c2440_soc.h"
#include "uart.h"

int main(void)
{
	unsigned char c;
	uart0_init();
	puts("Hello, world!\n\r");

	while(1)
	{
		c = getchar();
		if(c == '\r')
			putchar('\n');
		if(c == '\n')
			putchar('\r');
		putchar();
	}
	return 0;
}

Makefile文件

all:
	arm-linux-gcc -c -o led.o led.c
	arm-linux-gcc -c -o uart.o uart.c
	arm-linux-gcc -c -o main.o main.c
	arm-linux-ld -Ttext 0 start.o led.o uart.o main.o -o uart.elf
	arm-linux-objcopy -O binary -S uart.elf uart.bin
	arm-linux-objdump -D uart.elf > uart.dis
clean:
	rm *.bin *.o *.elf *.dis

start.S s3c2440_soc.h led.o 文件不是重点,略去

4)测试结果

UART简单收发操作
OK,运行结果没问题

总结一下:
UART的通信实现相对简单。看似只是操作几个寄存器,但要重点理解UART硬件收发数据的流程。
UART的通信原理不难理解。此外,在代码编写前,一定要养成事先理清操作步骤及项目文件组织。
简言之,要有意识锻炼编程思维,养成良好编程习惯。

参考教材:
韦东山老师的新一期视频《UART硬件介绍 + UART编程 》两节内容

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
UART(Universal Asynchronous Receiver/Transmitter)是一种通用异步收发器,可以将并行数据转换成串行数据,或将串行数据转换成并行数据。在串口通信中,UART通常用于将数据从微控制器或计算机发送到外设(如传感器、执行器等)或从外设接收数据并发送到微控制器或计算机。下面介绍UART串口通信实验原理。 UART串口通信的实验步骤如下: 1. 确定串口通信参数:通信波特率、数据位数、停止位数、校验位等。波特率是串口通信中的重要参数,表示数据传输的速率,通常选择常见的波特率(如9600、115200等)。 2. 连接串口通信的设备:将微控制器或计算机的串口与外设的串口连接,使用串口线连接即可。需要注意的是,串口线的连接方式必须与设备的串口通信参数相匹配。 3. 编写程序:使用编程语言(如C语言)编写程序,实现数据的发送和接收。在程序中,需要设置串口通信参数,并使用串口发送和接收函数进行数据的传输。发送数据时,将数据转换为串行数据,并通过UART发送到外设;接收数据时,通过UART接收串行数据,并将其转换为并行数据,保存在缓冲区中。 4. 调试程序:将程序下载到微控制器或计算机中,通过串口进行调试。在调试过程中,可以使用示波器或串口调试软件查看串口发送和接收的数据,检查程序是否正常运行。 需要注意的是,串口通信中,外设和微控制器或计算机的串口通信参数必须相同才能正常进行通信。同时,在数据的发送和接收过程中,需要注意数据的格式和传输顺序,以免出现数据丢失或错误的情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值