【CC2530入門教程-03】CC2530的中斷系統及外部中斷應用


第3課  CC2530的中斷系統及外部中斷應用

廣東職業技術學院  歐浩源

一、中斷相關的基礎概念

        內核外設之間的主要交互方式有兩種:輪詢中斷。 輪詢的方式貌似公平,但實際工作效率很低,且不能及時響應緊急事件;中斷系統使得內核具備了應對突發事件的能力。

        在執行CPU當前程序時,由於系統中出現了某種急需處理的情況,CPU暫停正在執行的程序,轉而去執行另外一段特殊程序來處理出現的緊急事務,處理結束后,CPU自動返回到原來暫停的程序中去繼續執行。 這種程序在執行過程中由於外界的原因而被中間打斷的情況,稱為中斷

        兩個重要的概念:

        <1> 中斷服務函數: 內核響應中斷后執行的相應處理程序。

        <2> 中斷向量:中斷服務程序的入口地址。每個中斷源都對應一個固定的入口地址。當內核響應中斷請求時,就會暫停當前的程序執行,然后跳轉到該入口地址執行代碼。

 

二、CC2530的中斷系統

        CC2530具有18個中斷源,每個中斷源都由各自的一系列特殊功能寄存器來進行控制。可以編程設置相關特殊功能寄存器,設置18個中斷源的優先級以及使能中斷申請響應等。我們常用的中斷源有下面幾個:

 

三、CC2530的中斷處理函數編寫方法

        中斷服務函數與一般自定義函數不同,有特定的書寫格式

<1> 在每一個中斷服務函數之前,都要加上一句起始語句

        #pragma vector = <中斷向量>

        <中斷向量>表示接下來要寫的中斷服務函數是為那個中斷源服務的,該 語句有兩種寫法:

        #pragma  vector = 0x7B    或者    #pragma  vector = P1INT_VECTOR

        前者是中斷向量的入口地址,后者是頭文件“ioCC2530.h”中的宏定義。

<2> _ _interrupt關鍵字表示該函數是一個中斷服務函數,<函數名稱>可以 自定義,函數體不能帶有參數,也不能有返回值

 

四、CC2530的外部中斷

        CC2530的P0、P1和P2端口中的每個引腳都具有外部中斷輸入功能,要使某些引腳具有外部中斷功能,需要對IENx寄存器、PxIEN寄存器和PICTL寄存器進行適當的設置。 除了各個中斷源都有自己的中斷使能開關之外,中斷系統還有一個總開關,可以同“EA = 1;”來打開總中斷。

        P0、P1和P2端口分別使用P0IF、P1IFP2IF作為中斷標志位,任何一個端口組上的引腳產生外部中斷時,都會將對應端口組的中斷標志自動置位。注意,外部中斷標志必須在中斷服務函數中手工清除,否則CPU會反復進入中斷。 端口狀態標志寄存器P0IFGP1IGFP2IFG,分別對應3個端口中各引腳的中斷觸發狀態,當某引腳發生外部中斷觸發時,對應的標志位會自動置位,這個標志同樣需要手工清除。

 

五、實訓案例:外部中斷輸入控制LED燈

【1】設計外部中斷初始化函數Init_INTP()

        外部中斷初始化函數,主要是完成跟中斷相關的特殊功能寄存器配置工作:

        <1> 配置IENx寄存器,使能端口組的中斷功能。

        <2> 配置PxIEN寄存器,使能具體的外部中斷引腳。

        <3> 配置PICTL寄存器,設置中斷觸發方式。

【2】設計外部中斷服務函數Int1_Sevice()

        在編寫中斷服務函數的時候,書寫格式要正確,中斷向量不能搞錯。特別要注意:在函數里面把端口組和引腳的標志位清除,否則CPU將會反復進入中斷,必須先清除引腳標志位PxIFG,再清除端口組標志位PxIF。

【3】實訓項目源代碼及注釋

 1 #include "ioCC2530.h"
 2 
 3 #define  LED6   P1_4
 4 #define  LED3   P1_0
 5 #define  LED4   P1_1
 6 /*===================延時函數=========================*/
 7 void Delay(unsigned int t)
 8 {
 9   while(t--);
10 }
11 /*==================端口初始化函數=====================*/
12 void Init_Port()
13 {
14   //將P1_0、P1_1和P1_4設置為通用I/O端口功能
15   P1SEL &= ~0x13;   
16   //將P1_0、P1_1和P1_4的端口傳輸方式設置為輸出
17   P1DIR |= 0x13;   
18   LED6 = 0;
19   LED3 = 0;
20   LED4 = 0;
21 }
22 /*==================跑馬燈子函數=====================*/
23 void LED_Running()
24 {
25   LED3 = 1;
26   Delay(50000);
27   LED4 = 1;
28   Delay(50000);
29   LED3 = 0;
30   Delay(50000);
31   LED4 = 0;
32   Delay(50000);
33 }
34 /*===============外部中斷初始化函數==================*/
35 void Init_INTP()
36 {
37   IEN2 |= 0x10;         //端口1中斷使能
38   P1IEN |= 0x04;        //端口P1_2外部中斷使能
39   PICTL |= 0x02;        //端口P1_0到P1_3下降沿觸發 
40   EA = 1;               //使能總中斷
41 }
42 /*================外部中斷1服務函數====================*/
43 #pragma vector = P1INT_VECTOR     //外部中斷1的向量入口
44 __interrupt void Int1_Sevice()
45 {
46   LED6 = ~LED6;
47 /*先清除引腳標志位,再清除端口標志位,否則會不斷進入中斷*/
48   P1IFG &= ~ 0x04;        //軟件清除P1_2引腳的標志位
49   P1IF = 0;               //軟件清除P1端口組的標志位
50 }
51 /*====================主函數==========================*/
52 void main()
53 {
54   Init_Port();          //初始化通用I/O端口
55   Init_INTP();          //初始化外部中斷
56   while(1)
57   {
58     LED_Running();     //跑馬燈
59   }
60 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM