ARM通讯接口-作业

修改代码,实现除com2口外的别的一个com口输出字符显示
(请视频演示及上传源码,1. 把你写的程序通过com2加载到内存中。2.然后执行 go 命令,允许该程序。3. 把串口线插到com0,观察现象)

解:本程序采用com0输出字符显示

1.1 .c代码

#define GPA0CON 	0x11400000
#define ULCON0 		0x13800000
#define UCON0 		0x13800004
#define UBRDIV0 	0x13800028
#define UFRACVAL0 	0x1380002c
#define UTXH0 		0x13800020
#define UTRSTAT0 	0x13800010

#define rGPA0CON 	(*(volatile unsigned int*)GPA0CON)
#define rULCON0 	(*(volatile unsigned int*)ULCON0)
#define rUCON0 		(*(volatile unsigned int*)UCON0)
#define rUBRDIV0 	(*(volatile unsigned int*)UBRDIV0)
#define rUFBRACVAL0 (*(volatile unsigned int*)UFBRACVAL0)
#define rUTXH0 		(*(volatile unsigned int*)UTXH0)
#define rUTRSTAT0 	(*(volatile unsigned int*)UTRSTAT0)

void uart_putc(char c);

int main(int argc, const char *argv[])
{
	/* 设置GPA0控制器为UART模式 */
	rGPA0CON &= ~(0xff<<0);   	//把寄存器的bit0~7全部清零
	rGPA0CON |= 0X22; 			//Rx,Tx
	/* 设置串口协议 */
	rULCON0 = 0x03; 			//0校验位 ,8数据位,1停止位
	rUCON0 = 0x05; 				//轮询模式
	/*
	 * 设置波特率:
	 *UART时钟信号源的值为:
	 *100Mhz= 100 000khz = 100 000 000hz
	 *本实验波特率值位115200,DIV_VAL = 100000000/(115200*16) -1 = 54.25 -1 = 53.25
	 *UBRDIVn = 53
	 *UFRACVALn/16 = 0.25 ----> UFRACVALn = 4
	 */
	rUBRDIV0 = 53; 				
	rUFRACVAL0 = 4;
	/* 发送状态判断 */	
	while(1)
	{
		uart_putc('c');
		delay1s();
	}

	return 0;
}


void uart_putc(char c)
{	
	while(!(rUTRSTAT0&0X02));
	rUTXH0 = c;
	return;
}

1.2 .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

1.3 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

1.4 map.lds文件

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")	/* 规定生成文件的版本号 */
OUTPUT_ARCH(arm)	/* 设置输出文件的架构体系为arm架构 */
ENTRY(_start)	/* 设置入口点为_start */
SECTIONS	/* 段落 */
{
	. = 0x40008000;  /* 初始地址 */
	. = ALIGN(4);		/* 四字节对齐 */
	.text      :		/* 代码段 */
	{
		start.o(.text)		/* 从start.o 文件的.text段落开始执行 首先给它分配地址空间*/
		*(.text)			/* 其余链接文件的.text自动分配地址 */
	}
	. = ALIGN(4);			/* 4字节对齐 */
    .data : 				/* 数据段 */
	{ *(.data) }			/* 所有链接文件中的数据段均自动分配地址  */
    . = ALIGN(4);			/* 4字节对齐 */
    .bss :					/* 未初始化的数据段 */
     { *(.bss) }			/* 所有链接文件中的未初始化的数据段均自动分配地址 */
}

1.5 效果展示: