ARM体系结构及接口技术-05ARM通讯接口
2019-06-03 22:31
169 查看
版权声明: https://blog.csdn.net/Set_Mode/article/details/90760327
串口 UART 协议 Exynos4412 UART接口功能模块 Exynos4412 相关寄存器 UART 编程
文章目录
ARM通讯接口
串行通信的基本概念
- 在通信领域内,有两种数据通信方式:并行通信和串行通信
- 串口的数据传输是以串行方式进行的。
- 串口在数据通信中,一次只传输一个比特的数据。
- 串行数据的传输速度用bps或波特率来描述。
串行通信涉及的常用术语(单工、半双工和全双工,异步方式与同步方式)
- 单工(Simplex)
特点:仅能进行一个方向的数据传送 - 半双工(Half Duplex)
特点:数据可以在两个方向上进行传送,但是这种传送绝不能同时进行 - 全双工(Full Duplex)
特点:能够在两个方向同时进行数据传送
数据传输率
每秒传输的二进制位数,单位为bps(bit per second )也称比特率
多根数据线 地址线,如内存
- 同步通信方式( Synchronous )所用的数据格式没有起始位、停止位,一次传送的字符个数可变。在传送前,先按照一定的格式将各种信息装配成一个包,该包包括供接收方识别用的同步字符一个或两个,其后紧跟着要传送的n个字符,再后就是校验字符。
- 异步方式(Asynchronous):也称“起止同步式”。
协议举例
-
串行通讯
双线 uart (全双工 异步)
双线 i2c (半双工 同步)
三线 spi (全双工 同步)
- 串口通信接收端通过循环检测高低电平来读取数据。若频率太高,波形就会变窄,接收端误识别几率就会增大
- 所以同步通信引入了时钟线。同步通信速度较异步高
- 并行通讯:多根数据线 地址线,如内存
- 硬件流控制
如果打开串口硬件流控制后,串口A只有在nCTS被(串口B的nRTS)激活后才能把数据发送出去;
当串口A可以接收数据时,激活nRTS
串口 UART 协议
Exynos4412 UART接口功能模块
Exynos4412 相关寄存器
UART 编程
main.c
/* 功能:修改代码,实现除com2口外的别的一个com口输出字符显示 */ #define GPA1CON (*(volatile unsigned int *)0x11400020) //volatile 确保本条指令不会因编译器的优化而省略 #define ULCON2 (*(volatile unsigned int *)0x13820000) //串口2线控:数据位,停止位,奇偶校验位 #define UCON2 (*(volatile unsigned int *)0x13820004) //串口2读取控制:串口读的方式(如:轮询/中断等),写的方式 #define UBRDIV2 (*(volatile unsigned int *)0x13820028) //串口2波特率设置 #define UFRACVAL2 (*(volatile unsigned int *)0x1382002c) //串口2波特率设置 #define UTXH2 (*(volatile unsigned int *)0x13820020) //串口2发送缓存器 #define URXH2 (*(volatile unsigned int *)0x13820024) //串口2接受缓存器 #define UTRSTAT2 (*(volatile unsigned int *)0x13820010) //串口2状态寄存器 #define GPA0CON (*(volatile unsigned int *)0x11400000) //volatile 确保本条指令不会因编译器的优化而省略 #define ULCON0 (*(volatile unsigned int *)0x13800000) //串口0线控:数据位,停止位,奇偶校验位 #define UCON0 (*(volatile unsigned int *)0x13800004) //串口0读取控制:串口读的方式(如:轮询/中断等),写的方式 #define UBRDIV0 (*(volatile unsigned int *)0x13800028) //串口0波特率设置 #define UFRACVAL0 (*(volatile unsigned int *)0x1380002c) //串口0波特率设置 #define UTXH0 (*(volatile unsigned int *)0x13800020) //串口0发送缓存器 #define URXH0 (*(volatile unsigned int *)0x13800024) //串口0接受缓存器 #define UTRSTAT0 (*(volatile unsigned int *)0x13800010) //串口0状态寄存器 #define ULCON3 (*(volatile unsigned int *)0x13830000) //串口3线控:数据位,停止位,奇偶校验位 #define UCON3 (*(volatile unsigned int *)0x13830004) //串口3读取控制:串口读的方式(如:轮询/中断等),写的方式 #define UBRDIV3 (*(volatile unsigned int *)0x13830028) //串口3波特率设置 #define UFRACVAL3 (*(volatile unsigned int *)0x1383002c) //串口3波特率设置 #define UTXH3 (*(volatile unsigned int *)0x13830020) //串口3发送缓存器 #define URXH3 (*(volatile unsigned int *)0x13830024) //串口3接受缓存器 #define UTRSTAT3 (*(volatile unsigned int *)0x13830010) //串口3状态寄存器 typedef enum { DEVICE_UART_COM0 = 0, DEVICE_UART_COM1 = 1, 1caa8 DEVICE_UART_COM2 = 2, DEVICE_UART_COM3 = 3, MAX_DEVICE }DEVICE_LIST_E; /* 设置波特率为115200 //For example, if the Baud rate is 115200 bps and SCLK_UART is 100 MHz,UBRDIVn and UFRACVALn are: //DIV_VAL = (SCLK_UART/(bps * 16)) - 1 //DIV_VAL = (100000000/(115200 * 16)) – 1 //= 54.253 – 1 //= 53.253 //UBRDIVn = 53 (integer part of DIV_VAL) //UFRACVALn/16 = 0.253 //Therefore, UFRACVALn = 4 */ void USART_Init(DEVICE_LIST_E Device_type) { if(Device_type == DEVICE_UART_COM0) { //1.配置GPA0CON寄存器中的UART0 //GPA0_0 UART_0_RXD //GPA0_1 UART_0_TXD GPA0CON &= 0xffffff00; GPA0CON |= 0x00000022; //2.配置ULCON0寄存器 //串口0 8位数据位,1位停止位,无奇偶校验 ULCON0 &= 0Xffffffc0; ULCON0 |= 0x00000003; //3.配置UCON0寄存器 //通过轮询(polling)的模式读取串口数据 通过轮询(polling)的模式往串口写入数据数据 UCON0 &= 0xfffffff0; UCON0 |= 0x00000005; //4.设置波特率为115200 UBRDIV0 = 53; UFRACVAL0 = 4; } if(Device_type == DEVICE_UART_COM2) { GPA1CON &= 0xffffff00; GPA1CON |= 0x00000022; ULCON2 &= 0Xffffffc0; ULCON2 |= 0x00000003; UCON2 &= 0xfffffff0; UCON2 |= 0x00000005; UBRDIV2 = 53; UFRACVAL2 = 4; } if(Device_type == DEVICE_UART_COM3) { GPA1CON &= 0xff00ffff; GPA1CON |= 0x00220000; ULCON3 &= 0Xffffffc0; ULCON3 |= 0x00000003; UCON3 &= 0xfffffff0; UCON3 |= 0x00000005; UBRDIV3 = 53; UFRACVAL3 = 4; } } void putc(DEVICE_LIST_E Device_type, char c) { switch(Device_type) { case DEVICE_UART_COM0: while(1) { if(UTRSTAT0 && 0X02) break; } UTXH0 = c; break; case DEVICE_UART_COM1: break; case DEVICE_UART_COM2: while(1) { if(UTRSTAT2 && 0X02) break; } UTXH2 = c; break; case DEVICE_UART_COM3: while(1) { if(UTRSTAT3 && 0X02) break; } break; default: break; } } char getc(void) { while(1) { if(UTRSTAT0 && 0X01) break; } return URXH0; } int main(void) { DEVICE_LIST_E vDevice = DEVICE_UART_COM0; USART_Init(vDevice); char c; while(1) { c = getc(); delay1s(); putc(vDevice,c); delay1s(); } return 0; }
Makefile
all: arm-none-linux-gnueabi-gcc -fno-builtin -nostdinc -c -o start.o start.S arm-none-linux-gnueabi-gcc -fno-builtin -nostdinc -c -o main.o main.c arm-none-linux-gnueabi-ld start.o main.o -Tmap.lds -o uart.elf arm-none-linux-gnueabi-objcopy -O binary uart.elf uart.bin arm-none-linux-gnueabi-objdump -D uart.elf > uart.dis clean: rm -rf *.bak start.o main.o uart.elf uart.bin uart.dis
start.S
.global delay1s .text .global _start _start: b reset @0x00 ldr pc,_undefined_instruction @0x04 ldr pc,_software_interrupt ldr pc,_prefetch_abort ldr pc,_data_abort ldr pc,_not_used ldr pc,_irq ldr pc,_fiq _undefined_instruction: .word _undefined_instruction _software_interrupt: .word _software_interrupt _prefetch_abort: .word _prefetch_abort _data_abort: .word _data_abort _not_used: .word _not_used _irq: .word _irq _fiq: .word _fiq reset: ldr r0,=0x40008000 @设置异常向量表的启始地址为 0x40008000 mcr p15,0,r0,c12,c0,0 @ Vector Base Address Register init_stack: ldr r0,stacktop /*get stack top pointer*/ /********svc mode stack********/ mov sp,r0 sub r0,#128*4 /*512 byte for irq mode of stack*/ /****irq mode stack**/ msr cpsr,#0xd2 mov sp,r0 sub r0,#128*4 /*512 byte for irq mode of stack*/ /***fiq mode stack***/ msr cpsr,#0xd1 mov sp,r0 sub r0,#0 /***abort mode stack***/ msr cpsr,#0xd7 mov sp,r0 sub r0,#0 /***undefine mode stack***/ msr cpsr,#0xdb mov sp,r0 sub r0,#0 /*** sys mode and usr mode stack ***/ msr cpsr,#0x10 mov sp,r0 /*1024 byte for user mode of stack*/ b main delay1s: ldr r4,=0x1ffffff delay1s_loop: sub r4,r4,#1 cmp r4,#0 bne delay1s_loop mov pc,lr .align 4 /**** swi_interrupt handler ****/ stacktop: .word stack+4*512 .data stack: .space 4*512 .end
map.lds
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") /* 指定输出的文件格式 */ OUTPUT_ARCH(arm) /* 生成文件支持arm系列的CPU */ ENTRY(_start) /* 连接后的第一条指令所在的地址是_start */ SECTIONS /* 目标文件的摆放 */ { . = 0x40008000; /* 指定链接的起始地址 */ . = ALIGN(4); /* 指令的对齐 */ .text : /* 代码段的开始 */ { start.o(.text) /* start.o文件放在开始的位置 */ *(.text) /* 其他目标文件自动分配位置 */ } . = ALIGN(4); /* 代码的对齐*/ .data : { *(.data) } . = ALIGN(4); .bss : { *(.bss) } }
相关文章推荐
- ARM体系结构及接口技术-07ARM波形控制
- ARM体系结构及接口技术-06ARM异常处理过程,软中断
- arm体系结构和接口技术
- ARM体系结构及接口技术-03裸机开发
- 华数费用350元/年电视费,能够使用技术让所有用户华数接口进行打造成多用户电子自由协议通讯接口。
- 微机原理与接口技术之8086的编程结构
- JDBC之接口技术
- 数据库开发技术 数据库层次设计之层次结构
- 温故知新之进程间通讯技术(IPC)
- NFC---近场通讯技术
- 即时通讯中语音视频聊天后面的技术支持有哪些
- ARM体系结构与内核回顾(三)
- 移动通讯技术--CMWAP和CMNET的区别
- Calico 的网络结构是什么?- 每天5分钟玩转 Docker 容器技术(68)
- phprap中根据DB结构生成和表中属性命名相同的接口参数
- Calico 的网络结构是什么?- 每天5分钟玩转 Docker 容器技术(68)
- App接口【核心技术】
- 基于spring-cloud相关技术整合,实现接口调用、服务容错、动态路由配置等
- 论软件接口中几种底层通讯的实现
- Java 远程通讯技术及原理分析