Thứ Năm, 1 tháng 3, 2012

[Lập trình ARM-LPC2378] Ngắt Trong LPC23xx


Bài trước: [Lập trình ARM-LPC2378] Truyền Thông Nối Tiếp Không Đồng Bộ- UART


Bài 4: Ngắt Trong LPC23xx


Nội Dung
+ Giới thiệu về ngắt trong LPC23xx
+ Các thanh ghi liên quan tới điều khiển ngắt
+ Hàm cài đặt ngắt install_irq()

Giới thiệu về ngắt trong LPC23xx
+ LPC2378 hỗ trợ 32 ngắt với 16 mức độ ưu tiên.
+ Có 2 loại ngắt: Interrupt request (IRQ) và Fast Interrupt Request (FIQ).
+ Fast Interrupt Request là ngắt có độ ưu tiên cao nhất. IRQ có độ ưu tiên thấp hơn.
+ Nếu có nhiều ngắt cùng độ ưu tiên thì ngắt nào ở Vector có chỉ số nhỏ hơn sẽ được thực thi trước.


+ Bảng trên thể hiện vị trí thứ tự các bit tương ứng với ngắt cho từng loại đối tượng.


Các thanh ghi liên quan tới điều khiển ngắt
+ VICIRQStatus (32bits) : Thanh ghi trạng thái của ngắt loại IRQ, bit bật lên 1 cho biết đối tượng ngắt tương ứng được kích hoạt và loại ngắt là IRQ.
VICFIQStatus (32bits) : Thanh ghi trạng thái của ngắt loại FIQ, bit bật lên 1 cho biết đối tượng ngắt tương ứng được kích hoạt và loại ngắt là FIQ.
VICVectAddrn (32bits) : Thanh ghi địa chỉ, chỉ tới hàm sẽ thực hiện nếu có ngắt xảy ra.
VICIntEnable (32bits) : Cho giá trị bằng 1 ở bit muốn cài đặt.
VICVectPriorityn (32bits) : Thanh ghi xét độ ưu tiên.
            n: bit thứ n ( Với n: 0 -> 31 ).
Ví Dụ:
VICVectAddr4 = ( unsigned long ) TO_IRQHandler;
VICVectCnt4 = 15;
VICIntEnable = ( 1 << 4 );

+ Với n=4: Ngắt của Timer0
+ Hàm thực hiện khi ngắt xảy ra là TO_IRQHandler
+ Độ ưu tiên cho ngắt là 15
+ Khởi động Bộ điều khiển ngắt ở bit thứ 4

Khai báo
+ Hàm ngắt: có từ khóa __irq hoặc __fiq
VD:
void TO_IRQHandler(void)__irq
{
        ...
        VICVectAddr = 0;
}
__irq void TO_IRQHandler(void)
{
        ...
        VICVectAddr = 0;
}


Hàm cài đặt ngắt install_irq()
Hàm cài đặt ngắt
DWORD install_irq( DWORD IntNumber, void *HandlerAddr, DWORD Priority )
{
        DWORD *vect_addr;
        DWORD *vect_prio;

        VICIntEnClr = 1 << IntNumber; //Disable Interrupt
        if( IntNumber >= VIC_SIZE )
        {
                return( FALSE );
        }
        else
        {
                /* find first un assigned VIC address for the handler */
                vect_addr = (DWORD *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + IntNumber*4);
                vect_prio = (DWORD *)(VIC_BASE_ADDR + VECT_PRIO_INDEX + IntNumber*4);
                *vect_addr = (DWORD)HandlerAddr; /* set interrupt vector */
                *vect_prio = Priority;
                VICIntEnable = 1 << IntNumber; /* Enable Interrupt */
                return( TRUE );
        }
}


Ví Dụ
Tạo ngắt cho Interrupt0 Button(INT0)


+ PINSEL4 = 0x01 << 20;
+ VICVectAddr14 = (unsigned long)abc;
+ VICVectCntl14 = 14; 
+ VICIntEnable  = (1  << 14);
+  __irq void abc (void) 
{
        ……// xuat ten cua ban ra HyperTerminal
        EXTINT=0x01;
        VICVectAddr = 0;
}





(nguồn: ĐHKHTN TP.HCM)

0 nhận xét:

Đăng nhận xét