《嵌入式硬件(十五):基于IMX6ULL的统一异步收发器(UART)的操作》
一、UART的基本概念
该UART具备以下特性:
1.高速TIA/EIA-232-F兼容,速率高达5.0 Mbit/s
2.低速串行红外接口,兼容IrDA标准(最高115.2 Kbit/s)
3.支持9位或多机通信模式(RS-485),含自动从机地址检测
4.RS-232字符格式支持7或8位数据位,RS-485支持9位格式
5.可配置1或2位停止位
6.可编程校验(奇校验、偶校验、无校验)
7.两组DMA请求(发送FIFO DMA请求与接收FIFO DMA请求)
连接方法:
发送接发送,接收接接收,进行数据传递
发送接接收,接收接发送,不是传递,是直接接收
二、原理
1.底板原理图
2.接收寄存器(URXD)
3.发送寄存器(UTXD)
4.控制寄存器(UCR1)
5.控制寄存器(UCR2)
6.控制寄存器(UCR3)
7.缓冲区控制寄存器(UFCR)
8.状态寄存器(USR2)
9.(UBIR)
10.(UBMR)
11.复用功能
三、波特率设置
tips波特率计算:
其中RefFreq参考频率,80;BaudRate,实际要设置的波特率,115200
可得UBIR = 999,UBIR = 43402;(不唯一)
1.80M的设置方法
第零位是控制主路旁路
当他为零的时候,刚好是主路,所以不用设置
2.选通门设置
第六位
为0的时候是主路
3.分频器设置
CSCDR1第0~5位为0时,默认一分频
四、代码
1.uart.c
#include "uart.h"
#include "fsl_iomuxc.h"
#include "MCIMX6Y2.h"void init_uart1(void)
{IOMUXC_SetPinMux(IOMUXC_UART1_TX_DATA_UART1_TX, 0);IOMUXC_SetPinMux(IOMUXC_UART1_RX_DATA_UART1_RX, 0);IOMUXC_SetPinConfig(IOMUXC_UART1_TX_DATA_UART1_TX, 0x10B0);IOMUXC_SetPinConfig(IOMUXC_UART1_RX_DATA_UART1_RX, 0x10B0);UART1->UCR1 = 0;UART1->UCR2 &= ~(1 << 0);unsigned int t;t = UART1->UCR2;t |= (1 << 14);t &= ~(1 << 8);t &= ~(1 << 6);t |= (1 << 5);t |= (1 << 2) | (1 << 1);UART1->UCR2 = t;UART1->UCR3 |= (1 << 2);t = UART1->UFCR;t &= ~(7 << 7);t |= (5 << 7);UART1->UFCR = t;UART1->UBIR = 999;UART1->UBMR = 43402;UART1->UCR1 |= (1 << 0);}void putc(unsigned char ch)
{while((UART1->USR2 & (1 << 3)) == 0);UART1->UTXD = ch;
}void puts(const char *p)
{while(*p){putc(*p++);}
}unsigned char getc(void)
{while((UART1->USR2 & (1 << 0)) == 0);return UART1->URXD & 0xFF;//只保留低位
}
2.uart.h
#ifndef _UART_H_
#define _UARE_H_extern void init_uart1(void);
extern void putc(unsigned char ch);
extern void puts(const char *p);
extern unsigned char getc(void);#endif
3.main.c
#include "beep.h"
#include "led.h"
#include "key.h"
#include "MCIMX6Y2.h"
#include "core_ca7.h"
#include "gpio.h"
#include "interrupt.h"
#include "clock.h"
#include "epit.h"#include "gpt.h"
#include "delay.h"#include "uart.h"int main(void)
{init_clock();system_interrupt_init();init_led();init_beep();//init_epit();int_gpt1(); init_uart1(); while(1){//puts("hello world!");//putc('A');//delayms(1000);unsigned char c;c = getc();if(c == 'A'){puts("Hello");}else if(c == 'K'){puts("world!");}else{puts("error");}}return 0;
}
必须先写UBIR,在写UBMR
五、移植printf,scanf
1.在工程中添加stdio文件
2.修改Makefile
target = uartcross_compiler = arm-linux-gnueabihf-cc = $(cross_compiler)gcc
ld = $(cross_compiler)ld
objcopy = $(cross_compiler)objcopy
objdump = $(cross_compiler)objdumpincdirs = bsp imx6ull stdio/include
srcdirs = bsp project stdio/libinclude = $(patsubst %, -I%, $(incdirs))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/cfiles = $(foreach dir, $(srcdirs), $(wildcard $(dir)/*.c))
sfiles = $(foreach dir, $(srcdirs), $(wildcard $(dir)/*.S))cfilenodir = $(notdir $(cfiles))
sfilenodir = $(notdir $(sfiles))cobjs = $(patsubst %, obj/%, $(cfilenodir:.c=.o))
sobjs = $(patsubst %, obj/%, $(sfilenodir:.S=.o))objs = $(cobjs) $(sobjs)VPATH = $(srcdirs)$(target).bin : $(objs)$(ld) -Timx6ull.lds -o$(target).elf $^ $(libpath)$(objcopy) -O binary -S -g $(target).elf $@$(objdump) -D $(target).elf > $(target).dis$(sobjs) : obj/%.o : %.S@mkdir -p obj$(cc) -Wa -Wall,-mimplict-it=thumb fno-builtin -nostdlib -c $(include) -o $@ $<$(cobjs) : obj/%.o : %.c@mkdir -p obj $(cc) -Wa -Wall,-mimplict-it=thumb fno-builtin -nostdlib -c $(include) -o $@ $<.PHONY : clean
clean:rm -rf $(objs) $(target).elf $(target).bin $(target).dis
3.修改错误
此时直接编译,会报错,只需要在uart.c里面加
void raise(void)
{}
示例:
#include "stdio.h"int main(void)
{init_clock();system_interrupt_init();init_led();init_beep();//init_epit();int_gpt1(); init_uart1(); while(1){int i,j;scanf("%d%d", &i, &j);printf("%d + %d = %d\n", i, j, i + j);}return 0;
}
结果:
六、数据类型大小以及大小端验证
printf("%d\n", sizeof(int));printf("%d\n", sizeof(char));printf("%d\n", sizeof(short));printf("%d\n", sizeof(long));printf("%d\n", sizeof(long long));char i = 0;int j = 1;i = j;printf("%d\n", i);delayms(1000);
结论:
在I.MX6ULL下,int占4字节,char占1字节,short占2字节,long占4字节,longlong占8字节,并且是小段字节存储