ARM裸机开发:串口通信

ARM裸机开发:串口通信
一、硬件平台:
正点原子I.MX6U阿尔法开发板

二、原理分析
2.1 UART 介绍
UART 全称是 UniversalAsynchronous Receiver/Trasmitter,异步串行收发器

USART 的全称是 Universal Synchronous/Asynchronous Receiver/Transmitter,同步/异步串行收发器。相比 UART 多了 一个同步的功能,在硬件上体现出来的就是多了一条时钟线

UART 作为串口的一种,其工作原理也是将数据一位一位的进行传输,发送和接收各用一条线,连接方式如下:

因为 UART 没有时钟线做同步,所以是异步收发器,必须有起止位,其通信位如下:

各位的含义如下:

位    功能
空闲位    数据线在空闲状态的时候为逻辑“1”状态,也就是高电平,表示没有数据线空闲,没有数据传输
起始位    当要传输数据的时候先传输一个逻辑“0”,也就是将数据线拉低,表示开始数据传输
数据位    数据位就是实际要传输的数据,数据位数可选择 5~8 位,我们一般都是按照字节传输数据的,一个字节 8 位,因此数据位通常是 8 位的。低位在前,先传输,高位最后传输
奇偶校验位    这是对数据中“1”的位数进行奇偶校验用的,可以不使用奇偶校验功能
停止位    数据传输完成标志位,停止位的位数可以选择 1 位、1.5 位或 2 位高电平,一般都选择 1 位停止位
波特率    波特率就是 UART 数据传输的速率,也就是每秒传输的数据位数,一般选择 9600、19200、115200 等
每一位的 0 和 1 的硬件层表达就是串口的硬件层协议,目前主流的有 TTL 、RS232、RS485等不同电平的协议

TTL电平:高电平为 1,低电平为 0(低电平要小于0.8V,高电平要大于2.4V)

RS232电平:电平采用负逻辑,逻辑1的电平为-3~-15V,逻辑0的电平为+3~+15V

RS485电平:数据信号采用差分传输方式,接收端和发送端有不同的定义

对于发送器,逻辑1(正)是A>B, AB之间电压差为+2+6V,而逻辑0(负)是A<B,AB之间的电压差为-2-6V.
而对于接收器,则逻辑1(正)则是B>A,BA之间的电压不小于200mV,逻辑0则是A>B,BA之间的电压小于-200mv,即正负逻辑,电压绝对值都大于200mv
此处我们的串口物理层使用的是 TTL 电平

开发板上串口接口如下:

2.2 UART 寄存器
UART 控制寄存器 1

寄存器位    功能
ADBR(bit14):    自动波特率检测使能位,为 0 的时候关闭自动波特率检测,为 1 的时候使能自动波特率检测。
UARTEN(bit0):    UART 使能位,为 0 的时候关闭 UART,为 1 的时候使能 UART。
UART 的控制寄存器 2

寄存器位    功能
IRTS(bit14):    为 0 的时候使用 RTS 引脚功能,为 1 的时候忽略 RTS 引脚
PREN(bit8):    奇偶校验使能位,为 0 的时候关闭奇偶校验,为 1 的时候使能奇偶校验
PROE(bit7):    奇偶校验模式选择位,开启奇偶校验以后此位如果为 0 的话就使用偶校验,此位为 1 的话就使能奇校验
STOP(bit6):    停止位数量,为 0 的话 1 位停止位,为 1 的话 2 位停止位。
WS(bit5):    数据位长度,为 0 的时候选择 7 位数据位,为 1 的时候选择 8 位数据位。
TXEN(bit2):    发送使能位,为 0 的时候关闭 UART 的发送功能,为 1 的时候打开 UART的发送功能。
RXEN(bit1):    接收使能位,为 0 的时候关闭 UART 的接收功能,为 1 的时候打开 UART 的接收功能。
SRST(bit0):    软件复位,为 0 的是时候软件复位 UART,为 1 的时候表示复位完成。复位完成以后此位会自动置 1,表示复位完成。此位只能写 0,写 1 会被忽略掉
UARTx_UCR3 寄存器

就用到了寄存器 UARTx_UCR3 中的位 RXDMUXSEL(bit2),这个位应该始终为 1

UARTx_USR2 状态寄存器 2

寄存器位    功能
TXDC(bit3):    发送完成标志位,为 1 的时候表明发送缓冲(TxFIFO)和移位寄存器为空,也就是发送完成,向 TxFIFO 写入数据此位就会自动清零。
RDR(bit0):    数据接收标志位,为 1 的时候表明至少接收到一个数据,从寄存器
UARTx_URXD    读取数据接收到的数据以后此位会自动清零
寄存器 UARTx_UFCR 、 UARTx_UBIR 和 UARTx_UBMR

UARTx_UFCR 中我们要用到的是位 RFDIV(bit9:7),用来设置参考时钟分频:

UART 的波特率计算公式

公式含义如下:

Ref Freq: 经过分频以后进入 UART 的最终时钟频率

UBMR: 寄存器 UARTx_UBMR 中的值

**UBIR: ** 寄存器 UARTx_UBIR 中的值

2.3 UART 使用步骤
设置 UART1 的时钟源
设置 UART 的时钟源为 pll3_80m,设置寄存器 CCM_CSCDR1 的 UART_CLK_SEL 位为 0即可。
初始化 UART1
初始化 UART1 所使用 IO,设置 UART1 的寄存器 UART1_UCR1~UART1_UCR3,设置内容包括波特率,奇偶校验、停止位、数据位等等。
使能 UART1
UART1 初始化完成以后就可以使能 UART1 了,设置寄存器 UART1_UCR1 的位 UARTEN为 1。
编写 UART1 数据收发函数
编写两个函数用于 UART1 的数据收发操作
三、程序编写
工程还是在上一章工程基础上进行实现,创建 bsp_uart.c 和 .h 模块文件,这里直接使用正点原子代码
修改 Makefile 文件

CROSS_COMPILE     ?= arm-linux-gnueabihf-
TARGET              ?= bsp_uart

CC                 := $(CROSS_COMPILE)gcc
LD                := $(CROSS_COMPILE)ld
OBJCOPY         := $(CROSS_COMPILE)objcopy
OBJDUMP         := $(CROSS_COMPILE)objdump

LIBPATH            := -lgcc -L /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/lib/gcc/arm-linux-gnueabihf/4.9.4

INCDIRS         := imx6ul \
                   bsp/bsp_clk \
                   bsp/bsp_led \
                   bsp/bsp_delay\
                   bsp/bsp_beep\
                   bsp/bsp_key\
                   bsp/bsp_int\
                   bsp/bsp_exit\
                   bsp/bsp_gpio\
                   bsp/bsp_epit\
                   bsp/bsp_uart

SRCDIRS            := project \
                   bsp/bsp_clk \
                   bsp/bsp_led \
                   bsp/bsp_delay\
                   bsp/bsp_beep\
                   bsp/bsp_key\
                   bsp/bsp_int\
                   bsp/bsp_exit\
                   bsp/bsp_gpio\
                   bsp/bsp_epit\
                   bsp/bsp_uart

INCLUDE            := $(patsubst %, -I %, $(INCDIRS))

SFILES            := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))
CFILES            := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))

SFILENDIR        := $(notdir  $(SFILES))
CFILENDIR        := $(notdir  $(CFILES))

SOBJS            := $(patsubst %, obj/%, $(SFILENDIR:.S=.o))
COBJS            := $(patsubst %, obj/%, $(CFILENDIR:.c=.o))
OBJS            := $(SOBJS) $(COBJS)

VPATH            := $(SRCDIRS)
.PHONY: clean

$(TARGET).bin : $(OBJS)
    $(LD) -Timx6ul.lds -o $(TARGET).elf $^ $(LIBPATH)
    $(OBJCOPY) -O binary -S $(TARGET).elf $@
    $(OBJDUMP) -D -m arm $(TARGET).elf > $(TARGET).dis

$(SOBJS) : obj/%.o : %.S
    $(CC) -Wall -nostdlib -fno-builtin -c -O2  $(INCLUDE) -o $@ $<

$(COBJS) : obj/%.o : %.c
    $(CC) -Wall -nostdlib -fno-builtin -c -O2  $(INCLUDE) -o $@ $<

clean:
    rm -rf $(TARGET).elf $(TARGET).dis $(TARGET).bin $(COBJS) $(SOBJS)


Makefile 文件在链接的时候加入了数学库, 因为在 bsp_uart.c 中有个函数 uart_setbaudrate,在此函数中使用到了除法运算,因此在链接的时候需要将编译器的数学库也链接进来,的变量LIBPATH就是数学库的目录

编译指令处加入了选项“-fno-builtin”,否则编译的时候提示“putc”、“puts” 这两个函数与内建函数冲突

编译通过,下载程序到SD卡

四、实验现象
连接串口,设置波特率 115200


————————————————
版权声明:本文为CSDN博主「Top嵌入式」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_45396672/article/details/121503040

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值