ARM体系结构及接口技术-05ARM通讯接口

ARM通讯接口

串行通信的基本概念

  • 在通信领域内,有两种数据通信方式:并行通信和串行通信
  • 串口的数据传输是以串行方式进行的。
  • 串口在数据通信中,一次只传输一个比特的数据。
  • 串行数据的传输速度用bps或波特率来描述。

串行通信涉及的常用术语(单工、半双工和全双工,异步方式与同步方式)

  • 单工(Simplex)
    特点:仅能进行一个方向的数据传送
  • 半双工(Half Duplex)
    特点:数据可以在两个方向上进行传送,但是这种传送绝不能同时进行
  • 全双工(Full Duplex)
    特点:能够在两个方向同时进行数据传送
    数据传输率
    每秒传输的二进制位数,单位为bps(bit per second )也称比特率

多根数据线 地址线,如内存

  • 同步通信方式( Synchronous )所用的数据格式没有起始位、停止位,一次传送的字符个数可变。在传送前,先按照一定的格式将各种信息装配成一个包,该包包括供接收方识别用的同步字符一个或两个,其后紧跟着要传送的n个字符,再后就是校验字符。
  • 异步方式(Asynchronous):也称“起止同步式”。
    在这里插入图片描述

协议举例

  1. 串行通讯

    双线 uart (全双工 异步)
    在这里插入图片描述
    双线 i2c (半双工 同步)
    在这里插入图片描述
    三线 spi (全双工 同步)
    在这里插入图片描述

  • 串口通信接收端通过循环检测高低电平来读取数据。若频率太高,波形就会变窄,接收端误识别几率就会增大
  • 所以同步通信引入了时钟线。同步通信速度较异步高
  1. 并行通讯:多根数据线 地址线,如内存
  • 硬件流控制
    如果打开串口硬件流控制后,串口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, 

    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) }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值