UART实验

一、UART简介

UART

Universal Asynchronous Receiver Transmitter 即通用异步收发器,是一种通用的串行、异步通信总线,该总线有两条数据线,可以实现全双工的发送和接收,在嵌入式系统中常用于主机与辅助设备之间的通信

二、通信基础 - 并行和串行

在这里插入图片描述

并行通信

并行:多条数据线,

缺点:浪费很多资源,数据条数多,多条数据线之间传送数据时会有一些信号干扰
:char类型转换二进制八位二进制数,并行一次性可以用八根线传输这八位二进制

串行通信

串行:一条数据线,
:char类型转换二进制八位二进制数,串行只能一次传送一位二进制的数据

三、通信基础 - 单工和双工

单工通信

在这里插入图片描述

双工通信

在这里插入图片描述

四、通信基础 - 波特率

波特率

波特率用于描述UART通信时的通信速度,其单位为bps(bit per second)即每秒钟传送的bit的数量

五、UART帧格式

在这里插入图片描述
UART帧格式:
A->B串行发送数据时 如:0x55(01010101),
空闲位:空闲的时候必须是高电平 1
起始位:发送数据之前先发送一个低电平,用于空闲时期和发送数据之间的区分 0
数据位:5-8位(先发高位,后发低位)10101010
校验位:验证发送的数据(奇偶方式)
停止位:高电平
注意:一次最多发送一个字节(八位),发送多个字节必须发完一个字节之后停止,然后再发送下一个字节

  • 为什么串行发送数据最多八位呢?
  • 因为UART使用的是一种异步通信,发送和接收方使用的时钟不一样,发送的数据多了会产生误差,为了防止这种 误差,就把数据位控制在最多八位

六、UART硬件连接

硬件连接

在这里插入图片描述

七、UART控制器

UART控制器

一般情况下处理器中都会集成UART控制器 我们使用UART进行通信时候只需对其内部的相关寄存器进行设置即可
在这里插入图片描述

实验

UART实验: 通信的功能,比如,我的主控制器要和其他芯片或外围设备就会用到UART进行通信

通过UART寄存器实现4412电路板和电脑传输数据

第一步:

在电路板上面找到想要传输数据的串口的名字:CON7,在芯片电路板上找到相应的网络标号,控制着那个引脚

发送引脚网络标号:4 BUF_XuTXD2/UART_AUDIO_TXD
接收引脚网络标号:4 BUF_XuRXD2/UART_AUDIO_RXD

在这里插入图片描述

在这里插入图片描述
可以看到控制该引脚的寄存器是GPA1_0和GPA1_1这两个寄存器

第二步:

在这里插入图片描述
找到GPA1寄存器,通过GPA1CON设置这一组寄存器,GPA1CON[0]引脚设置 0x2 ,串口 2 的接收引脚, GPA1CON[1] 引脚设置成0x2,串口的发送引脚

第四步:

在4412芯片手册中查看UART第二组寄存器设置相关寄存器,并初始化相关寄存器

在这里插入图片描述
代码:


#include "exynos_4412.h"


/*串口控制器号初始化*/
void UART_Init(void)
{
	/*1.将GPA1_0和GPA1_1设置成UART2的接收和发送引脚 GPA1CON[7:0]*/
	GPA1.CON = GPA1.CON & (~(0xFF << 0)) | (0x22 << 0);

	/*2.设置UART2的帧格式 8位数据位 1位停止位 无校验 正常模式 ULCON2[6:0]*/
	UART2.ULCON2 = UART2.ULCON2 & (~(0x7F << 0)) | (0x3 << 0);

	/*3.设置UART2的接收和发送模式为轮询模式 UCON2[3:0]*/
	UART2.UCON2 = UART2.UCON2 & (~(0xF << 0)) | (0x5 << 0);

	/*4.设置UART2的波特率为115200 UBRDIV2/UFRACVAL2*/
	UART2.UBRDIV2 = 53;
	UART2.UFRACVAL2 = 4;
}

/*对外发送一个字节数据*/
void UART_Send_Byte(char Dat)
{
	/*等待发送寄存器为空,即上一个数据已经发送完成 UTRSTAT2[1]*/
	while(!(UART2.UTRSTAT2 & (1 << 1)));

	/*将要发送的数据写入发送寄存器 UTXH2*/
	UART2.UTXH2 = Dat;
}

/*接受外部发来的数据*/
char UART_Rec_Byte(void)
{
	char Dat = 0;

	/*判断接收寄存器是否接收到了数据 UTRSTAT2[0]*/
	if(UART2.UTRSTAT2 & 1) { 

		/*从接收寄存器读取接收到的数据 URXH2*/
		Dat = UART2.URXH2;
		return Dat;

	} else {
		return 0;
	}

}

void UART_Send_Str(char *pstr) {
	while(* pstr != '\0') {
		UART_Send_Byte(*pstr++);
	}
} 

int main()
{
	char RecDat = 0;

	UART_Init();

	while(1)
	{
		RecDat = UART_Rec_Byte();
		if(RecDat == 0) {
		}
		else {
			RecDat = RecDat + 1;
			UART_Send_Byte(RecDat);
		}

#if 0
		/*通过串口输出字符串*/
		UART_Send_Str("Hello world!");

		/* 这个printf不是Linux系统函数,是自己写的
		 * 两个的区别就在于输出重定向不同
		 * 1. 来源不一样:这个自己写的printf函数   Linux下是调用的C库函数
		 * 2. 输出定向不同:
		 *		Linux下终端输入' ls > out.txt' 将查到的目录下的信息输出到out.txt文件当中
		 *		‘ ls’ 是将输出定向到了显示器 是直接将信æ¯显示到屏幕上面去的
		 *		' ls > out.txt ' 是将输出定向磁盘中,该命令是将信息输出到文件当中
		 *
		 *		Linux下的printf:输出定向到了显卡,然后显示到屏幕上
		 *		而自己写的printf函数:输出定向到了UART寄存器,然后UART寄存器再将输出的信息发送到计算机当中解析
		 *
		 * */
		printf("Hello world!");
#endif

	}
	return 0;
}

例:

例:编程实现电脑远程控制LED状态
注:在终端上输入‘2’,LED2点亮,再次输入‘2’,LED2熄灭… …

#include "exynos_4412.h"


/*串口控制器号初始化*/
void UART_Init(void)
{
	/*1.将GPA1_0和GPA1_1设置成UART2的接收和发送引脚 GPA1CON[7:0]*/
	GPA1.CON = GPA1.CON & (~(0xFF << 0)) | (0x22 << 0);

	/*2.设置UART2的帧格式 8位数据位 1位停止位 无校验 正常模式 ULCON2[6:0]*/
	UART2.ULCON2 = UART2.ULCON2 & (~(0x7F << 0)) | (0x3 << 0);

	/*3.设置UART2的接收和发送模式为轮询模式 UCON2[3:0]*/
	UART2.UCON2 = UART2.UCON2 & (~(0xF << 0)) | (0x5 << 0);

	/*4.设置UART2的波特率为115200 UBRDIV2/UFRACVAL2*/
	UART2.UBRDIV2 = 53;
	UART2.UFRACVAL2 = 4;
}

/*对外发送一个字节数据*/
void UART_Send_Byte(char Dat)
{
	/*等待发送寄存器为空,即上一个数据已经发送完成 UTRSTAT2[1]*/
	while(!(UART2.UTRSTAT2 & (1 << 1)));

	/*将要发送的数据写入发送寄存器 UTXH2*/
	UART2.UTXH2 = Dat;
}

/*接受外部发来的数据*/
char UART_Rec_Byte(void)
{
	char Dat = 0;

	/*判断接收寄存器是否接收到了数据 UTRSTAT2[0]*/
	if(UART2.UTRSTAT2 & 1) { 

		/*从接收寄存器读取接收到的数据 URXH2*/
		Dat = UART2.URXH2;

		if (Dat == 2)
			return Dat;

		return Dat;

	} else {
		return 0;
	}

}

void UART_Send_Str(char *pstr) {
	while(* pstr != '\0') {
		UART_Send_Byte(*pstr++);
	}
} 

/* 通过设置GPX2_CON寄存器来将GPX2_7引脚设置成输出功能 LED2*/
void GPIO_CON() {
	GPX2.CON = GPX2.CON & (~(0xF << 28)) | (0x1 << 28);
}

/*通过GPX2_DAT引脚的设置 对LED2灯点亮和熄灭 */
void GPIO_DAT(char flag) {
	if (flag) {

		/* 熄灭LED2 */
		GPX2.DAT = GPX2.DAT & (~(1 << 7));
	} else {

		/* 点亮LED2 */
		GPX2.DAT = GPX2.DAT | (1 << 7);
	}

}

int main()
{
	char RecDat = 0;
	char flag = 0x1;
	UART_Init();

	while(1)
	{
		RecDat = UART_Rec_Byte();
		if(RecDat == '2') {
			flag = !flag;	
			GPIO_DAT(flag);
		}
		else {
			RecDat = RecDat + 1;
			UART_Send_Byte(RecDat);
		}
	}
	return 0;
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值