找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

帖子
查看: 4547|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

PIC32中斷及振蕩器配置

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:99624 發(fā)表于 2015-12-25 04:16 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
在忙碌的玉米地間享受揮汗如雨熱情。不過(guò)學(xué)習(xí)還是沒(méi)落下太多的,趁現(xiàn)在難得的網(wǎng)絡(luò),匯總個(gè)這一個(gè)月的筆記情況。


一.中斷設(shè)置
步驟:
1.  設(shè)置外設(shè)中斷優(yōu)先級(jí)及子優(yōu)先級(jí),觸發(fā)方式等配置
2.   設(shè)置為系統(tǒng)向量模式并使能中斷
常用函數(shù)如下
   INTSetVectorPriority(); 設(shè)置優(yōu)先級(jí)
   INTSetVectorSubPriority(); 設(shè)置子優(yōu)先級(jí)
   INTClearFlag(); 清除中斷標(biāo)志位
   INTEnable(); 使能中斷
系統(tǒng)
   INTEnableSystemMultiVectoredInt();//多向量中斷允許
   INTEnableSystemSingleVectoredInt();//單向量中斷允許
所謂多向量模式即中斷向量都有自己的入口,從自己的入口進(jìn)入ISR。而單向量模式則是所有的中斷共用一個(gè)向量入口。

例如控制時(shí)鐘中斷
                  
  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();
   先設(shè)置時(shí)鐘的中斷優(yōu)先級(jí)和子優(yōu)先級(jí)并允許中斷
  ConfigIntTimer1(T1_INT_ON|T1_INT_PRIOR_3|TI_INT_SUB_PRIOR_0);      
//T1中斷優(yōu)先級(jí)為3,子優(yōu)先級(jí)為0, 并    允    許    T1_INT_ON     時(shí)鐘源1中斷。                       
   設(shè)置系統(tǒng)內(nèi)核中斷
  INTEnableSystemMultiVectoredInt();
//系統(tǒng)多向量中斷MultiVectored開啟,并允許INTEnable中斷。
  




庫(kù)函數(shù)說(shuō)明:


中斷不能返回任何數(shù)據(jù)(void)
不能傳遞參數(shù)(void)
無(wú)法直接調(diào)用中斷,最好也不調(diào)用其他函數(shù)

INTEnableSystemSingleVectoredInt();    單向量模式——在一個(gè)向量地址處處理所有中斷請(qǐng)求(復(fù)位之后的模式)。
INTEnableSystemMultiVctoredInt();      多向量模式——在所計(jì)算的向量地址處處理中斷請(qǐng)求。
注: 雖然用戶可以在運(yùn)行時(shí)將中斷控制器從單向量模式重新配置為多向量模式(或反
之),但強(qiáng)烈建議用戶不要如此操作。在初始化之后更改中斷控制器模式可能導(dǎo)致
未定義的行為。
必須先允許內(nèi)核的系統(tǒng)中斷。然后,在IEC 寄存器中允許中斷,并在IPS 寄存器中分配非零優(yōu)先級(jí)后,才會(huì)接收到中斷請(qǐng)求。

INTEnableSystemSingleVectoredInt();   單向量模式——在一個(gè)向量地址處處理所有中斷請(qǐng)求(復(fù)位之后的模式)。
INTEnableSystemMultiVctoredInt();    多向量模式——在所計(jì)算的向量地址處處理中斷請(qǐng)求。

通用:       INTSetVectorPriority(4,INT_PRIORITY_LEVEL_2);
//中斷向量查數(shù)據(jù)手冊(cè)得timer1為4
其他:
INTSetVectorPriority(INT_TIMER_1_VECTOR,INT_PRIORITY_LEVEL_2);//配置中斷向量的組優(yōu)先級(jí)0~7
mXXSetIntPriority(x);//XX為宏縮寫器件例如mT1SetIntPriority(2);

通用:            INTSetVectorSubPriority(4, INT_SUB_PRIORITY_LEVEL_0);
//中斷向量查數(shù)據(jù)手冊(cè)得timer1為4
其他:
INTSetVectorSubPriority(INT_TIMER_1_VECTOR,INT_SUB_PRIORITY_LEVEL_0);
//配置中斷向量的子優(yōu)先級(jí)0~3,當(dāng)組優(yōu)先級(jí)相同時(shí),子優(yōu)先級(jí)高的先執(zhí)行
mXXSetIntSubPriorty(x);//XX為宏縮寫器件例如mT1SetIntPriority(0);

INTEnable(INT_XX,INT_ENABLED);
mXXIntEnable();//中斷源允許中斷

INTClearFlag(INT_XX);// 清除XX的中斷標(biāo)志
mXXClearIntFlag();// XX為宏縮寫器件例如ClearIntFlag(INT_T1);

INTGetFlag(INT_XX);
mXXGetIntFlag();//獲得XX的中斷標(biāo)志,有中斷為1,否則0.





                                                中斷源









                                                 向量表













以控制1s時(shí)鐘led為例
  
  先進(jìn)行時(shí)鐘的設(shè)置,也就是震蕩器的配置這是定時(shí)器的關(guān)鍵
  
   再對(duì)定時(shí)器選擇并配置
  
   定義中斷向量并允許中斷
  
   中斷函數(shù)
  
   #include
   #pragma config JTAGEN=OFF
   //震蕩器配置如下 在windows->pic MemoryViews->configuration Bits有詳細(xì)設(shè)置復(fù)制出來(lái)粘貼
   #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,外設(shè)時(shí)鐘
   #pragma config FNOSC =FRCPLL          //震蕩主通道內(nèi)部8MHZ震蕩帶PLL功能
   #pragma config POSCMOD =OFF            //主震蕩模式關(guān)
   #pragma config FWDTEN =OFF            //看門狗時(shí)鐘關(guān)閉
   #define SYS_FREQ(48000000L)           //系統(tǒng)時(shí)鐘SYSCLK:8MHz/2*24/2=48MHz     
                                                                //外設(shè)時(shí)鐘PBCLK:SYSCLK/FPBDIV=48MHz
   #define PERIOD6000                  
//時(shí)鐘源1的1-8分頻,time=period*8/48000000=0.001s



   int main()
{   //io口設(shè)置
  PORTSetPinsDigitalOut(IOPORT_B,BIT_7|BIT_9|BIT_8|BIT_13);//7,8,9.13設(shè)為數(shù)字輸出端口
  PORTSetBits(IOPORT_B,BIT_7|BIT_8|BIT_9|BIT_13);         //置一,燈滅
  OpenTimer1(T1_ON|T1_SOURCE_INT|T1_PS_1_8,PERIOD);
   //中斷設(shè)置  配置時(shí)鐘中斷允許->系統(tǒng)中斷允許
   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();
}
                      //中斷函數(shù)
void__ISR(_TIMER_1_VECTOR,     ipl2) Timer1Handler(void)  
//時(shí)鐘源1所指中斷向量每產(chǎn)生一次中斷運(yùn)行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);//翻轉(zhuǎn)7,8,9,13
    }
}


    振蕩器選擇標(biāo)準(zhǔn)典型的FRC8MHZ通過(guò)輸入分頻FPLLIDIV,倍頻FPLLMUL,輸出分頻FPLLODIV成為系統(tǒng)內(nèi)時(shí)鐘SYSCLK,在經(jīng)由后分頻FPBDIV成為外設(shè)時(shí)鐘PBCLK。
  外設(shè)時(shí)鐘通過(guò)定時(shí)器Timer1,時(shí)間t=PS*PERIOD/PBCLK;
  
  
   Timer 定時(shí)器工作原理淺析:
經(jīng)過(guò)上面設(shè)置,定時(shí)器從0開始計(jì)數(shù),當(dāng)計(jì)數(shù)值與period時(shí)產(chǎn)生中斷,中斷后會(huì)清標(biāo)志,并清period值,重新從0開始計(jì)數(shù)(period對(duì)應(yīng)寄存器PR1)
  


單向量中斷與多向量中斷
INTEnableSystemSigleVectoredInt();//系統(tǒng)單向量中斷使能,單向量模式則是所有的中斷共用一個(gè)向量入口。
INTEnableSystemMultiVectoredInt();//系統(tǒng)多向量中斷使能,所謂多向量模式即中斷向量都有自己的入口,從自己的入口進(jìn)入ISR。



單向量模式時(shí),共用默認(rèn)的0向量口,僅由優(yōu)先級(jí)不同來(lái)判斷中斷操作。當(dāng)一個(gè)中斷正在執(zhí)行時(shí),其他的中斷事件就必須等待當(dāng)前中斷事件結(jié)束后才能進(jìn)行。
    void__ISR(0,ipl2) hander2(void)
    {
    }


多向量中斷時(shí),各個(gè)中斷源都有自己的中斷向量,僅當(dāng)對(duì)應(yīng)的中斷源出現(xiàn)中斷時(shí)標(biāo)志時(shí)才會(huì)調(diào)用中斷事件。當(dāng)一個(gè)中斷進(jìn)行時(shí),其他優(yōu)先級(jí)高的中斷可以打斷并進(jìn)行高優(yōu)先級(jí)中斷。
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先進(jìn)行
   mT2ClearIntFlag();//清除T2中斷,但T1中斷仍在,繼續(xù)觸發(fā)Timer1hander
    elseif(mT1GetIntFlag())
   mT1ClearIntFlag();
   n1++;//每0.001s加兩次
   if(n1>1000)//約為0.5s
    {
       n1=0;
   PORTBINV=(1<<7|1<<8);
    }

}
                         多向量模式
定時(shí)器2優(yōu)先級(jí)高,直接搶占定時(shí)器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);
    }
   
}

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表