ARM:UART串口异步通信驱动编程

发布者:独享留白1028最新更新时间:2017-09-21 来源: eefocus关键字:ARM  UART  串口  异步通信 手机看文章 扫描二维码
随时随地手机看文章

1. 串口的基本概念
1.1 UART - 串行异步收发器 Universal Asynchronous Receiver/Transmitter
串行/并行(课后补充)
异步/同步:'异步/同步通信两者之间的区别' (补充)
'单工/半双工/全双工:
单工:任何时候数据只能朝一个方向传输
半双工:数据可以向两个方向传输,任何同一时刻只能朝同一方向传输
全双工:数据可以同时向两个方向传输
1.2 串口通信标准
RS232 (电子工业协议EIA) - 目前最常用的'串行接口标准'
规定了'电气特性':
逻辑 0 ,+3 v ~ +15 v,SPACE
逻辑 1 ,- 3 v ~ - 15 v,MARK
规定了'机械特性':
传输距离 < 10 m
TTL电平,计算机内部电平(CPU):
逻辑 0 ,低电平 < 0.8 v
逻辑 1 ,高电平 > 2.4 v
串行异步通信的重要参数:
>>数据位个数: 5 ~ 8 bit  (开发板那端定好的是 8 bit / 帧数据)
>>验证方式:奇校验、偶校验、无校验
>>停止位宽度:1~2bit
>>通信的速率:bps (bit per second - 每秒传输bit位)'波特率单位'

2. 电路原理图
【底板】
             |---SP3232E电平转换芯片---|
PC_TXD1 ---> T2OUT ---> T2IN ---> UARTTXD0 ---> 'GPIOD18
PC_RXD1 ---> R2IN ---> R2OUT ---> UARTRXD0 ---> 'GPIOD14
完成串口通信有两种方式:
1) 一种方式:运行在arm core的程序和LED一样直接操作GPIO管脚,形成串行异步收发数据的时序。
2) 另一方式:S5P6818中集成了uart控制器,方式 1)纯软件实现通信的过程就可以使用软硬件结合的方式来实现通信时序,从而简化软件编程。

问题:
uart控制器可以完成哪些工作,还需软件做哪些工作,两者之间如何配合?
答案:CPU的数据手册中关于uart的相关章节

3. CPU datasheet
3.1 管脚的功能选择
--->P 71 - 2.3
GPIOD18 - Function1
GPIOD14 - Function1
--->P 757 - 16.5.1.8
GPIODALTFN0 - 0xc001d020 - [29:28] - 01=ALT Function1
GPIODALTFN1 - 0xc001d020 - [ 5 : 4 ] - 01=ALT Function1
3.2 uart 控制器
--->P 960 - 25.1
' S5P6818串行异步收发器 UART 单元特点:
1) 提供 6 个独立的uart控制器
2) 数据传输可以使用轮询、中断、DMA方式
3) 采用系统时钟时最大传输速率 4 Mbps   // 采用外部时钟时可以达更大速率
4) 每个UART通道有两个 64 bytes FIFO供发送和接收数据,以提供较高效率
5) 可编程波特率、红外发送接收、1~2个停止位、5~8位数据宽度、奇偶校验

问题:
COM1对应的是CPU内部的哪个uart控制器?
答案:
根据COM1使用的是CPU上的GPIOD14、GPIOD18,推断对应的是CPU内部的'UART0'。

知识点:
'CPU感知外接硬件变化通常有3种方式:
1> 轮询; 
// 定时对各种设备轮流询问一遍有无处理要求,有要求就处理,处理完回归CPU日常工作。- 适合硬件变化频繁的状况
2> 中断; 
// 当有硬件设备处理要求是,CPU启动输入输出设备存档准备数据,I/O完成发出中断信号,接收中断处理数据,随后某个时刻继续工作。 - 适合硬件变化不是特别频繁的状况
3>DMA;
// 直接内存存取,direct memory access,数据在内存与I/O设备间直接进行成块传输。

'【UART控制器重要参数】
non-FIFO - 115200 - 8 - None - 1 - 轮询mode

ULCON0 - 0xc00a1000 - R/W
- [ 1 : 0 ] - 11 , 8 bit - 数据宽word lenth
- [ 2 ] - 0 , 1 bit - 停止位number of stop bit
- [ 5 : 3 ] - 000 - 无校验
- [ 6 ] - 0 - 红外正常模式

UCON0 - 0xc00a1004 - R/W
- [ 1 : 0 ] - 01 - 轮询接收 Receive Mode(Polling mode)
- [ 3 : 2 ] - 01 - 轮询发送 Transmit Mode(Polling mode)
- [ 5 ] - 01 - 设置轮询模式 Setting Loop-back mode

UFCON0 - 0xc00a1008 - R/W
- [ 0 ] - 0 - 禁用FIFO(non-FIFO) FIFO Disables

UTRSTAT0 - 0xc00a1010 - R
- [ 0 ] - 1 - 代表收到了数据 Buffer has a received data
- [ 1 ] - 0 / 1 - 0 代表 transmit buffer 非空, 1 代表空

UTXH0 - 0xc00a1020 - W
- [ 7 : 0 ] - 写入要发送的数据 Transmit Data for UART0

URXH0 - 0xc00a1024 - R
- [ 7 : 0 ] - 读出接收到的数据 Receive Data for UART0

--->P 313 - 5.3.2.1.13 UARTCLKENB - '时钟源配置,地址数与UART对应
UARTCLKENB - 0xc00a9000 - R/W
- [ 2 ] - 1 - 使UART0时钟使能 Enable

 UARTCLKGEN0L - 0xc00a9004 - R/W
- [ 4 : 2 ] - 1 - 时钟源频率选择 PLL[1]==800MHz(uboot中调为该频率)
- [12: 5 ] - 1111 1111 - 分频系数,提供给UART0的时钟信号 50 MHz
// 1M==100万,800M==8亿,1111==0x0f,800MHz(0x0f+1)=50MHz

--->P 986 - 25.4.1.11/25.4.1.12 - '用于分频,将输入的50MHz分频成适合每秒钟发送115200个bit所需要的时钟信号
UBRDIV0 - 0xc00a1028 - R/W - 经计算取值为 26
UFRACVAL0 - 0xc00a102c - R/W - 经计算取值为 2

--->P 969 - For example // 设置方法示例


  1. /* 手册定好的计算方式,不需要问为什么,直接套公式即可。 

  2. DIV_VAL = (40000000/(115200 x 16))  –  1 

  3. = 21.7 – 1 

  4. = 20.7 

  5. UBRDIVn = 20 (integer part of DIV_VAL) 

  6. UFRACVALn/16 = 0.7  

  7. So, UFRACVALn = 11 

  8. */  

50000000 / (115200 * 16) - 1 = 27.13 - 1 = 26.13 = 26 【==UBRDIV0】
0.13 * 16 = 2.08 = 2 【==UFRACVAL0】

【汇总】S5P6818UART相关寄存器
1) UART行控制器ULCONn - 设置数据格式
2) UART模式控制寄存器UCONn - 用来选择时钟源,发送/接收数据可选轮询
3) UART FIFO控制寄存器UFCONn
4) UART MODEM控制寄存器UMCONn
5) 发送寄存器UTXH、接收寄存器URXH
6) 波特率分频寄存器UBRDIV,UFRACVAL
7) GPIO相关寄存器
8) 中断相关寄存器
9) 时钟、电源控制寄存器


4. 编码


  1. /** 代码演示 - main.c **/  

  2. #include "uart.h"  

  3. void main (void) {  

  4.     // 8N1 115200 non-FIFO polling  

  5.     uart_init ( );  

  6.     while (1) {  

  7.         uart_puts ("\n hello,world!");  

  8.     }     

  9. }  


  1. /** 代码演示 - uart.c **/  

  2. #define UART0CLKENB     *((volatile unsigned int*)0xc00a9000)  

  3. #define UART0CLKGEN0L   *((volatile unsigned int*)0xc00a9004)  

  4.   

  5. #define GPIOD_ALTFN0    *((volatile unsigned int*)0xc001d020)  

  6. #define GPIOD_ALTFN1    *((volatile unsigned int*)0xc001d024)  

  7. #define GPIOD_PULLENB   *((volatile unsigned int*)0xc001d060)  

  8.   

  9. #define ULCON0          *((volatile unsigned int*)0xc00a1000)  

  10. #define UCON0           *((volatile unsigned int*)0xc00a1004)  

  11. #define UFCON0          *((volatile unsigned int*)0xc00a1008)  

  12. #define UTRSTAT0        *((volatile unsigned int*)0xc00a1010)  

  13. #define UTXH0           *((volatile unsigned int*)0xc00a1020)  

  14. #define URXH0           *((volatile unsigned int*)0xc00a1024)  

  15. #define UBRDIV0         *((volatile unsigned int*)0xc00a1028)  

  16. #define UFRACVAL0       *((volatile unsigned int*)0xc00a102c)  

  17. void uart_init (void) {  

  18.     /* uart0 clk disable */  

  19.     UART0CLKENB &= ~(1 << 2);  

  20.     // GPIOD18(Tx 接收管脚) GPIOD14(Rx 发送管脚) 配置功能Function1  

  21.     GPIOD_ALTFN0 &= ~(3 << 28); // GPIOD14  

  22.     GPIOD_ALTFN0 |= (1 << 28);  

  23.     GPIOD_ALTFN1 &= ~(3 << 4); // GPIOD18  

  24.     GPIOD_ALTFN1 |= (1 << 4);  

  25.     // 时钟配置:选择PLL[1] 800MHz  

  26.     UART0CLKGEN0L &= ~(7 << 2);  

  27.     UART0CLKGEN0L |= (1 << 2);  

  28.     // 分频设置 800/(0x0f+1)=50MHz  

  29.     UART0CLKGEN0L &= ~(0xff << 5); // [12:5] 8个位  

  30.     UART0CLKGEN0L |= (0xf << 5); // [12:5] 4个位设置为1111  

  31.     // UART控制器设置  

  32.     ULCON0  = 0x03; // 8N1  

  33.     UCON0   = 0x05; // 0101 == 0x05 polling  

  34.     UFCON0 &= ~(1 << 0); // non-FIFO disable  

  35.     UBRDIV0 = 26; // 50000000/(115200*16) - 1 == 26.13  

  36.     UFRACVAL0 = 2; // 0.13*16 == 2.08  

  37.     /* uart0 clk enable */  

  38.     UART0CLKENB |= (1 << 2);  

  39. }  

  40. void uart_putc (char c) {  

  41.     // UTRSTAT0 bit[1] == 1, 缓存寄存器为empty  

  42.     // 轮询是否为空  

  43.     while (! (UTRSTAT0 & 0x02)); // !(空) 什么都不干。  

  44.     UTXH0 = c;  

  45.     if (c == '\n')  

  46.         uart_putc ('\r');  

  47. }  

  48. void uart_puts (char* str) {  

  49.     if (! str)  

  50.         return ;  

  51.   

  52.     while (*str) {  

  53.         uart_putc (*str);  

  54.         str++;  

  55.     }  

  56. }  


  1. /** 代码演示 - uart.h **/  

  2. #ifndef _UART_H_  

  3. #define _UART_H_  

  4.   

  5. extern void uart_init (void);  

  6. extern void uart_puts (char*);  

  7.   

  8. #endif //_UART_H_  

5. 编译

$:' arm-cortex_a9-linux-gnueabi-gcc -c -nostdlib main.c -o main.o
$:' arm-cortex_a9-linux-gnueabi-gcc -c -nostdlib uart.c -o uart.o
$:' arm-cortex_a9-linux-gnueabi-ld -nostdlib -nostartfiles -Ttext=48000000 -emain main.o uart.o -o uart      // 注意.o文件顺序
$:' arm-cortex_a9-linux-gnueabi-objcopy -O binary uart uart.bin
6. 运行
$:' sudo cp uart.bin /tftpboot/
X6818#:' tftp 48000000 uart.bin
X6818#:' go 48000000


关键字:ARM  UART  串口  异步通信 引用地址:ARM:UART串口异步通信驱动编程

上一篇:STM32:Keil MDK(uVision v4.10)开发环境搭建
下一篇:STM32经验心得(一)

推荐阅读最新更新时间:2024-03-16 15:37

“节能之星”EFM32应用方案——手持式激光测距仪
概述 随着现代科技的发展以及人们生活水平的提高,便携式 激光测距 仪在各行各业中都有广泛的应用,如建筑业,高尔夫,行车速度与车距测量。激光是一种电磁波,具有方向性强、单色性好、相干性好、亮度高等特性,使其成为测距的首选电磁波。 目前常用的激光测距方法主要有: 1、 脉冲测距法:利用 脉冲激光器 发射单次激光脉冲或激光脉冲串,测量激光脉冲到达目标并由目标返回到接收器的往返时间,由此运算目标距离。此方法误差较大,适用于远距离测量。 2、 干涉测距法:利用光的干涉原理,通过测量激光发射与接收这间的干涉条纹来测量距离。此方法精度非常高,但只能测量相对距离,不能测量绝对距离。 3、 相位式测距法:采用连续调制的激光光束照
[电源管理]
“节能之星”EFM32应用方案——手持式激光测距仪
STM32笔记 (九)串口通讯USART(串口发送接收编程)
简介 串口USART(Universal Synchronous Asynchronous Receiver and Transmitter)也叫通用同步异步收发器,是单片机与外部进行信息交互的重要通信接口,属于单片机的一种外设,几乎所有单片机都支持使用串口通讯,同时也是单片机程序调试的一种重要手段,对于STM32,串口资源非常丰富,功能也比较齐全,以STM32F103ZET6为例,就提供了5路的串口,我们一般用把串口用来在电脑的串口调试工具上打印调试信息,从而了解程序运行是否正确、如果出错的话也能知道是哪里出了错误。 通讯的有关概念 并行通讯 并行就是采用多条数据线进行通讯 优点是传输速度快,缺点是占用的引脚资源多 串行
[单片机]
STM32笔记 (九)<font color='red'>串口</font>通讯USART(<font color='red'>串口</font>发送接收编程)
MSP430F5438学习笔记 UART ACLK 9600-8-N-1
1.初始化UART0之前需要先初始化ACLK、SMCLK和MCLK。示例代码中使用XT1,ACLK为32768,SMCLK和MCLK约为8MHZ。 2.UART的时钟可以参考ACLK或者SMCLK,本例参考ACLK。由于参考ACLK时钟,所以串口速率不能超过32768。选择9600较为合适。 3.MSP430波特率的产生有两种模式,低频波特率产生和过采样波特率产生。代码中使用低频波特率产生。 4.代码的开头调用了stdio,在函数中宏重写了putchar函数,定向到UART单字节输出。 5.代码初始化之后输出 Hello MSP430,随后直接反射串口接收到的数据,例如发送123456即返回123456。 /
[单片机]
STM32 HAL 库, 配置串口DMA接收及空闲中断
1、 使用CUBEMX 配置自动生成代码: ①添加串口的DMA 通道 ②使用串口全局中断: 其他的配置就不详细说了。 生成代码后, 打开工程在串口初始化函数中添加代码: /* USART1 init function */ void MX_USART1_UART_Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Pari
[单片机]
arm 64位实时处理器Cortex-R82,5nm工艺,性能高达5.82 MHz
虽然Arm的芯片部门存在被出售的可能,但Arm公司的技术人员并没有停下脚步。 本周,Arm推出了其首款64位实时处理器,这是其Cortex-R系列的最新产品,其中包括Linux支持以及对企业存储应用的重视。该策略反映了使处理和分析更接近数据的日益增长的需求。 64位Cortex-R82添加了“计算存储”(computational storage)功能,例如通过内存管理选件支持Linux微服务和云本机软件开发。它还满足了解决更大内存容量的需求,该公司表示,这正在成为运行Linux或新兴计算存储设备时性能的障碍。 Arm指出:“计算存储就是使存储设备更智能,以便直接在存储数据的地方处理数据。” 根据工作负载测试
[嵌入式]
<font color='red'>arm</font> 64位实时处理器Cortex-R82,5nm工艺,性能高达5.82 MHz
Arm推出平台安全架构PSA为万亿互联设备建立行业通用框架
新闻要点: Arm全新的平台安全架构(PSA) 为互联设备定义安全基础 广受行业领先的云服务、硬件和芯片供应商支持 开源的Arm Trusted Firmware-M将支持PSA规范 全新安全IP提升基于Arm Cortex处理器的IoT芯片的安全性 Arm今日宣布推出首个行业通用框架——平台安全架构(PSA,Platform Security Architecture),用以打造安全的互联设备。该举措将为万物互联奠定可信基础,从而加速实现“2035年全球一万亿设备互联”的宏伟愿景。 实现该项愿景,不仅需要人们具备更多保护设备安全方面的知识,还需要人们信任科技行业正在竭尽所能地保护数据。这并非易事,因为这需要与黑客不断较量,而他们
[嵌入式]
<font color='red'>Arm</font>推出平台安全架构PSA为万亿互联设备建立行业通用框架
错误解决:STM32F103串口1与串口3相同代码却结果不同
在前几天调试openmv时发现同样的代码串口1和串口3的结果却是不一样的,当时着实是把我坑了很久,怎么都找不到原因,用示波器看波形也是没有问题的,在Openedv网站上有位网友指出是我初始化代码的问题,在翻阅参考手册后终于发现了问题。 下列代码为我原本的初始化代码: #include sys.h #include usart.h #include led.h #include usart3.h int theta_err,rho_err; int main(void) { Stm32_Clock_Init(9); //=====系统时钟设置 delay_init(72); /
[单片机]
错误解决:STM32F103<font color='red'>串口</font>1与<font color='red'>串口</font>3相同代码却结果不同
CAN转串口转换器在汽车行业中的应用场景
CAN转串口转换器在汽车行业中具有广泛的应用。以下是一些主要的应用场景: (1)车辆诊断和调试:汽车制造商和维修技师经常需要诊断和调试车辆的各种系统。CAN转串口转换器可以将车辆的CAN总线数据转换为串口数据,使得通过普通的串口通信工具就可以读取和分析这些数据,从而进行故障排查和系统优化。 (2)车辆网络和娱乐系统的集成:现代汽车通常配备有复杂的车辆网络和娱乐系统,这些系统通常通过CAN总线进行通信。CAN转串口转换器可以用于将这些系统与外部设备或系统进行集成,例如连接智能手机、导航设备或其他车载电子设备。 (3)车辆测试和验证:在汽车开发过程中,对车辆的各种系统和功能进行测试和验证是非常重要的。CAN转串口转换器可以帮助开发人员
[嵌入式]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved