? 春節(jié)前做了一個簡單的開箱測試,跑了個流水燈,大概了解了一下CH563的基本開發(fā)流程。假期間天天走親訪友、吃喝醉睡,板子扔在一邊整個假期居然一下也沒碰。昨天上班,剛開工,沒什么事干,又把板子拿起來測試了一下CH563的中斷系統(tǒng)。
? CH563的中斷模式與其它ARM芯片差不多,分為IRQ與FIQ,同時每種模式還分為查詢?nèi)肟谂c直跳入口中斷。第一篇測試文章里提到的IRQ_Handler(),F(xiàn)IQ_Handler()這兩個函數(shù)就是默認的查詢?nèi)肟谥袛嗵幚砗瘮?shù)。在使用查詢?nèi)肟谥袛鄷r,我們要把中斷處理相關(guān)內(nèi)容寫到這兩個函數(shù)里。由于在查詢方式下所有的中斷源發(fā)生中斷后都是跳向這兩個函數(shù),所以一般要在這兩個函數(shù)里先對中斷源進行判斷,再跳轉(zhuǎn)到相應(yīng)的處理程序里。顯然這種方式會多消耗一些處理器時間。
? 而相對的直跳入口與51單片機的中斷處理差不多,都是通過指定中斷向量,一旦某一特定中斷發(fā)生時,就直接跳轉(zhuǎn)到指定的中斷處理函數(shù)里去,從而節(jié)省了一點處理器時間。
? 為了了解CH563的中斷處理方式,俺設(shè)計了兩個小程序來分別測試查詢?nèi)肟谂c直跳入口。使用的都是PB管腳做為外中斷源,利用板上的三個LED燈來指示是否進入了中斷處理程序。
? 程序1為查詢?nèi)肟?,中斷源為PB6、PB7。PB6設(shè)定為上升沿觸發(fā),PB7設(shè)定為下降沿觸發(fā)。PB7是直接利用板上的按鈕S2來觸發(fā)中斷,從而控制三個LED依次單獨點亮。PB6則用了一根杜邦線通過與GND的接觸來觸發(fā)中斷,將三個LED的狀態(tài)反轉(zhuǎn)。
下面為程序1的代碼,具體寄存器的作用都作了注釋:
#include?"CH563BAS.H" #include?"CH563SFR.H" #include?"SYSFREQ.H" #define?LED?0x38 CHAR?LEDMASK[]={0x30,0x28,0x18}; CHAR?IntTime; __irq?void?IRQ_Handler() { ??if(R8_INT_STATUS_PB_0&0x80) //是否為PB.7中斷 { Delay_ms(30);???????????//在中斷處理程序里做延時消抖,就是這么任性:) if(!(R8_PB_PIN_0&0x80)) { if(IntTime<3) { R8_PB_CLR_0?|=LED;?//LED清零 R8_PB_OUT_0?|=?LEDMASK[IntTime]; } if(++IntTime>=3)?IntTime=0; } } if(R8_INT_STATUS_PB_0&0x40) //是否為PB.6中斷 { Delay_ms(30); if((R8_PB_PIN_0&0x40)) { R8_PB_OUT_0?^=LED;? ?????????? } } ????R8_INT_STATUS_PB_0?=?0xff;?????????//?中斷標(biāo)志清零? ???? } __irq?void?FIQ_Handler(){} void?IRQ_InitPB_7_6(void) { R8_PB_PU_0?|=?0xc0; //設(shè)置PB.7.6為上拉 R8_PB_DIR_0?&=?~0xc0; //設(shè)置PB.7.6為輸入 R8_INT_ENABLE_PB_0?|=?0xc0; //打開兩IO外部中斷 R8_INT_MODE_PB_0?|=0xc0; //設(shè)置中斷觸發(fā)方式為邊沿觸發(fā) R8_INT_POLAR_PB_0?&=?0x7f; //設(shè)置PB.7下降沿觸發(fā) R8_INT_POLAR_PB_0?|=?0x40; //設(shè)置PB.6上升沿觸發(fā) R8_INT_STATUS_PB_0?=?0xff; R8_INT_EN_IRQ_1?|=?RB_IE_IRQ_PB; //使能PB口IRQ中斷 R8_INT_EN_IRQ_GLOB|=?RB_IE_IRQ_GLOB;???//使能全局IRQ中斷 } void?Init_LED(void) { R8_PB_DIR_0?|=?LED; //PB.3.4.5為輸出 R8_PB_OUT_0?|= LED; } int?main() { IRQ_InitPB_7_6(?); Init_LED(); IntTime=0; while(1) { } }