S5PV210 串口实验(中断方式)

结合之前的串口实验(轮询方式)中断体系分析,我们来做下中断方式的串口接收实验。

start.S

.global _start
.global IRQ_handle

_start:
    /* 关 Watch Dog */
    ldr r0, =0xE2700000
    mov r1, #0
    str r1, [r0]

    /* 设置系统模式栈指针 */
    ldr sp, =0x40000000

    /* 开 IRQ 总中断开关 */
    mov r0, #0x53
    msr CPSR_cxsf, r0

    /* 时钟初始化 */
    bl clock_init

    bl main

halt:
    b halt

IRQ_handle:
    /* 设置 IRQ 模式栈指针 */
    ldr sp, =0xD0037F80

    /* 设置 lr */
    sub lr, lr, #4
    stmfd sp!, {r0-r12, lr}

    /* 另一个 ISR 的接口 */
    bl  irq_handler

    /* 弹出保存的数据 */
    ldmfd sp!, {r0-r12, pc}^

配置串口

#define UART_UBRDIV_VAL     34
#define UART_UDIVSLOT_VAL   0xDFDD

void uart_init()
{
    /* 配置引脚为串口模式 */
    GPA0CON = 0x22;

    /* 不使用 FIFO */
    UFCON0 = 0x00;
    
    /* 无流控 */
    UMCON0 = 0x00;
    
    /* 配置数据格式 */
    ULCON0 = 0x03;
    
    /* 配置 UART */
    UCON0  = 0x105;

    /* 配置波特率 */
    UBRDIV0 = UART_UBRDIV_VAL;
    UDIVSLOT0 = UART_UDIVSLOT_VAL;

    /* 开放 RX0 中断 */
    UINTM = 0x0e;
}

配置中断

所调用的 API 可在之前串口实验文章中找到。

/* 初始化异常向量 */
system_initexception();

/* 配置 ISR 函数 */
intc_setvectaddr(NUM_UART0, handler);

/* 使能 NUM_UART0 中断 */
intc_enable(NUM_UART0);

中断服务程序

void handler(void)
{
    /* 发送 +1 后的结果 */
    putc(getc()+1);

    /* 清 VICnADDR */
    intc_clearvectaddr();

    /* 清除中断标志 */
    UINTP  = 0x0f;
    UINTSP = 0x0f;
}

运行结果

向 S5PV210 发送一个字符,会得到这个字符 +1 后的字符。
原文地址:https://www.cnblogs.com/GyForever1004/p/8450157.html