LV.12 D13 UART实验 学习笔记

2023-11-02 02:04
文章标签 学习 笔记 实验 uart lv.12 d13

本文主要是介绍LV.12 D13 UART实验 学习笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、UART帧格式详解

 UART    

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

通信基础 - 并行和串行

        并行通信:总线在传送数据的时候,可以一次性发送多位数据。

        

        串行通信:数据线只有一根,逐次传送各位数据

 

        在同等条件下,并行比串行的通信速度更快,但并行使用的总线数量较多,会比较浪费资源,布线难度也比较大,不同总线在传输数据时,线和线之间都会有一些信号的干扰。做项目时,使用串行通信多一点

通信基础 - 单工和双工

        单工通信:通信的双方区分为发送器和接收器,数据传输的方向是单向的

 

        双工通信: 分为半双工和全双工,它们数据的传输都是双向的。半双工通信时,A和B可以互相发数据,但不能是同时的,而全双工可以同时进行。

如果总线的数据线只有一根,一般是半双工的,如果有多根,一般是全双工。

通信基础 - 波特率 

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

UART帧格式

        起始位表示一次通信的开始,数据位就是通过串口发送的数据,校验位会校验(只能校验,不能修正)数据发送的正确性,停止位表示一次通信的结束。如果想发送多个数据,重复这个步骤就可以

注:  1、数据线在空闲时,数据线上的状态必须是高电平。       

         2、发送数据时,先发低位数据。

        3、串口每次只能发送一个字节, 是为了避免产生累计误差(发送方与接收方的时间误差)。

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

UART硬件连接

 两个芯片通信时,要交叉接线,一方的TXD要与另一方的RXD连接,

 

UART控制器

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

二、Exynos4412下的 UART控制器

引脚功能设置 

 注:设置引脚功能的实质是让引脚在芯片内部连接到某一个对应的控制器上

 

        串口的高低电平信号较弱,极有可能收到干扰,通信距离较短。为了增强串口的信号,在中间加了一个U3芯片,把串口发出来的TTL信号转化为232信号。 

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

  

        UART在4412内部提供了四个独立的通道,每个通道都包含输入输出端口,这4和通道时Ch0-3,另外还提供了一个专用通道Ch4,用于跟GPS通信(本次使用的是ch2)。所有的端口都可以运行中断和DMA模式。在CPU和串口控制器进行数据传送时,UART既可以产生中断,也可以产生DMA的一些请求。UART支持的波特率最大是4Mbps。每个串口通道都有两个FIFO用于接收和发送数据,

        想要发送数据时,只需要将发送内容写入FIFO(队列)就会自动发送,接收时也只需要读取FIFO(队列)内容即可。

 

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

支持红外传输,(无线)

1位或者两位停止位

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

 

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

 

        波特率的发生器使用SCLK_UART时钟,他的频率时100M,发送器和接收器都包含队列和移位器。要被发送的数据会先写到发送队列里,如何数据会被拷贝到发送的移位器。数据通过发送数据的引脚被移出去。接收的数据从接收数据的引脚移进来,被拷贝到接收的缓冲区里。

数据通过FIFO->移位器->引脚实现发送,通过引脚->移位器->FIFO实现接收。

 

三、UART寄存器详解 

先用tar xvf命令解压出一个新工程

 

1、将GPA1_0和GPA1_1分别设置成UART2的接收引脚和发送引脚 GPA1CON[7:0] 

 

 

2、设置UART2的帧格式 ULCON2 (8位数据位、1位停止位、无校验位、正常模式)

 

 

 回环模式就是将发送端和用户端短接,一般用于测试。

 

中断模式:有消息通知CPU

轮询模式:CPU不断的读取缓冲区,查看有没有数据

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

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

3、设置UART2的接收和发送模式为轮询模式 UCON2[3:0]

 

 

 只读,[1]表示发送的队列是空的,[0]表示接收的队列有数据

把要发送的数据写到UTXHn寄存器的[7:0]位

 

接收器接收到的数据会放入URXHn寄存器的[7:0]位

 

 

  UBRDIVn寄存器的[15:0]位和UFRACVALn寄存器的[3:0]位是设置波特率的

4、设置UART2的波特率为115200 (UBRDIV2 / UFRACVAL2) 

四、UART编程

#include "exynos_4412.h"int main()
{/*1.将GPA1_0和GPA1_1设置成UART2的接收引脚和发送引脚 GPA1CON[7:0]*/GPA1.CON = GPA1.CON & (~(0xFF << 0)) | (0x22 << 0);/*2.设置UART2的帧格式 ULCON2 (8位数据位、1位停止位、无校验位、正常模式)*/UART2.ULCON2 = UART2.ULCON2 & (~(0x7F << 0)) | (0x3 << 0);/*3.设置UART2的接收和发送模式为轮询模式 UCON2[3:2]*/UART2.UCON2 = UART2.UCON2 & (~(0xF << 0)) | (0x5 << 0);/*4.设置UART2的波特率为115200 (UBRDIV2 / UFRACVAL2)*/UART2.UBRDIV2 = 53;UART2.UFRACVAL2 = 4;while(1){/*将发送的数据写入发送寄存器 UTXH2*/UART2.UTXH2 = 'A';}return 0;
}

 

#include "exynos_4412.h"int main()
{/*1.将GPA1_0和GPA1_1设置成UART2的接收引脚和发送引脚 GPA1CON[7:0]*/GPA1.CON = GPA1.CON & (~(0xFF << 0)) | (0x22 << 0);/*2.设置UART2的帧格式 ULCON2 (8位数据位、1位停止位、无校验位、正常模式)*/UART2.ULCON2 = UART2.ULCON2 & (~(0x7F << 0)) | (0x3 << 0);/*3.设置UART2的接收和发送模式为轮询模式 UCON2[3:2]*/UART2.UCON2 = UART2.UCON2 & (~(0xF << 0)) | (0x5 << 0);/*4.设置UART2的波特率为115200 (UBRDIV2 / UFRACVAL2)*/UART2.UBRDIV2 = 53;UART2.UFRACVAL2 = 4;while(1){/*将发送的数据写入发送寄存器 UTXH2*/UART2.UTXH2 = 'A';UART2.UTXH2 = 'B';UART2.UTXH2 = 'C';UART2.UTXH2 = 'D';}return 0;
}

 并没有输出想要的结果,因为CPU的执行速度是1GHz,而发送器的速度是115200,两者的速度不一样,所以发送的字符是随机的。

#include "exynos_4412.h"int main()
{/*1.将GPA1_0和GPA1_1设置成UART2的接收引脚和发送引脚 GPA1CON[7:0]*/GPA1.CON = GPA1.CON & (~(0xFF << 0)) | (0x22 << 0);/*2.设置UART2的帧格式 ULCON2 (8位数据位、1位停止位、无校验位、正常模式)*/UART2.ULCON2 = UART2.ULCON2 & (~(0x7F << 0)) | (0x3 << 0);/*3.设置UART2的接收和发送模式为轮询模式 UCON2[3:2]*/UART2.UCON2 = UART2.UCON2 & (~(0xF << 0)) | (0x5 << 0);/*4.设置UART2的波特率为115200 (UBRDIV2 / UFRACVAL2)*/UART2.UBRDIV2 = 53;UART2.UFRACVAL2 = 4;while(1){/*将发送的数据写入发送寄存器 UTXH2*/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)
{/*1.将GPA1_0和GPA1_1设置成UART2的接收引脚和发送引脚 GPA1CON[7:0]*/GPA1.CON = GPA1.CON & (~(0xFF << 0)) | (0x22 << 0);/*2.设置UART2的帧格式 ULCON2 (8位数据位、1位停止位、无校验位、正常模式)*/UART2.ULCON2 = UART2.ULCON2 & (~(0x7F << 0)) | (0x3 << 0);/*3.设置UART2的接收和发送模式为轮询模式 UCON2[3:2]*/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)
{/*等待发送寄存器寄存器为空*/while(!(UART2.UTRSTAT2 & (1 << 1)));/*将发送的数据写入发送寄存器 UTXH2*/UART2.UTXH2 = Dat;
}char UART_Rec_Byte(void)
{char Dat;/*判断接收寄存器是否接收到了数据*/if(UART2.UTRSTAT2 & 1){Dat = UART2.URXH2;return Dat;}else{return 0;}
}int main()
{char RecDat = 0;UART_Init();while(1){RecDat = UART_Rec_Byte();if(RecDat == 0){}else{RecDat = RecDat + 1;UART_Send_Byte(RecDat);}}return 0;
}

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

 

 五、输入输出重定向

#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的帧格式 ULCON2 (8位数据位、1位停止位、无校验位、正常模式)*/UART2.ULCON2 = UART2.ULCON2 & (~(0x7F << 0)) | (0x3 << 0);/*3.设置UART2的接收和发送模式为轮询模式 UCON2[3:2]*/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)
{/*等待发送寄存器寄存器为空*/while(!(UART2.UTRSTAT2 & (1 << 1)));/*将发送的数据写入发送寄存器 UTXH2*/UART2.UTXH2 = Dat;
}char UART_Rec_Byte(void)
{char Dat;/*判断接收寄存器是否接收到了数据*/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();while(1){  UART_Send_Str("Hello World\n");}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;}
}void uart_send_str(char * pstr)
{while(*pstr != '\0')uart_send_byte(*pstr++);
}int main()
{char RecDat = 0;UART_Init();while(1){printf("Hello World\n");}return 0;
}

 

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

作业

 1.若使用UART协议发送一个字节的数据0x63,画出信号线上的时序图

注:8位数据位、无校验位、一位停止位

 

2.编程实现电脑远程控制LED状态

注:在终端上输入‘2’,LED2点亮,再次输入‘2’,LED2熄灭... ...

#include "exynos_4412.h"void UART_Init(void)
{/*1.将GPA1_0和GPA1_0_1置成ART2的接收引脚和发送引脚 GPA1CON[7:0]*/GPA1.CON = GPA1.CON & (~(0xFF << 0)) | (0x22 << 0);/*2.设置UART2的帧格式 ULCON2(8位数据位、1位停止位、无校验位、正常模式)*/UART2.ULCON2 = UART2.ULCON2 & (~(0x7F << 0)) | (0x3 << 0);/*3.设置UART2的接收和发送模式为轮询模式 UCON2[3:2]*/UART2.UCON2 = UART2.UCON2 & (~(0xF << 0)) | (0x5 << 0);/*4.设置UART2的波特率为115200 (UBRDIV2 / UFRACVAL2)*/UART2.UBRDIV2 = 53;UART2.UFRACVAL2 = 4;
}void GPIO_Init(void)
{GPX2.CON = GPX2.CON & (~(0xF << 28)) | (0x1 << 28);
}void UART_Send_Byte(char Dat)
{/*等待发送寄存器寄存器为空*/while(!(UART2.UTRSTAT2 & (1 << 1)));/*将发送的数据写入发送寄存器 UTXH2*/UART2.UTXH2 = Dat;
}char UART_Rec_Byte(void)
{char Dat;/*判断接收寄存器是否接收了数据*/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 OnLED2(void)
{GPX2.DAT = GPX2.DAT | (1 << 7);
}void OffLED2(void)
{GPX2.DAT = GPX2.DAT & (~(1 << 7));
}int main()
{char RecDat = 0;UART_Init();GPIO_Init();while(1){   RecDat = UART_Rec_Byte();if(RecDat == '2'){if(GPX2.DAT & (1 << 7)){OffLED2();}else{OnLED2();}}else{}}return 0;
}

这篇关于LV.12 D13 UART实验 学习笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/327343

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

线性代数|机器学习-P36在图中找聚类

文章目录 1. 常见图结构2. 谱聚类 感觉后面几节课的内容跨越太大,需要补充太多的知识点,教授讲得内容跨越较大,一般一节课的内容是书本上的一章节内容,所以看视频比较吃力,需要先预习课本内容后才能够很好的理解教授讲解的知识点。 1. 常见图结构 假设我们有如下图结构: Adjacency Matrix:行和列表示的是节点的位置,A[i,j]表示的第 i 个节点和第 j 个

Node.js学习记录(二)

目录 一、express 1、初识express 2、安装express 3、创建并启动web服务器 4、监听 GET&POST 请求、响应内容给客户端 5、获取URL中携带的查询参数 6、获取URL中动态参数 7、静态资源托管 二、工具nodemon 三、express路由 1、express中路由 2、路由的匹配 3、路由模块化 4、路由模块添加前缀 四、中间件