//13-12-09 11:12 唐湘衡
//同級優先順序的掌握
/*熟悉中斷功能,沒有發生中斷時第,板子上的額第一個數位管RA0亮,並迴圈顯示0-9
//如當外部產生中斷(高優先順序)(RB0)按下時,數位管顯示暫停,蜂鳴器響5秒,然後數位管迴圈閃
//如按下RB2(定義為高低優先順序)時,蜂鳴器嗒響5下, 然後數位管迴圈閃*/
/*器件:MPLAB軟體8.2以上,MCC18編譯器,mcd—II模擬器,工程板一塊,晶片PIC18F4520*/
//實驗問題:當程式在板子上運行時,低優先順序只能執行1次 !然後在按RB2就無反應了,但高優先順序一直有效
#include<p18cxxx.h>
const char table[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x98}; //0-9共陽極設定
void PIC18F_High_isr(void); //中斷服務程式
void PIC18F_Low_isr(void);
void Inio(); //連接埠初始化程式
void Buzze(); //蜂鳴器響函數
void Delay_Onesecond(); //一秒延時函數
void Need_Delay(unsigned x); //通過參數可獲得秒的倍
void Delay(unsigned int x); //延時函數
void Buzze2(void); //高優先順序鬧鈴
void Delay(unsigned int x)
{
unsigned int i;
i = x;
for (i=x; i>0; i--);
}
void Buzze2(void) //高優先順序鬧鈴
{
int i = 5;
for (i=5; i>0; i--)
{
TRISC = 0;
PORTC = 0x04; //RC2=1 發聲
Delay(100000); //100ms 微妙
PORTCbits.RC2= 0; //不發聲
Delay(100000); //100000us 100ms 毫秒
}
}
void Delay_Onesecond() //一秒延時函數 數字1在此晶片中執行 +1 或-1 所需時間為0.2us(微妙)
{ //那1秒鐘所需值為(1us等於5個數字) 5000 000
unsigned int i ;
for (i=10000000; i>0; i--);
}
void Need_Delay(unsigned x) //通過參數可獲得秒的倍數
{
unsigned int i;
for (i=x; i>0; i--)
{
Delay_Onesecond(); //調用1秒函數
}
}
void Inio() //連接埠初始化程式
{
TRISA = 0X7e; //RA0允許為亮
TRISD = 0X00; //D連接埠全部設為輸出
ADCON1 = 0X07; //設定A口為普通I/O口(模數轉換寄存器)查表吧
TRISC = 0; //設定c連接埠為輸出,蜂鳴器用 高電平有效
PORTA = 0X00;
PORTD = 0XFe; //開啟第1數位管 低電平有效
}
//***********************************************
void Buzze() //蜂鳴器響函數
{
TRISC = 0;
PORTCbits.RC2=1; //發聲
Need_Delay(5); //發聲延時5秒
PORTCbits.RC2 = 0; //不發聲
}
//**********************************************
#pragma code high_vector_section = 0x8//#pragma code指定後面的程式在rom的起始地址為0X8,終止於0x17
void high_vector()
{
_asm goto PIC18F_High_isr _endasm //通過此指令逃到中斷服務程式
}
//**************************************************
#pragma code Low_vector_section = 0x18
void low_vector()
{
_asm goto PIC18F_Low_isr _endasm //通過此指令逃到中斷服務程式
}
//****************************************************************
#pragma code //返回預設的程式碼片段
#pragma interrupt PIC18F_High_isr //#pragma interrupt 關鍵字 跳轉到高中斷服務程式,下面一定是次程式
void PIC18F_High_isr() //進階中斷服務程式 記得要清中斷標誌位
{
//同級優先順序的判斷-標誌位進行判斷
if(INTCONbits.INT0IF == 1)
{
Buzze(); //蜂鳴器響函數
INTCONbits.INT0IF = 0; //iINT0外部中斷標誌位 INTCON1寄存器 寫成INTCON
}
if (INTCON3bits.INT2IF == 1)
{
Buzze2();
INTCON3bits.INT2IF = 0; //INT2外部中斷標誌清除 INTCON1寄存器 寫成INTCON
}
}
#pragma interruptlow PIC18F_High_isr //跳轉到低中斷服務程式 記得要清楚中斷標誌位
void PIC18F_Low_isr()
{
// Buzze2(); //低優先順序鬧鈴
//INTCON3bits.INT2IF = 0; //INTCON3寄存器
}
void main()
{
char num;
Inio(); //連接埠初始化程式
INTCONbits.GIE = 0; //關閉全域中斷 INTCON1
//初始化程式
TRISB = 0x05; //RB0,RB2設為輸入,當有按鍵按下時,將會自動執行
INTCON2bits.RBPU = 0; //S使能B連接埠的上拉電位
//PORTBbits.RB0
RCONbits.IPEN = 1; // 使能中斷優先順序 RCON
//高優先順序設定 1
INTCON2bits.INTEDG0 = 0; //INTCON2 使能外部中斷觸發邊緣中斷(下降源)
INTCONbits.INT0IF = 0; //清外部中斷標誌優先位
INTCONbits.INT0IE = 1; //使能int0(供RB0使用)外部中斷使能位
//INTCON3bits.INT0IP = 0; //外部中斷優先順序為高優先順序 INT0IP不存在,預設的
//高優先順序設定 2
INTCON2bits.INTEDG2 = 0; //INTCON2 使能外部中斷觸發邊緣中斷(下降源)
INTCON3bits.INT2IF = 0; //清外部中斷標誌優先位
INTCON3bits.INT2IP = 1; //外部中斷優先順序為高低優先順序 INTCON3
INTCON3bits.INT2IE = 1; //使能部中斷
INTCONbits.GIEL = 1; //所有外設中斷允許低優先順序使能
RCONbits.IPEN = 1; //使能中斷優先順序
INTCONbits.GIE = 1; //開啟全域中斷
//主程式
/*總結:中斷模組中,記得三個寄存器:標誌,使能,優先順序,在程式中,先把他們關閉,然後才開啟*/
while (1) //迴圈顯示0-9
{
for (num=0; num<10; num++)
{
PORTD = table[num];
Delay_Onesecond(); //1秒延時
}
}
}