ARM S5PV210 串行通信编程实战

news2024/11/18 21:27:48

一、串行通信编程实战1

1、整个程序流程分析

(1) 整个串口通信相关程序包含 2 部分:uart_init 负责初始化串口,uart_putc 负责发送一个字节。


2、串口控制器初始化关键步骤

(1) 初始化串口的 Tx 和 Rx 引脚所对应的GPIO(查原理图可知 Rx 和 Rx 分别对应GPA0_1和GPA0_0)

可以看到,S5PV210 上面一共有 4 个 UART 外设。
在这里插入图片描述


可以看到,UART0 外设的RXD/TXD 对应的引脚名称如下。

在这里插入图片描述


因此,在我们的核心板原理图上可以找到,UART0 的 RXD/TXD 引脚的对应关系:
UART0 RXD -> GPA0_0
UART0 TXD -> GPA0_1

在这里插入图片描述


(2) GPA0CON(0xE0200000),bit[3:0] = 0b0010 bit[7:4] = 0b0010

在这里插入图片描述


(3) 初始化这几个关键寄存器:UCON0, ULCON0, UMCON0, UFCON0, UBRDIV0, UDIVSLOT0.

在这里插入图片描述


3、主要的几个寄存器

(1) ULCON0 = 0x3 // 0校验位、8数据位、1停止位
在这里插入图片描述

(2) UCON = 0x5 // 发送和接收都是polling mode
在这里插入图片描述
在这里插入图片描述

(3) UMCON0 = 0x0 // 禁止modem、afc
在这里插入图片描述

(4) UFCON0 = 0x0 // 禁止FIFO模式
在这里插入图片描述
在这里插入图片描述

(5) UBRDIV0 和 UDIVSLOT0 和波特率有关,要根据公式去算的
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


4、在C源文件中定义访问寄存器的宏

/*  uart.c */
#define GPA0CON         0xE0200000
#define UCON0           0xE2900004
#define ULCON0          0xE2900000
#define UMCON0          0xE290000C
#define UFCON0          0xE2900008
#define UBRDIV0         0xE2900028
#define UDIVSLOT0       0xE290002C
#define UTRSTAT0        0xE2900010
#define UTXH0           0xE2900020
#define URXH0           0xE2900024

#define rGPA0CON        (*(volatile unsigned int *)GPA0CON)
#define rUCON0          (*(volatile unsigned int *)UCON0)
#define rULCON0         (*(volatile unsigned int *)ULCON0)
#define rUMCON0         (*(volatile unsigned int *)UMCON0)
#define rUFCON0         (*(volatile unsigned int *)UFCON0)
#define rUBRDIV0        (*(volatile unsigned int *)UBRDIV0)
#define rUDIVSLOT0      (*(volatile unsigned int *)UDIVSLOT0)
#define rUTRSTAT0       (*(volatile unsigned int *)UTRSTAT0)
#define rUTXH0          (*(volatile unsigned int *)UTXH0)
#define rURXH0          (*(volatile unsigned int *)URXH0)
/**************************************************************************************/
#define ULCON0_FUNC_NO_PARITY_MODE             (0b000 << 3)  // 无校验
#define ULCON0_FUNC_NUMBER_STOP_0_BIT          (0b0   << 2)  // Stop bit: 0
#define ULCON0_FUNC_WORLD_LENGTH_8_BIT         (0b11  << 0)  // 8 位数据位

/**************************************************************************************/
#define UCON0_FUNC_CLOCK_SELECTION_PLCK        (0b0   <<10)  //选择PCLK
#define UCON0_FUNC_LOOPBACK_MODE_NORMAL        (0b0   << 5)  //正常模式
#define UCON0_FUNC_TX_MODE_POLLING             (0b01  << 2)  //轮询模式
#define UCON0_FUNC_RX_MODE_POLLING             (0b01  << 0)  //轮询模式

/**************************************************************************************/
#define UFCON0_FUNC_FIFO_DISABLE               (0b0   << 0)  //禁止 FIFO 模式

/**************************************************************************************/
#define UTRSTAT0_FUNC_TRANSMITTER_EMPTY                       (0b1   << 2)  //发送缓冲区为空
#define BIT_LOCATION_UTRSTAT0_FUNC_TRANSMITTER_EMPTY          (0b1   << 2)  //发送缓冲器状态位
#define UTRSTAT0_FUNC_RECEIVE_BUFFER_DATA_READY               (0b1   << 0)  //接收缓冲区已接收到数据
#define BIT_LOCATION_UTRSTAT0_FUNC_RECEIVE_BUFFER_DATA_READY  (0b1   << 0)  //接收缓冲区状态位

/**************************************************************************************/
#define BIT_WIDTH_GPA0                  (4)   
#define GPA0_0_FUNC_INPUT               (0x0 << 0 * BIT_WIDTH_GPA0)
#define GPA0_0_FUNC_OUTPUT              (0x1 << 0 * BIT_WIDTH_GPA0)
#define GPA0_0_FUNC_UART0RXD            (0x2 << 0 * BIT_WIDTH_GPA0)
#define GPA0_0_FUNC_GPA0_INT0           (0Xf << 0 * BIT_WIDTH_GPA0)
							            
#define GPA0_1_FUNC_INPUT               (0x0 << 1 * BIT_WIDTH_GPA0)
#define GPA0_1_FUNC_OUTPUT              (0x1 << 1 * BIT_WIDTH_GPA0)
#define GPA0_1_FUNC_UART0TXD            (0x2 << 1 * BIT_WIDTH_GPA0)
#define GPA0_1_FUNC_GPA0_INT1           (0Xf << 1 * BIT_WIDTH_GPA0)

#define BIT_LOCATION_GPA0_CON0          (0xf << 0 * BIT_WIDTH_GPA0)
#define BIT_LOCATION_GPA0_CON1          (0xf << 1 * BIT_WIDTH_GPA0)

/**************************************************************************************/


定义好了访问寄存器的宏之后,将来写代码时直接使用即可。


二、串行通信编程实战2

1、串口 Tx、Rx 对应的 GPIO 的初始化

给 GPA0CON 的相应 bit 位赋值为相应值,用 C 语言位操作来完成。
    // 初始化 TX RX 对应的 GPIO 引脚
    rGPA0CON &= ~(BIT_LOCATION_GPA0_CON0 | BIT_LOCATION_GPA0_CON1);  
    rGPA0CON |= GPA0_0_FUNC_UART0RXD  | GPA0_1_FUNC_UART0TXD;

2、UCON、ULCON、UMCON、UFCON等主要控制寄存器

依据上节中分析的值进行依次设置即可。
    //几个关键寄存器的设置
    rULCON0 = ULCON0_FUNC_NO_PARITY_MODE | ULCON0_FUNC_NUMBER_STOP_0_BIT | ULCON0_FUNC_WORLD_LENGTH_8_BIT;
    rUCON0 = UCON0_FUNC_CLOCK_SELECTION_PLCK | UCON0_FUNC_LOOPBACK_MODE_NORMAL | UCON0_FUNC_TX_MODE_POLLING | UCON0_FUNC_RX_MODE_POLLING;
    rUMCON0 = 0;
    rUFCON0 = UFCON0_FUNC_FIFO_DISABLE;

3、波特率的计算和设置

(1)第一步,用 PCLK_PSYS 和目标波特率去计算 DIV_VAL: DIV_VAL = (PCLK / (bps x 16)) - 1
(2)第二步,UBRDIV0 寄存器中写入 DIV_VAL 的整数部分
(3)第三步,用小数部分乘以 16 得到 1 的个数,查表得 uBDIVSLOT0 寄存器的设置值
在这里插入图片描述

    //波特率设置  DIV_VAL = (PCLK / (bps X 16) ) - 1
    //PCLK_PSYS 用 66MHz 算  DIV_VAL = (66 X 10^6 / (115200 X 16)) - 1 = 34.807
    //小数是 0.8,0.8 x 16 = 12.8
    rUBRDIV0 = 34;
    //12 0xDDDD(1101_1101_1101_1101b)
    //13 0xDFDD(1101_1111_1101_1101b)
    rUDIVSLOT0 =  0xDDDD;

4、串口发送和接收函数的编写

(1) 写发送函数,主要发送前要用 while 循环等待发送缓冲区为空才能发送。

//串口接收程序,轮询方式,接收一个字节
void uart_putc(char c)
{
    //串口发送一个字符,其实就是把一个字节丢到发送缓冲区中去
    //因为串口控制器发送 1 个字节的速度远远低于 CPU 的速度,所以 CPU 发送1个字节前必须
    //确认串口控制器当前缓冲区是空的(意思就是串口已经发完了上一个字节)
    //如果缓冲区非空则位为0,此时应该循环,直到位为1
    while (rUTRSTAT0 & (BIT_LOCATION_UTRSTAT0_FUNC_TRANSMITTER_EMPTY) != UTRSTAT0_FUNC_TRANSMITTER_EMPTY) ;
    rUTXH0 = c;
}

源自朱有鹏老师.

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

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

相关文章

【数列分段DP】膜拜

P1564 膜拜 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意&#xff1a; 思路&#xff1a; 这是个经典模型&#xff1a;数列分段DP&#xff0c;在其他地方也出现过&#xff1a;(150条消息) 代码源每日一题div1 DP 数组划分_lamentropetion的博客-CSDN博客 这类DP模型核…

_13LeetCode代码随想录算法训练营第十三天-C++二叉树

_13LeetCode代码随想录算法训练营第十三天-C二叉树 题目列表 102.二叉树的层序遍历107.二叉树的层次遍历II199.二叉树的右视图637.二叉树的层平均值429.N叉树的层序遍历515.在每个树行中找最大值116.填充每个节点的下一个右侧节点指针117.填充每个节点的下一个右侧节点指针II…

说话人识别中的数据预处理和数据增强

数据预处理 假设已经采集到一些数据&#xff0c;在进行训练之前&#xff0c;需要先对数据做以下预处理&#xff1a; 数据清洗语音检测&#xff08;Voice Activity Detection&#xff0c;VAD&#xff0c;也叫Speech Detection&#xff0c;或Silence Suppression&#xff0c;静音…

ICMP V6(计算机网络-网络层)

IPv6 使用的 ICMP IETF 制定的与IPv6配套使用的ICMP新版本&#xff0c;即ICMPv6 ICMPv6报文作为IPv6分组有效载荷进行传输&#xff0c;对应的IPv6“下一个首部字段”的值为58 ICMPv6 的报文格式和 IPv4 使用的 ICMP 的相似&#xff0c;即前 4 个字节的字段名称都是一样的&…

Linux下进程及其相关概念理解

目录 何为进程&#xff1f; task_struct 中存储了什么进程信息&#xff1f; 如何查看进程&#xff1f; 如何获取进程pid&#xff1f; 如何创建子进程&#xff1f; 为什么返回值如此呢&#xff1f; 为什么有两个返回值&#xff1f; 进程状态 进程的一般状态 运行态 终…

18-JavaSE基础巩固练习:正则表达式练习

正则表达式基本练习 一、练习1 1、需求 请编写正则表达式验证用户输入的手机号码是否满足要求。请编写正则表达式验证用户输入的邮箱号是否满足要求。请编写正则表达式验证用户输入的电话号码是否满足要求。 2、思路&#xff1a; 心得&#xff1a; 拿着一个正确的数据&…

SAP UI5 Smart Chart 功能介绍

笔者已经写过一篇详细的文章介绍 SAP UI5 Smart Chart 的使用方法&#xff1a; SAP UI5 应用开发教程之一百五十三 - 使用 SAP UI5 Smart Chart 控件轻松绘制十数种不同类型的专业图表 本文泛泛地介绍 Smart Chart 提供的一些其他功能。 工具栏右侧的按钮可用于选择图表类型…

Zookeeper 1 初识 Zookeeper 1.1 Zookeeper 概念

Zookeeper 【黑马程序员Zookeeper视频教程&#xff0c;快速入门zookeeper技术】 文章目录Zookeeper1 初识 Zookeeper1.1 Zookeeper 概念1.1.1 Zookeeper 概念1 初识 Zookeeper 1.1 Zookeeper 概念 1.1.1 Zookeeper 概念 Zookeeper 是 Apache Hadoop 项目下的一个子项目&…

3、前端笔记-JS-变量

1、什么是变量 变量是用于存放数据的容器&#xff0c;可以通过变量名获取数据 本质&#xff1a;变量是程序在内存中申请的一块用来存放数据的空间 2、变量的使用 2.1 声明变量和赋值 1、声明变量 2、给变量赋值 var:JS关键字&#xff0c;用来声明变量。使用这个关键字后&a…

(二)计算机组成原理——计算机的基本组成

目录 冯诺依曼计算机的特点 计算机硬件框图 系统复杂性管理的方法&#xff08;3’Y&#xff09; 计算机的工作步骤 上机前的准备 计算机的工作过程 存储器的基本组成 运算器的基本组成及操作过程 控制器 计算机组成原理课程笔记。 冯诺依曼计算机的特点 冯诺依曼计算…

sandbox启动未加载repeater的问题

背景 通过官方提供的 repeater 的下载链接&#xff0c;并不能够在sandbox启动时&#xff0c;加载进行&#xff0c;我们可以看下sandbox的日志截图 但是如果通过源码的repeater进行安装后&#xff0c;就能够成功加载到repeater。 分析 这是个很奇怪的问题&#xff0c;想要分析…

Sentinel的规则

四.Sentinel的规则 1.流控规则 1.1流控规则有哪些? 流量控制有以下几个角度: 资源的调用关系&#xff0c;例如资源的调用链路&#xff0c;资源和资源之间的关系&#xff1b;运行指标&#xff0c;例如 QPS&#xff08;每秒查询率&#xff09;、线程池、系统负载等&#xff…

深度学习时数据量过大的一个解决思路:将零散的数据集中化

问题描述 最近笔者在做一个kaggle上的树叶分类的题目&#xff08;https://www.kaggle.com/competitions/classify-leaves&#xff09;&#xff0c;这个题目要求根据一张树叶的图片给出这片树叶的类别&#xff0c;这个题目也是沐神的《动手深度学习》课程里的一个课程竞赛题目。…

编译原理笔记03

第四章 语义分析 语义分析也称为类型检查&#xff0c;上下文相关分析&#xff0c;主要负责检查程序的上下文相关的属性&#xff0c;例如变量使用前要声明&#xff0c;函数调用要与声明一致等。 1.语义规则 通常来说&#xff0c;程序设计语言都采用自然语言来表达程序语言的语义…

JMeter分布式压测

一、Jmeter4.0分布式压测准备工作 压测注意事项 the firewalls on the systems are turned off or correct ports are opened. 系统上的防火墙被关闭或正确的端口被打开。 all the clients are on the same subnet. 所有的客户端都在同一…

数据科学与工程理论基础复习提纲

一、Sketch 1.1 简单抽样算法 1.1.1 核心思想 对于到达的元素aia_iai​&#xff0c;以概率pM/mpM/mpM/m对该元素的频数加1。 MMM&#xff1a;抽样后的数据流大小mmm&#xff1a;原始数据流大小 1.1.2 操作 更新&#xff1a;当元素aia_iai​到达时&#xff0c;以ppp的概率更…

分库分表:垂直分库、垂直分表、水平分库、水平分表四个概念

文章目录一、分库分表的意义二、垂直分表的思路三、垂直分库的思路四、水平分库的思路五、水平分表的思路一、分库分表的意义 随着公司业务快速发展&#xff0c;数据库中的数据量猛增&#xff0c;访问性能也变慢了&#xff0c;优化迫在眉睫。分析一下问题出现在哪儿呢&#xf…

太强了,阿里内部JDK源码剖析知识手册,由浅入深堪称完美

前言 作为Java程序员&#xff0c;在这里想问问大家在空余时间有没有去读过 JDK 源码&#xff0c;虽然读源码有点自不量力的感觉&#xff0c;&#xff08;大佬可以忽略这句&#xff09;但是如若能够经常在空余时间看一下 jdk 源码不仅可以让自己对日常的开发环境了解得更加深刻…

【nowcoder】笔试强训Day3

目录 一、选择题 二、编程题 2.1在字符串中找出连续最长的数字串 2.2 数组中出现次数超过一半的数字 一、选择题 1.以下代码运行输出的是 public class Person{private String name "Person";int age0;} public class Child extends Person{public String gra…

Python json常见用法

目录 导包 api介绍 常见用法 json转python内置对象 字典对象 数组对象 文件读取 python内置对象转json 字典转json 字典转json&#xff08;压缩存储&#xff09; 字典转json&#xff08;美化输出&#xff09; 文件读取 自定义对象 普通对象 嵌套对象 补充支持 …