UART实验

news2024/11/15 17:48:19

目录

一、UART

1.1简介

1.2并行通信和串行通信

1.3单工和双工 

1.4波特率

1.5UART帧格式

1.6UART硬件连接

1.7UART控制器

二、Exynos4412的UART控制器

三、UART寄存器 

四、UART编程

五、输入输出重定向

六、使用串口控制LED


一、UART

1.1简介

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

1.2并行通信和串行通信

1.3单工和双工 

1.4波特率

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

1.5UART帧格式

串口一般为奇偶校验

奇偶校验(Parity Check)是一种校验代码传输正确性的方法。根据被传输的一组二进制代码的数位中“1”的个数是奇数或偶数来进行校验。采用奇数的称为奇校验,反之,称为偶校验。采用何种校验是事先规定好的。通常专门设置一个奇偶校验位,用它使这组代码中“1”的个数为奇数或偶数。若用奇校验,则当接收端收到这组代码时,校验“1”的个数是否为奇数,从而确定传输代码的正确性。

奇偶校验_百度百科

为了避免累计误差的出现一次最多发一个字节,异步通信的弊端。

1.6UART硬件连接

1.7UART控制器

一般情况下处理器中都会集成UART控制器,我们使用UART进行通信时候只需对其内部的相

关寄存器进行设置即可。

二、Exynos4412的UART控制器

由于串口信号太弱了,所以加上SP3232EEA芯片来放大这个信号

 

设置引脚功能本质上就是让引脚连接对应的控制器

 这个串口输入输出控制器都有个缓冲区,FIFO形式的发送时只需要将发送内容写入缓冲区就会自动发送,接收时也只需要读取缓冲区内容即可。每个串口缓冲区不一样大,本次使用的是ch2,

串口通信最大频率是4M

串口的波特率是可以编程的

支持红外传输,(无线)

1位或者两位停止位

数据位可以是5-8位,还可以有校验位

 波特率发生器、发送器、接收器、控制单元

 

 

 SOC的频率是1000M,UART是100M,数据通过引脚->移位器->FIFO,FIFO->移位器->引脚实现

发送和接收

CLOCK Source是100M

三、UART寄存器 

tar xvf 出来一个新工程

 ULCON2 = 0000011

回环模式将发送接收短接

 UCON2 = 0101

中断模式:有消息通知CPU

轮询模式:CPU一直在等消息

DMA:自动传送给内存,解放CPU

 AFC:自动流控制,这次实验就是普通的收发暂时不需要

只能读,【1】表示发送的队列是空的【0】表示接收的队列有数据

 波特率的计算方法

 如果还有小数直接四舍五入就行,虽然有一丢误差,但是因为他会重新算所以没到一位就不会有问题。

四、UART编程

#include "exynos_4412.h"

int main()
{
	GPA1.CON = GPA1.CON & (~(0xFF)) | (0x22);
	UART2.ULCON2 = UART2.ULCON2 & (~(0x7F)) | (0x3);
	UART2.UCON2 = UART2.UCON2 & (~(0xF)) | (0x5);
	UART2.UBRDIV2 = 53;
	UART2.UFRACVAL2 = 4;
	while(1)
	{
		UART2.UTXH2 = 'A';
	} 
	return 0;
}

 

#include "exynos_4412.h"

int main()
{
	GPA1.CON = GPA1.CON & (~(0xFF)) | (0x22);
	UART2.ULCON2 = UART2.ULCON2 & (~(0x7F)) | (0x3);
	UART2.UCON2 = UART2.UCON2 & (~(0xF)) | (0x5);
	UART2.UBRDIV2 = 53;
	UART2.UFRACVAL2 = 4;
	while(1)
	{
		UART2.UTXH2 = 'A';
		UART2.UTXH2 = 'B';
		UART2.UTXH2 = 'C';
		UART2.UTXH2 = 'D';
	} 
	return 0;
}

 结果和想的不一样,因为CPU的执行速度是1GHz,而串口速度是115200,CPU速度太快了,我们前一个还没发送完CPU已经送进来好几个了。

#include "exynos_4412.h"

int main()
{
	GPA1.CON = GPA1.CON & (~(0xFF)) | (0x22);
	UART2.ULCON2 = UART2.ULCON2 & (~(0x7F)) | (0x3);
	UART2.UCON2 = UART2.UCON2 & (~(0xF)) | (0x5);
	UART2.UBRDIV2 = 53;
	UART2.UFRACVAL2 = 4;
	while(1)
	{
		while(!(UART2.UTRSTAT2 & (1 << 1)));
		UART2.UTXH2 = 'A';
		while(!(UART2.UTRSTAT2 & (1 << 1)));
		UART2.UTXH2 = 'B';
		while(!(UART2.UTRSTAT2 & (1 << 1)));
		UART2.UTXH2 = 'C';
		while(!(UART2.UTRSTAT2 & (1 << 1)));
		UART2.UTXH2 = 'D';
	} 
	return 0;
}

#include "exynos_4412.h"

void UART_Init(void)
{
	GPA1.CON = GPA1.CON & (~(0xFF)) | (0x22);
	UART2.ULCON2 = UART2.ULCON2 & (~(0x7F)) | (0x3);
	UART2.UCON2 = UART2.UCON2 & (~(0xF)) | (0x5);
	UART2.UBRDIV2 = 53;
	UART2.UFRACVAL2 = 4;
}

void uart_send_byte(char Dat)
{	
	while(!(UART2.UTRSTAT2 & (1 << 1)));
	UART2.UTXH2 = Dat;
}

char uart_recv_byte(void)
{
	char Dat = 0;
	if(UART2.UTRSTAT2 & 1)
	{
		Dat = UART2.URXH2;
		return Dat;
	}
	else
    {
		return 0;
    }
}

int main()
{
    char RecDat = 0;
	UART_Init();
	while(1)
	{
        RecDat = uart_recv_byte();
        if(RecDat == 0)
        {
        
        }
        else
        {
            RecDat = RecDat + 1;
            uart_send_byte(RecDat);
        }
	} 
	return 0;
}

 

 输入什么返回什么加一,以ASCII计算

五、输入输出重定向

#include "exynos_4412.h"

void UART_Init(void)
{
	GPA1.CON = GPA1.CON & (~(0xFF)) | (0x22);
	UART2.ULCON2 = UART2.ULCON2 & (~(0x7F)) | (0x3);
	UART2.UCON2 = UART2.UCON2 & (~(0xF)) | (0x5);
	UART2.UBRDIV2 = 53;
	UART2.UFRACVAL2 = 4;
}

void uart_send_byte(char Dat)
{	
	while(!(UART2.UTRSTAT2 & (1 << 1)));
	UART2.UTXH2 = Dat;
}

char uart_recv_byte(void)
{
	char Dat = 0;
	if(UART2.UTRSTAT2 & 1)
	{
		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();
#if 0
    while(1)
	{
        RecDat = uart_recv_byte();
        if(RecDat == 0)
        {
        
        }
        else
        {
            RecDat = RecDat + 1;
            uart_send_byte(RecDat);
        }
	}
#endif
    while(1)
    {
        uart_send_str("Hello World\n");
    }
	return 0;
}

因为Linux和windows换行不一样    windows要写/r/n 

 我们也可以把printf封装一下直接调用,但是这时的输出和以前的不同,以前的是Linux为我们提供的C库,它将输出重定向到显卡,所以我们能在屏幕上看到,而这个printf是我们自己写的,它重定向到了串口,所以我们使用串口软件连接单片机时能打印出来

#include "exynos_4412.h"

void UART_Init(void)
{
	GPA1.CON = GPA1.CON & (~(0xFF)) | (0x22);
	UART2.ULCON2 = UART2.ULCON2 & (~(0x7F)) | (0x3);
	UART2.UCON2 = UART2.UCON2 & (~(0xF)) | (0x5);
	UART2.UBRDIV2 = 53;
	UART2.UFRACVAL2 = 4;
}

void uart_send_byte(char Dat)
{	
	while(!(UART2.UTRSTAT2 & (1 << 1)));
	UART2.UTXH2 = Dat;
}

char uart_recv_byte(void)
{
	char Dat = 0;
	if(UART2.UTRSTAT2 & 1)
	{
		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();
#if 0
    while(1)
	{
        RecDat = uart_recv_byte();
        if(RecDat == 0)
        {
        
        }
        else
        {
            RecDat = RecDat + 1;
            uart_send_byte(RecDat);
        }
	}
#endif
    while(1)
    {
        printf("Hello World\n");
    }
	return 0;
}

六、使用串口控制LED

#include "exynos_4412.h"

void UART_Init(void)
{
	GPA1.CON = GPA1.CON & (~(0xFF)) | (0x22);
	UART2.ULCON2 = UART2.ULCON2 & (~(0x7F)) | (0x3);
	UART2.UCON2 = UART2.UCON2 & (~(0xF)) | (0x5);
	UART2.UBRDIV2 = 53;
	UART2.UFRACVAL2 = 4;
}

void uart_send_byte(char Dat)
{	
	while(!(UART2.UTRSTAT2 & (1 << 1)));
	UART2.UTXH2 = Dat;
}

char uart_recv_byte(void)
{
	char Dat = 0;
	if(UART2.UTRSTAT2 & 1)
	{
		Dat = UART2.URXH2;
		return Dat;
	}
	else
    {
		return 0;
    }
}

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

void LED_init(void)
{
	GPX2.CON = GPX2.CON & (~(0xF << 28)) | (0x1 << 28);	
}
unsigned int LED(unsigned int flag)
{
	if(flag == 1)
	{
		GPX2.DAT = GPX2.DAT | (1 << 7);
		return 0;
	}else if(flag == 0)
	{
		GPX2.DAT = GPX2.DAT & (~(1 << 7));
		return 1;
	}
}

int main()
{
    char RecDat = 0;
	UART_Init();
	LED_init();
#if 0
    while(1)
	{
        RecDat = uart_recv_byte();
        if(RecDat == 0)
        {
        
        }
        else
        {
            RecDat = RecDat + 1;
            uart_send_byte(RecDat);
        }
	}
#endif
	unsigned int flag = 1;
    while(1)
    {
		RecDat = uart_recv_byte();
        if(RecDat == 0)
        {
        
        }
        else if(RecDat == '2')
		{
			uart_send_byte(RecDat);
			flag = LED(flag);
		}
    }
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/133239.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Elasticsearch学习

基本概念 运维角度物理概念 分片&#xff08;shard&#xff09;&#xff1a;一个索引所占用的物理空间分配 primary shard&#xff1a;解决数据水平扩展问题&#xff0c;分片数据量过大时&#xff0c;可以通过增加DataNode节点扩容。一个主分片等于一个lucene实例。创建索引时…

windows认证之本地认证

windows认证包括本地认证、网络认证和域认证三个部分windows认证和密码的抓取可以说是内网渗透的第一步。 1、window认证流程 Windows的登陆密码是储存在系统本地的SAM文件中的&#xff0c;在登陆Windows的时候&#xff0c;系统会将用户输入的密码与 SAM文件中的密码进行对比&…

JavaScript基础系列之引用类型细节总结

1. 前言 这里不罗列 API&#xff0c;如果需要 API 可以自行查询。只会强调一些不起眼但是很重要的细节问题 2. Object 2.1 生成对象几种方式&#xff1a; 曾经被面试过哦&#xff0c; 虽然很基础&#xff0c;但是划重&#xff01;&#xff01;&#xff01; const obj new Obj…

【机器学习】线性回归(理论)

线性回归&#xff08;理论&#xff09; 目录一、概论1、何为线性回归2、问题的抽象3、误差的引入4、极大似然估计的引入5、目标函数的优化二、梯度下降1、何为梯度下降2、利用梯度下降进行函数寻优3、梯度下降的一些问题Ⅰ 迭代步长Ⅱ 算法的初始位置Ⅲ 数据的取值范围差异Ⅳ 鞍…

i.MX8MP平台开发分享(IOMUX篇)- uboot驱动

专栏目录:专栏目录传送门 平台内核i.MX8MP5.15.71文章目录 1. pinfunc.h2.iomux驱动3.pinctrl_select_state_full4.imx_pinctrl_set_state1. pinfunc.h pinfunc.h中定义了所有的引脚,命名方式是MX8MP_IOMUXC___,例如下面的MX8MP_IOMUXC_GPIO1_IO00__GPIO1_IO00定义了MUX寄存…

网络信息安全-LSB图像隐写与检测的设计实现

任务目标&#xff1a; 本选题需要学习经典的图像信息隐藏算法&#xff0c;包括基于空域的隐写算法和数字水印算法。 接着你将使用某种编程语言实现这些算法&#xff0c;实现在图片中嵌入一些信息&#xff0c;例如字符串和一些 文件。除此之外&#xff0c;还需要尝试一些基础的…

吴恩达《机器学习》——Logistic多分类与神经网络

Logistic多分类与神经网络1. MINIST数据集与Logistic多分类MINIST简介数据集可视化Logistic如何实现多分类&#xff1f;One-Hot向量Python实现2. 神经网络(Neural Network, NN)神经网络前馈传播Python实现3. 基于PyTorch框架的网络搭建数据集、源文件可以在Github项目中获得 链…

使用CMake构建静态库和动态库

使用CMake构建静态库和动态库一、准备工作二、动态库的构建2.1 工程改造2.2 编译动态库2.3 更多的说明三、静态库的构建3.1 错误的尝试3.2 新的构建指令四、动态库的版本号五、安装动态库和头文件一、准备工作 本机演示环境为&#xff1a; 主机windows11 vscode 虚拟机安装的…

人工智能在药物研发和生物技术中的应用:回顾与展望

人工智能(Artificial intelligence, AI)的出现正在重新塑造整个制药和生物技术行业的发展。几乎所有大大小小的生命科学和药物发现机构&#xff0c;都对采用人工智能驱动的发现平台表现出浓厚的兴趣&#xff0c;希望通过AI来简化研发工作&#xff0c;减少发现时间和成本&#x…

【C++基础】10:STL(二)

CppSTL&#xff08;二&#xff09; OVERVIEWCppSTL&#xff08;二&#xff09;一、函数对象1.函数对象&#xff1a;&#xff08;1&#xff09;概述&#xff1a;&#xff08;2&#xff09;简单使用&#xff1a;2.谓词&#xff1a;&#xff08;1&#xff09;一元谓词&#xff1a;…

LVGL学习笔记10 - 按钮Button

目录 1. Check型按钮 2. 修改样式 2.1 设置背景 2.1.1 颜色 2.1.2 透明度 2.1.3 渐变色 2.1.4 渐变色起始位置设置 2.2 修改边界 2.2.1 宽度 2.2.2 颜色 2.2.3 透明度 2.2.4 指定边 2.3 修改边框 2.4 修改阴影 2.4.1 宽度 2.4.2 透明度 2.4.3 偏移坐标 2.3.…

PHP代码审计系列(五)

PHP代码审计系列&#xff08;五&#xff09; 本系列将收集多个PHP代码安全审计项目从易到难&#xff0c;并加入个人详细的源码解读。此系列将进行持续更新。 数字验证正则绕过 源码如下 <?phperror_reporting(0); $flag flag{test}; if ("POST" $_SERVER[…

数值优化之凸集

本文ppt来自深蓝学院《机器人中的数值优化》 目录 1 凸集的定义 2 凸集的运算 1 凸集的定义 集合中任意两点连线形成的线段属于这个集合&#xff0c;这个集合是凸集。 注意&#xff1a;是否是凸集&#xff0c;集合的边界是否属于这个集合很重要 这涉及到构造最小凸包的问题…

行锁功过:怎么减少行锁对性能的影响?

在上一篇文章中,我跟你介绍了 MySQL 的全局锁和表级锁,今天我们就来讲讲 MySQL 的行锁。 MySQL 的行锁是在引擎层由各个引擎自己实现的。但并不是所有的引擎都支持行锁,比如 MyISAM 引擎就不支持行锁。不支持行锁意味着并发控制只能使用表锁,对于这种引擎的表,同一张表上…

Java中的四种引用类型

1.对象引用介绍 从 JDK1.2 版本开始&#xff0c;把对象的引用分为四种级别&#xff0c;从而使程序更加灵活的控制对象的生命周期。这四种级别由高到低依次为&#xff1a;强引用、软引用、弱引用和虚引用。 用表格整理之后&#xff0c;各个引用类型的区别如下&#xff1a; 2.强…

BOM编程:location对象

document 对象和window对象的location的区别 document对象的位置获取步骤是返回这个相关的全局对象的位置对象&#xff0c;如果这是完全活动的&#xff0c;否则为空。 Window对象的位置获取步骤是返回它的位置对象。每个Window对象都与创建Window对象时分配的Location对象的唯…

Spark01:Spark工作原理

1. Spark执行数据计算的整个流程 首先通过Spark客户端提交任务到Spark集群&#xff0c;然后Spark任务在执行的时候会读取数据源HDFS中的数据&#xff0c;将数据加载到内存中&#xff0c;转化为RDD&#xff0c;然后针对RDD调用一些高阶函数对数据进行处理&#xff0c;中间可以调…

ElementUI——案例1用户管理(基于SpringBoot)

1.前期准备 备注&#xff1a;主要涉及组件container组件&#xff0c;导航菜单组件&#xff0c;router路由组件&#xff0c;carousel 走马灯组件&#xff0c;Image组件&#xff0c;Table表格组件 #1.在项目开发目录使用脚手架新建vue项目&#xff08;需要提前安装好node和webp…

无字母数字webshell提高

前言 元旦快乐 -- 转眼就到了2023年 新的一年继续努力 在p神博客中看到一个 通过上传临时文件进行rce&#xff0c;便想着写一篇文章&#xff0c;记录一下这个小trick。太强了 比如给你下面这么一串代码。正如文章标题 无字母数字&#xff0c;如果匹配到字母和数字&#xf…

【Vuex快速入门】vuex基础知识与安装配置

vuex快速入门——什么是vuex&#xff1f;创作背景vuex基础知识一、vuex是什么&#xff1f;二、vuex的组成三、为什么使用vuex&#xff1f;四、什么时候使用vuex&#xff1f;vuex的安装配置一、直接下载 / CDN引用二、npm安装vuex三、yarn安装四、自己构建更多内容可参考Vuex官方…