串口通信实战

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);
    
}
原文地址:https://www.cnblogs.com/jxjl/p/7077387.html