PIC18F中斷定時(shí)器
//基于MCC18編譯器,使用HI-PICC不可用
//-------------------------------------------- #include
//----------------------------------------------------------------------------
void main (void);
void InterruptHandlerHigh (void);
unsigned int Timeout;
//----------------------------------------------------------------------------
// Main routine
void main ()
{
Timeout = 0;
INTCON = 0x20; //disable global and enable TMR0 interrupt
INTCON2 = 0x84; //TMR0 high priority
RCONbits.IPEN = 1; //enable priority levels
TMR0H = 0; //clear timer
TMR0L = 0; //clear timer
T0CON = 0x82; //set up timer0 - prescaler 1:8
INTCONbits.GIEH = 1; //enable interrupts
TRISD = 0; /* configure PORTD for output */
PORTD=0X00;
while (1)
{
if (Timeout == 1)
{ //timeout?
Timeout = 0; //clear timeout indicor
PORTD++; //PORTD端口二進(jìn)制計(jì)數(shù)
}
}
}
PIC18F452定時(shí)器中斷@ZSTU
//----------------------------------------------------------------------------
// High priority interrupt vector
#pragma code InterruptVectorHigh = 0x08
void InterruptVectorHigh (void)
{ _asm
goto InterruptHandlerHigh //jump to interrupt routine
_endasm
}
//----------------------------------------------------------------------------
// High priority interrupt routine
#pragma code
#pragma interrupt InterruptHandlerHigh
void InterruptHandlerHigh ()
{
if (INTCONbits.TMR0IF)
{ //check for TMR0 overflow
INTCONbits.TMR0IF = 0; //clear interrupt flag
Timeout = 1; //indicate timeout
}
}
//----------------------------------------------------------------------------
PIC18F4520單片機(jī)提供多個(gè)中斷源及一個(gè)中斷優(yōu)先級(jí)功能,可以給大多數(shù)中斷源分配高優(yōu)先級(jí)或者低優(yōu)先級(jí).高優(yōu)先級(jí)中斷向量地址為0008H,低優(yōu)先級(jí)中斷向量地址為0018H。高優(yōu)先級(jí)中斷事伯將中斷所有可參正在進(jìn)行的低優(yōu)先級(jí)中斷。
有10個(gè)寄存器用于控制中斷的操作。它們是:
RCON
INTCON
INTCON2
INTCON3
PIR1和PIR2
PIE1和PIE2
IPR1和IPR2
通常,用三個(gè)位控制中斷源的操作。
標(biāo)志位 表明發(fā)生了中斷事件
使能位 允許程序跳轉(zhuǎn)轉(zhuǎn)到中斷向量地址處執(zhí)行(當(dāng)標(biāo)志位置1時(shí))
優(yōu)先級(jí) 用于選擇是高優(yōu)先級(jí)還是低先級(jí),通過將IPEN位(RCON<7>)置1,可使能中斷優(yōu)先級(jí)功能。當(dāng)使能中斷優(yōu)先級(jí)時(shí),有2位可使能全局中斷。將GIEH位(INTCON<7>)置1,可使能所有優(yōu)先級(jí)位置1(高優(yōu)先級(jí))的中斷。將GIEL位(INTCON<6>)置1,可使能所有優(yōu)先級(jí)位清零(低優(yōu)先級(jí))的中斷。
當(dāng)中斷標(biāo)志位、使能位以及相應(yīng)的全局中斷使能位均被置1時(shí),程序?qū)⒘⒓刺D(zhuǎn)到中斷地址0008H或0018H,具體地址取決于優(yōu)先級(jí)位的設(shè)置。通過設(shè)置相應(yīng)的使能位可以禁止單個(gè)中斷。
注意:系統(tǒng)復(fù)位時(shí)IPEN位為零(默認(rèn)狀態(tài))時(shí),便會(huì)禁止中斷優(yōu)先級(jí)功能,此時(shí)中斷與PIC16系統(tǒng)中檔單片機(jī)相兼容。在兼容模式下,所有中斷均跳轉(zhuǎn)到地址0008H執(zhí)行。
下面是在SP9608-PIC增強(qiáng)型單片機(jī)開發(fā)板利用PIC18F4520單片機(jī)來實(shí)現(xiàn)的數(shù)字頻率計(jì)數(shù)器功能,程序中使用了T0用為外部信號(hào)源輸入,通TMR0來實(shí)現(xiàn)對(duì)信號(hào)源的頻率計(jì)數(shù)。TMR3作為定時(shí)器,來產(chǎn)生1mS數(shù)碼管掃描時(shí)基和1S秒時(shí)基信號(hào)。為了提高頻率計(jì)數(shù)的準(zhǔn)確度,采用中斷嵌套技術(shù)來完成,將TMR3產(chǎn)生1mS的定時(shí)信號(hào)作為高優(yōu)先級(jí)中斷,TMR0作為頻率計(jì)數(shù)溢出中斷作為低先級(jí)中斷。源程序采用MCC18編譯器和MPLAB7.50版本的集成開發(fā)環(huán)境,調(diào)試工具采用ICD2;具體源程序如下:
系統(tǒng)時(shí)鐘:采用外部的12MHz晶振經(jīng)過內(nèi)部PLL的4倍頻到48MHz。(HS-PLL配置位)
1 #include
2 #define TRUE 1
3 #define FALSE 0
4 #define HIGH 1
5 #define LOW 0
6 rom unsigned char LEDDATA[]=
7 {
8 0x3F,0x06,0x5B,0x4F,0x66,
9 0x6D,0x7D,0x07,0x7F,0x6F,
10 0x40,0x00,
11 };
12 struct TIMER_STRUCT
13 {
14 unsigned int Interval;
15 unsigned char Enable;
16 };
17 struct TIMER_STRUCT Timer1S;
18 struct T0_T1_STRUCT
19 {
20 unsigned int High_Byte;
21 unsigned int Low_Byte;
22 unsigned long Result;
23 };
24 struct T0_T1_STRUCT My_T0,My_T1;
25 struct LED_STRUCT
26 {
27 unsigned char DotPointer;
28 unsigned char ScanPointer;
29 unsigned char Buffer[8];
30 };
31 struct LED_STRUCT NumberLED;
32 void PIC18F_High_isr (void);
33 void PIC18F_Low_isr (void);
34 #pragma code high_vector_section=0x8
35 void high_vector (void)
36 {
37 _asm goto PIC18F_High_isr _endasm
38 }
39 #pragma code low_vector_section=0x18
40 void low_vector (void)
41 {
42 _asm goto PIC18F_Low_isr _endasm
43 }
44 #pragma code
45 //---中斷高優(yōu)先級(jí)---//
46 #pragma interrupt PIC18F_High_isr
47 void PIC18F_High_isr (void)
48 {
49 if(TRUE==PIR2bits.TMR3IF)
50 {
51 PIR2bits.TMR3IF=FALSE;
52 TMR3H=(65536-11965)/256;
53 TMR3L=(65536-11965)%256;
54
55 if(FALSE==Timer1S.Enable)
56 {
57 Timer1S.Interval++;
58 if(1000==Timer1S.Interval)
59 {
60 T0CONbits.TMR0ON=FALSE;
61 Timer1S.Interval=0;
62 Timer1S.Enable=TRUE;
63 }
64 }
65
66 if(LOW==LATAbits.LATA0)LATAbits.LATA0=HIGH;
67 else LATAbits.LATA0=LOW;
68
69 LATD=LEDDATA[NumberLED.Buffer[NumberLED.ScanPointer]];
70 LATE=NumberLED.ScanPointer;
71 NumberLED.ScanPointer++; if(NumberLED.ScanPointer==sizeof(NumberLED.Buffer))NumberLED.ScanPointer=0;
72 }
73 }
74 //---中斷低優(yōu)先級(jí)---//
75 #pragma interruptlow PIC18F_Low_isr
76 void PIC18F_Low_isr (void)
77 {
78 if(TRUE==INTCONbits.TMR0IF)
79 {
80 INTCONbits.TMR0IF=FALSE;
81 My_T0.High_Byte++;
82 }
83
84 }
85 void main(void)
86 {
87 unsigned int i;
88 unsigned long temp;
89
90 Timer1S.Enable=FALSE;
91 Timer1S.Interval=0;
92 My_T0.High_Byte=0;
93 My_T0.Low_Byte=0;
94 My_T1.High_Byte=0;
95 My_T1.Low_Byte=0;
96 for(i=0;i 97 NumberLED.ScanPointer=0; 98 NumberLED.DotPointer=0; 99 TRISAbits.TRISA0=0; 100 LATAbits.LATA0=0; 101 TRISD=0; 102 LATD=0; 103 TRISE=0; 104 LATE=0; 105 T0CONbits.TMR0ON=FALSE; 106 TMR0L=0; 107 TMR0H=0; 108 T0CONbits.T0CS=1; 109 T0CONbits.T0SE=0; 110 T0CONbits.PSA=1; 111 T0CONbits.T08BIT=1; 112 INTCONbits.T0IF=FALSE; 113 INTCONbits.T0IE=TRUE; 114 T0CONbits.TMR0ON=TRUE; 115 T3CON=0x00; 116 TMR3H=(65536-12000)/256; 117 TMR3L=(65536-12000)%256; 118 PIR2bits.TMR3IF=FALSE; 119 PIE2bits.TMR3IE=TRUE; 120 T3CONbits.TMR3ON=TRUE; 121 INTCONbits.GIEH=TRUE; 122 INTCONbits.GIEL=TRUE; 123 RCONbits.IPEN=TRUE; 124 //---設(shè)置中斷優(yōu)先級(jí)---// 125 INTCON2bits.TMR0IP=FALSE; 126 IPR2bits.TMR3IP=TRUE; 127 128 while(1) 129 { 130 if(TRUE==Timer1S.Enable) 131 { 132 My_T0.Result=0; 133 My_T0.Result=My_T0.High_Byte; 134 My_T0.Result<<=8; 135 My_T0.Result|=TMR0L; 136 temp=My_T0.Result; 137 for(i=0;i