結合之前的 "串口實驗(輪詢方式)" 與 "中斷體系分析" ,我們來做下中斷方式的串口接收實驗。 start.S ~~~~ .global _start .global IRQ_handle _start: / 關 Watch Dog / ldr r0, =0xE2700000 mov r1, 0 ...
結合之前的串口實驗(輪詢方式)與中斷體系分析,我們來做下中斷方式的串口接收實驗。
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 後的字元。