【JZ2440笔记】串口通信

2024-01-24 01:30
文章标签 笔记 通信 串口 jz2440

本文主要是介绍【JZ2440笔记】串口通信,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、前言

二、实验目标

三、串口资源介绍

四、程序编写

五、实验总结


一、前言

串口通信是嵌入式开发中非常常见的调试工具接口,我们大都通过串口的打印输出来确定程序的运行状况,无论是在单片机还是在各种ARM处理器上,基本上都会有串口这个外设,以下是S3C2440的串口调试过程。

 

二、实验目标

通过JZ2440上的串口0实验与PC机的串口通信,波特率为115200、无奇偶校验位,8个数据位,1个停止位,并且开发板将串口助手发送的数据原样返回给串口助手。

 

三、串口资源介绍

1、开发板连线

S3C2440有三个串口模块,分别为UART0、UART1和UART2,JZ2440开发板将这三个串口全部引出到排针,其中UART0还通过PL2303芯片转出了一个micro USB接口,原理图如下:

 

2、S3C2440串口介绍

串口模块方框图如下:

串口模块可以通过PCLK、FCLK/n或UEXTCLK来提供运行时钟,每个串口通道都有64字节的发送缓冲寄存器和64字节的接收缓冲寄存器,这些缓冲寄存器可以通过配置选择使用或者不使用,同时串口模块还支持中断和DMA传输,这些附加功能跟单片机一模一样。另外串口模块还可以配置位红外模式来使用。

 

3、串口寄存器配置

串口的波特率和分频之间的计算公式如下:

UBRDIVn = (int)( UART 时钟 / ( 波特率 × 16) ) - 1

举个例子:如果波特率为 115200 bps 并且 UART 时钟为 40 MHz,则 UBRDIVn 为:

UBRDIVn = (int)(40000000 / (115200 x 16) ) - 1

= (int)(21.7) - 1 [ 取最接近的整数]

= 22 - 1 = 21

当然,由于取整的原因,以上计算是有一定误差的,手册上建议的误差是UART 帧误差应该小于 1.87%(3/160)。波特率设置的寄存器如下:

我们使用串口0只需要设置ULCON0,波特率为115200、无奇偶校验位,8个数据位,1个停止位,所以ULCON0的配置为0x03。

接下来是UCON寄存器:

因为使用的是PCLK作为串口工作时钟,所以FCLK Divider不用管,Clock Selection设为0,Tx Interrupt Type设为0不使用发送FIFO,Rx Interrupt Type设为0不使用接收FIFO,Transmit Mode 设置为01,Receive Mode设置为01。这样UCON0寄存器就设置为0x05。

还有波特率分频设置:

UBRDIV0 = (PCLK_SPEED / (115200 * 16)) - 1,PCLK_SPEED为50MHz,所以UBRDIV0为26。

配置好了上述寄存器后,我们还需要有标志位来判断什么时候接收到了数据,什么时候发送完成了数据,有如下的状态寄存器:

要发送的数据需要写到UTXH0 寄存器中,接收数据可以从URXH0中获得。

 

四、程序编写

程序分为以下几个文件:

head.S;启动文件。

init.c:关闭看门狗,初始化时钟的函数。

uart.c:串口相关配置。

uart.h:串口头文件。

main.c:主函数。

Makefile:编译程序。

每个文件具体内容如下:

head.S

@*************************************************************************
@ File:head.S
@ 功能:设置FCLK到400MHz,然后初始化串口
@*************************************************************************       
.text
.global _start
_start:ldr	    sp, =4096                       @设置堆栈,因为要调用C语言函数 bl	    disable_watch_dog               @关WATCH DOGbl	    init_system_clk                 @初始化系统时钟,FCLK=400MHz,HCLK=100MHz,PCLK=50MHzbl      main                            @跳转执行main函数halt_loop:b       halt_loop

init.c

/* WOTCH DOG register */
#define REG_WTCON               (*(volatile unsigned long *)0x53000000)/* Sys Clk Config */
#define REG_CLKDIVN             (*(volatile unsigned long *)0x4C000014)
#define REG_CAMDIVN             (*(volatile unsigned long *)0x4C000018)
#define REG_MPLLCON             (*(volatile unsigned long *)0x4C000004)void disable_watch_dog();
void init_system_clk();/*上电后,WATCH DOG默认是开着的,要把它关掉 */
void disable_watch_dog()
{REG_WTCON	= 0;
}void init_system_clk()
{//HCLK = FCLK/4, 当 CAMDIVN[9] = 0 时//PCLK 设置为 HCLK/2 //完成配置FCLK : HCLK : PCLK = 1 : 1/4 : 1/8,DIVN_UPLL是USB的时钟不用管REG_CLKDIVN = (2 << 1) | (1 << 0);/* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */
__asm__("mrc    p15, 0, r1, c1, c0, 0\n"        /* 读出控制寄存器 */ "orr    r1, r1, #0xc0000000\n"          /* 设置为“asynchronous bus mode” */"mcr    p15, 0, r1, c1, c0, 0\n"        /* 写入控制寄存器 */);//m=MDIV+8, p=PDIV+2, s=SDIV, Mpll = ( 2 × m × Fin ) / ( p × 2^s )//FCLK = (2 * (92 + 8) * 12000000) / ((1 + 2) * 2) = 400000000 = 400MHz//配置完MPLL后时钟停振,CPU停止运行等待时钟输出稳定,之后FCLK=400MHz,HCLK=100MHz,PCLK=50MHz */REG_MPLLCON = (92<<12)|(1<<4)|(1<<0);
}

uart.c

#include "uart.h"void init_uart(DWORD buadrate)
{//Step1,配置GPIO,GPH3(RXD0),GPH2(TXD0)//清除相关配置位REG_GPHCON &= ~((DWORD)(3 << (2*3)) | (3 << (2*2)));REG_GPHDAT &= ~((DWORD)(1 << 3) | (1 << 2));REG_GPHUP &= ~((DWORD)(1 << 3) | (1 << 2));//设置相关配置位REG_GPHCON |= ((DWORD)2 << (2*3)) | (2 << (2*2));REG_GPHDAT |= ((DWORD)1 << 3) | (1 << 2);REG_GPHUP |= ((DWORD)1 << 3) | (1 << 2);//无校验,1个停止位,8个数据位REG_ULCON0 = 0x03;//发送和接受设置为查询/中断模式REG_UCON0 = 0x05;//不使用FIFOREG_UFCON0 = 0;//不使用流控REG_UMCON0 = 0;//UBRDIVn = (int)( UART clock / ( buad rate x 16) ) –1REG_UBRDIV0 = (PCLK_SPEED / (115200 * 16)) - 1;
}void uart_send(BYTE ch)
{while(!(REG_UTRSTAT0 & (1 << 2))){;}REG_UTXH0 = ch;
}BYTE uart_receive()
{while(!(REG_UTRSTAT0 & (1 << 0))){;}return REG_URXH0;
}

uart.h

#ifndef _UART_H_
#define _UART_H_#define BYTE unsigned char
#define WORD unsigned short
#define DWORD unsigned int/* Uart Config */
#define PCLK_SPEED              50000000#define REG_GPHCON              (*(volatile unsigned long *)0x56000070)
#define REG_GPHDAT              (*(volatile unsigned long *)0x56000074)
#define REG_GPHUP               (*(volatile unsigned long *)0x56000078)#define REG_ULCON0              (*(volatile unsigned long *)0x50000000)
#define REG_UCON0               (*(volatile unsigned long *)0x50000004)
#define REG_UFCON0              (*(volatile unsigned long *)0x50000008)
#define REG_UMCON0              (*(volatile unsigned long *)0x5000000C)#define REG_UTXH0               (*(volatile unsigned long *)0x50000020)
#define REG_URXH0               (*(volatile unsigned long *)0x50000024)#define REG_UBRDIV0             (*(volatile unsigned long *)0x50000028)#define REG_UTRSTAT0            (*(volatile unsigned long *)0x50000010)void init_uart(DWORD buadrate);
void uart_send(BYTE ch);
BYTE uart_receive();#endif

main.c

#include "uart.h"void wait(volatile unsigned long dly)
{for(; dly > 0; dly--);
}int main()
{init_uart(115200);while(1){		uart_send(uart_receive());}return 0;
}

Makefile

objs := head.o init.o uart.o main.ouart.bin: $(objs)arm-linux-ld -Ttext 0x0000000 -g -o uart_elf $^arm-linux-objcopy -O binary -S uart_elf $@arm-linux-objdump -D -m arm uart_elf > uart.dis%.o:%.carm-linux-gcc -Wall -O2 -c -o $@ $<%.o:%.Sarm-linux-gcc -Wall -O2 -c -o $@ $<clean:rm -f uart.bin uart_elf uart.dis *.o	

最后,将所有源文件拷贝到linux下,执行make命令后,将生成的bin文件烧写到开发板NandFlash中,选择开发板nand启动后,连接串口线到串口0,使用串口助手可以看见实验现象,串口助手发送的所有数据被原样返回。

 

五、实验总结

串口的配置方式和寄存器基本都和单片机的一样,也就那些基本的操作。

 

 

 

这篇关于【JZ2440笔记】串口通信的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

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

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

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

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

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

论文阅读笔记: Segment Anything

文章目录 Segment Anything摘要引言任务模型数据引擎数据集负责任的人工智能 Segment Anything Model图像编码器提示编码器mask解码器解决歧义损失和训练 Segment Anything 论文地址: https://arxiv.org/abs/2304.02643 代码地址:https://github.com/facebookresear

数学建模笔记—— 非线性规划

数学建模笔记—— 非线性规划 非线性规划1. 模型原理1.1 非线性规划的标准型1.2 非线性规划求解的Matlab函数 2. 典型例题3. matlab代码求解3.1 例1 一个简单示例3.2 例2 选址问题1. 第一问 线性规划2. 第二问 非线性规划 非线性规划 非线性规划是一种求解目标函数或约束条件中有一个或几个非线性函数的最优化问题的方法。运筹学的一个重要分支。2

【C++学习笔记 20】C++中的智能指针

智能指针的功能 在上一篇笔记提到了在栈和堆上创建变量的区别,使用new关键字创建变量时,需要搭配delete关键字销毁变量。而智能指针的作用就是调用new分配内存时,不必自己去调用delete,甚至不用调用new。 智能指针实际上就是对原始指针的包装。 unique_ptr 最简单的智能指针,是一种作用域指针,意思是当指针超出该作用域时,会自动调用delete。它名为unique的原因是这个

vue2 组件通信

props + emits props:用于接收父组件传递给子组件的数据。可以定义期望从父组件接收的数据结构和类型。‘子组件不可更改该数据’emits:用于定义组件可以向父组件发出的事件。这允许父组件监听子组件的事件并作出响应。(比如数据更新) props检查属性 属性名类型描述默认值typeFunction指定 prop 应该是什么类型,如 String, Number, Boolean,

查看提交历史 —— Git 学习笔记 11

查看提交历史 查看提交历史 不带任何选项的git log-p选项--stat 选项--pretty=oneline选项--pretty=format选项git log常用选项列表参考资料 在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。 完成这个任务最简单而又有效的 工具是 git log 命令。 接下来的例子会用一个用于演示的 simplegit

记录每次更新到仓库 —— Git 学习笔记 10

记录每次更新到仓库 文章目录 文件的状态三个区域检查当前文件状态跟踪新文件取消跟踪(un-tracking)文件重新跟踪(re-tracking)文件暂存已修改文件忽略某些文件查看已暂存和未暂存的修改提交更新跳过暂存区删除文件移动文件参考资料 咱们接着很多天以前的 取得Git仓库 这篇文章继续说。 文件的状态 不管是通过哪种方法,现在我们已经有了一个仓库,并从这个仓

忽略某些文件 —— Git 学习笔记 05

忽略某些文件 忽略某些文件 通过.gitignore文件其他规则源如何选择规则源参考资料 对于某些文件,我们不希望把它们纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。通常它们都是些自动生成的文件,比如日志文件、编译过程中创建的临时文件等。 通过.gitignore文件 假设我们要忽略 lib.a 文件,那我们可以在 lib.a 所在目录下创建一个名为 .gi