串口通信实战
start.S
/* * 文件名: start.s * 作者: 朱老师 * 描述: 演示串口通信 */ #define WTCON 0xE2700000 #define SVC_STACK 0xd0037d80 .global _start // 把_start链接属性改为外部,这样其他文件就可以看见_start了 _start: // 第1步:关看门狗(向WTCON的bit5写入0即可) ldr r0, =WTCON ldr r1, =0x0 str r1, [r0] //第2步:设置时钟 bl clock_init // 第3步:设置SVC栈 ldr sp, =SVC_STACK // 第4步:开/关icache mrc p15,0,r0,c1,c0,0; // 读出cp15的c1到r0中 //bic r0, r0, #(1<<12) // bit12 置0 关icache orr r0, r0, #(1<<12) // bit12 置1 开icache mcr p15,0,r0,c1,c0,0; bl main // 从这里之后就可以开始调用C程序了 //bl led_blink // led_blink是C语言实现的一个函数 // 汇编最后的这个死循环不能丢 b .
main.c
void main(void) { uart_init(); while(1) { uart_putc('a'); delay(); } }
uart.c
#define GPA0CON 0xE0200000 #define ULCON0 0xE2900000 #define UCON0 0xE2900004 #define UMCON0 0xE290000C #define UFCON0 0xE2900008 #define UBRDIV0 0xE2900028 #define UDIVSLOT0 0xE290002C #define UTRSTAT0 0xE2900010 #define UTXH0 0xE2900020 #define URXH0 0xE2900024 #define rGPA0CON (*(volatile unsigned int *)GPA0CON) #define rULCON0 (*(volatile unsigned int *)ULCON0) #define rUCON0 (*(volatile unsigned int *)UCON0) #define rUMCON0 (*(volatile unsigned int *)UMCON0) #define rUFCON0 (*(volatile unsigned int *)UFCON0) #define rUBRDIV0 (*(volatile unsigned int *)UBRDIV0) #define rUDIVSLOT0 (*(volatile unsigned int *)UDIVSLOT0) #define rUTRSTAT0 (*(volatile unsigned int *)UTRSTAT0) #define rUTXH0 (*(volatile unsigned int *)UTXH0) #define rURXH0 (*(volatile unsigned int *)URXH0) //串口初始化程序 void uart_init(void) { //初始化Tx Rx对应的GPIO引脚 rGPA0CON &= ~(0xff<<0); //设置GPIO rGPA0CON |= 0x00000022; //几个关键寄存器 rULCON0 = 0x3; //设置停止位和一次传送几个字符 rUCON0 = 0x5; //设置模式中断/轮询 rUMCON0 = 0x0; //关闭自动流控 rUFCON0 = 0X0; //关闭流控 //波特率设置,PCLK_PSYS按照66.7M算 rUBRDIV0 = 35; //波特率的整数部分 rUDIVSLOT0 = 0x0888; //查表得知的 } //串口发送程序,发送一个字节 void uart_putc(char c) { //串口发送一个字符 //因为串口发送一个字节的速度远远低于CPU的速度,所以CPU发送一个字节前必须确认 //串口控制器缓冲区是空的 while(!(rUTRSTAT0 & (1<<1))); rUTXH0 = c; } //串口接收程序,轮训方式, char uart_getc(void) { while(!(rUTRSTAT0 & (1<<0))); return (rURXH0 & 0x0f); }