PIC32中斷及振盪器配置

 暑假過了一個月了,在忙碌的玉米地間享受揮汗如雨熱情。不過學習還是沒落下太多的,趁現在難得的網絡,彙總個這一個月的筆記情況。

 

 

一.中斷設置

步驟:

1.   設置外設中斷優先級及子優先級,觸發方式等配置

2.   設置爲系統向量模式並使能中斷

常用函數如下

    INTSetVectorPriority(); 設置優先級

    INTSetVectorSubPriority(); 設置子優先級

    INTClearFlag(); 清除中斷標誌位

    INTEnable(); 使能中斷

系統

    INTEnableSystemMultiVectoredInt();//多向量中斷允許

    INTEnableSystemSingleVectoredInt();//單向量中斷允許

所謂多向量模式即中斷向量都有自己的入口,從自己的入口進入ISR。而單向量模式則是所有的中斷共用一個向量入口。

 

例如控制時鐘中斷

                   

   INTSetVectorPriority(INT_TIMER_1_VECTOR, INT_PRIORITY_LEVEL_2);

   INTEnable(INT_T1,INT_ENABLED);                                //ConfigIntTimer1(T1_INT_ON | T1_INT_PRIOR_3 | T1_INT_SUB_PRIOR_0);

   INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR);

   INTEnableInterrupts();                                         //INTEnableSystemMultiVectoredInt();

   先設置時鐘的中斷優先級和子優先級並允許中斷

   ConfigIntTimer1(T1_INT_ON|T1_INT_PRIOR_3|TI_INT_SUB_PRIOR_0);      

//T1中斷優先級爲3,子優先級爲0,  並     允     許     T1_INT_ON      時鐘源1中斷。                       

   設置系統內核中斷

   INTEnableSystemMultiVectoredInt();

//系統多向量中斷MultiVectored開啓,並允許INTEnable中斷。 

  

 

 

 

 

 

 

 

 

 

 

 

 

 

庫函數說明:

 

 

中斷不能返回任何數據(void)

不能傳遞參數(void)

無法直接調用中斷,最好也不調用其他函數

 

INTEnableSystemSingleVectoredInt();     單向量模式——在一個向量地址處處理所有中斷請求(復位之後的模式)。

INTEnableSystemMultiVctoredInt();       多向量模式——在所計算的向量地址處處理中斷請求。

注: 雖然用戶可以在運行時將中斷控制器從單向量模式重新配置爲多向量模式(或反

之),但強烈建議用戶不要如此操作。在初始化之後更改中斷控制器模式可能導致

未定義的行爲。

必須先允許內核的系統中斷。然後,在IEC 寄存器中允許中斷,並在IPS 寄存器中分配非零優先級後,纔會接收到中斷請求。

 

INTEnableSystemSingleVectoredInt();    單向量模式——在一個向量地址處處理所有中斷請求(復位之後的模式)。

INTEnableSystemMultiVctoredInt();     多向量模式——在所計算的向量地址處處理中斷請求。

 

通用:        INTSetVectorPriority(4,INT_PRIORITY_LEVEL_2);

//中斷向量查數據手冊得timer1爲4

其他:

INTSetVectorPriority(INT_TIMER_1_VECTOR,INT_PRIORITY_LEVEL_2);//配置中斷向量的組優先級0~7

mXXSetIntPriority(x);//XX爲宏縮寫器件例如mT1SetIntPriority(2);

 

通用:             INTSetVectorSubPriority(4, INT_SUB_PRIORITY_LEVEL_0);

//中斷向量查數據手冊得timer1爲4

其他:

INTSetVectorSubPriority(INT_TIMER_1_VECTOR, INT_SUB_PRIORITY_LEVEL_0);

//配置中斷向量的子優先級0~3,當組優先級相同時,子優先級高的先執行

mXXSetIntSubPriorty(x);//XX爲宏縮寫器件例如mT1SetIntPriority(0);

 

INTEnable(INT_XX,INT_ENABLED);

mXXIntEnable();//中斷源允許中斷

 

INTClearFlag(INT_XX);// 清除XX的中斷標誌

mXXClearIntFlag();// XX爲宏縮寫器件例如ClearIntFlag(INT_T1);

 

INTGetFlag(INT_XX);

mXXGetIntFlag();//獲得XX的中斷標誌,有中斷爲1,否則0.

 

 

 

 

 

                                                  中斷源

PIC32中斷及振盪器配置

PIC32中斷及振盪器配置

PIC32中斷及振盪器配置

 

 

                                                  向量表

 PIC32中斷及振盪器配置

PIC32中斷及振盪器配置





 

 

 

 

以控制1s時鐘led爲例

  

   先進行時鐘的設置,也就是震盪器的配置這是定時器的關鍵

  

   再對定時器選擇並配置

  

   定義中斷向量並允許中斷

  

   中斷函數

  

   #include

   #pragma config JTAGEN =OFF

   //震盪器配置如下 在windows->pic Memory Views->configuration Bits有詳細設置複製出來粘貼

   #pragma config FPLLIDIV = DIV_2         // PLL輸入分頻2

   #pragma config FPLLMUL = MUL_24         // PLL倍頻24

   #pragma config FPLLODIV = DIV_2         // PLL輸出分頻2

   #pragma config FPBDIV = DIV_1           // PLL後分頻1,外設時鐘

   #pragma config FNOSC = FRCPLL           //震盪主通道內部8MHZ震盪帶PLL功能

   #pragma config POSCMOD = OFF             //主震盪模式關

   #pragma config FWDTEN = OFF             //看門狗時鐘關閉

   #define SYS_FREQ (48000000L)            //系統時鐘SYSCLK:8MHz/2*24/2=48MHz     

                                                                 //外設時鐘PBCLK:SYSCLK/FPBDIV=48MHz

   #define PERIOD 6000                   

 //時鐘源1的1-8分頻,time=period*8/48000000=0.001s 

PIC32中斷及振盪器配置

   int main()

{    //io口設置

   PORTSetPinsDigitalOut(IOPORT_B,BIT_7|BIT_9|BIT_8|BIT_13);//7,8,9.13設爲數字輸出端口

   PORTSetBits(IOPORT_B,BIT_7|BIT_8|BIT_9|BIT_13);          //置一,燈滅

   OpenTimer1(T1_ON|T1_SOURCE_INT|T1_PS_1_8,PERIOD);

    //中斷設置  配置時鐘中斷允許->系統中斷允許

   INTEnable(INT_T1, INT_ENABLED);                     

   INTSetVectorPriority(INT_TIMER_1_VECTOR, INT_PRIORITY_LEVEL_2);

//ConfigIntTimer1(T1_INT_ON | T1_INT_PRIOR_2 | T1_INT_SUB_PRIOR_0);

   INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR);

   INTEnableInterrupts();                                         //INTEnableSystemMultiVectoredInt();

}

                       //中斷函數

void __ISR(_TIMER_1_VECTOR,      ipl2) Timer1Handler(void)  

//時鐘源1所指中斷向量每產生一次中斷運行0.001s

{

//  Clear the interrupt flag

    INTClearFlag(INT_T1);

    n++;

    if(n > 1000)  //1s=1000ms=1000us

    {

       n= 0;

       PORTBINV=(1<<7)|(1<<8)|(1<<9)|(1<<13);//翻轉7,8,9,13

    }

}

 

 

     振盪器選擇標準典型的FRC 8MHZ通過輸入分頻FPLLIDIV,倍頻FPLLMUL,輸出分頻FPLLODIV成爲系統內時鐘SYSCLK,在經由後分頻FPBDIV成爲外設時鐘PBCLK。

   外設時鐘通過定時器Timer1,時間t=PS*PERIOD/PBCLK;

  

  

   Timer 定時器工作原理淺析:

經過上面設置,定時器從0開始計數,當計數值與period時產生中斷,中斷後會清標誌,並清period值,重新從0開始計數(period對應寄存器PR1)

  

 

 

單向量中斷與多向量中斷

INTEnableSystemSigleVectoredInt();//系統單向量中斷使能, 單向量模式則是所有的中斷共用一個向量入口。

INTEnableSystemMultiVectoredInt();//系統多向量中斷使能,所謂多向量模式即中斷向量都有自己的入口,從自己的入口進入ISR。

 

 

 

單向量模式時,共用默認的0向量口,僅由優先級不同來判斷中斷操作。當一箇中斷正在執行時,其他的中斷事件就必須等待當前中斷事件結束後才能進行。

     void__ISR(0,ipl2) hander2(void)

     {

     }

 

 

多向量中斷時,各個中斷源都有自己的中斷向量,僅當對應的中斷源出現中斷時標誌時纔會調用中斷事件。當一箇中斷進行時,其他優先級高的中斷可以打斷並進行高優先級中斷。

Void__ISR(_TIMER_1_VECTOR,ipl1)han(void)     void__ISR(_TIMER_2_VECTOR,ipl2) han2(void)

{                                         {

}                                         }

 

                          單向量模式

#include

#pragma config FPLLIDIV = DIV_2         // PLL Input Divider (2x Divider)

#pragma config FPLLMUL = MUL_24         // PLL Multiplier (24x Multiplier)

#pragma config FPLLODIV = DIV_2         // System PLL Output Clock Divider (PLL Divide by 2)

#pragma config FNOSC = FRCPLL           // Oscillator Selection Bits (Fast RC Osc with PLL)

#pragma config FPBDIV = DIV_1           // Peripheral Clock Divisor (Pb_Clk is Sys_Clk/1)

#pragma config JTAGEN = OFF

#pragma config FWDTEN = OFF

#define PERIOD 48000

int n2,n1;

int main()

{

 PORTSetPinsDigitalOut(IOPORT_B,BIT_7|BIT_8|BIT_9|BIT_13);

 PORTSetBits(IOPORT_B,BIT_7|BIT_8|BIT_9|BIT_13);

 OpenTimer1(T1_ON|T1_SOURCE_INT|T1_PS_1_1,PERIOD);

 OpenTimer2(T2_ON|T2_SOURCE_INT|T1_PS_1_1,PERIOD);

 INTSetVectorPriority(INT_TIMER_1_VECTOR,INT_PRIORITY_LEVEL_2);

 INTSetVectorPriority(INT_TIMER_2_VECTOR,INT_PRIORITY_LEVEL_5);

 mT1IntEnable(1);

 mT2IntEnable(1);

 INTEnableSystemSingleVectoredInt();

}

void __ISR(0,ipl5)  Timer1hander(void)

{

    if(mT2GetIntFlag())//單向量T2先進行

    mT2ClearIntFlag();//清除T2中斷,但T1中斷仍在,繼續觸發Timer1hander

    else if(mT1GetIntFlag())

    mT1ClearIntFlag();

    n1++;//每0.001s加兩次

    if(n1>1000)//約爲0.5s

    {

        n1=0;

    PORTBINV=(1<<7|1<<8);

    }

 

}

                          多向量模式

定時器2優先級高,直接搶佔定時器1

#include

#pragma config FPLLIDIV = DIV_2         // PLL Input Divider (2x Divider)

#pragma config FPLLMUL = MUL_24         // PLL Multiplier (24x Multiplier)

#pragma config FPLLODIV = DIV_2         // System PLL Output Clock Divider (PLL Divide by 2)

#pragma config FNOSC = FRCPLL           // Oscillator Selection Bits (Fast RC Osc with PLL)

#pragma config FPBDIV = DIV_1           // Peripheral Clock Divisor (Pb_Clk is Sys_Clk/1)

#pragma config JTAGEN = OFF

#pragma config FWDTEN = OFF

#define PERIOD 48000

int n2,n1;

int main()

{

 PORTSetPinsDigitalOut(IOPORT_B,BIT_7|BIT_8|BIT_9|BIT_13);

 PORTSetBits(IOPORT_B,BIT_7|BIT_8|BIT_9|BIT_13);

 OpenTimer1(T1_ON|T1_SOURCE_INT|T1_PS_1_1,PERIOD);

 OpenTimer2(T2_ON|T2_SOURCE_INT|T1_PS_1_1,PERIOD);

 INTSetVectorPriority(INT_TIMER_1_VECTOR,INT_PRIORITY_LEVEL_2);

 INTSetVectorPriority(INT_TIMER_2_VECTOR,INT_PRIORITY_LEVEL_5);

 mT1IntEnable(1);

 mT2IntEnable(1);

 INTEnableSystemMultiVectoredInt();

}

void __ISR(_TIMER_1_VECTOR,ipl2)  Timer1hander(void)

{

    mT1ClearIntFlag();

    n1++;

    if(n1>1000)

    {

        n1=0;

    PORTBINV=(1<<7|1<<8);

    }

 

}

void __ISR(_TIMER_2_VECTOR,ipl5)  Timer2hander(void)

{

   mT2ClearIntFlag();

    n2++;

    if(n2>1000)

    {

        n2=0;

    PORTBINV=(1<<9|1<<13);

    while(1);

    }

   

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章