PIC18F中断定时器
扫描二维码
随时随地手机看文章
//基于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端口二进制计数
}
}
}
PIC18F452定时器中断@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单片机提供多个中断源及一个中断优先级功能,可以给大多数中断源分配高优先级或者低优先级.高优先级中断向量地址为0008H,低优先级中断向量地址为0018H。高优先级中断事伯将中断所有可参正在进行的低优先级中断。
有10个寄存器用于控制中断的操作。它们是:
RCON
INTCON
INTCON2
INTCON3
PIR1和PIR2
PIE1和PIE2
IPR1和IPR2
通常,用三个位控制中断源的操作。
标志位 表明发生了中断事件
使能位 允许程序跳转转到中断向量地址处执行(当标志位置1时)
优先级 用于选择是高优先级还是低先级,通过将IPEN位(RCON<7>)置1,可使能中断优先级功能。当使能中断优先级时,有2位可使能全局中断。将GIEH位(INTCON<7>)置1,可使能所有优先级位置1(高优先级)的中断。将GIEL位(INTCON<6>)置1,可使能所有优先级位清零(低优先级)的中断。
当中断标志位、使能位以及相应的全局中断使能位均被置1时,程序将立即跳转到中断地址0008H或0018H,具体地址取决于优先级位的设置。通过设置相应的使能位可以禁止单个中断。
注意:系统复位时IPEN位为零(默认状态)时,便会禁止中断优先级功能,此时中断与PIC16系统中档单片机相兼容。在兼容模式下,所有中断均跳转到地址0008H执行。
下面是在SP9608-PIC增强型单片机开发板利用PIC18F4520单片机来实现的数字频率计数器功能,程序中使用了T0用为外部信号源输入,通TMR0来实现对信号源的频率计数。TMR3作为定时器,来产生1mS数码管扫描时基和1S秒时基信号。为了提高频率计数的准确度,采用中断嵌套技术来完成,将TMR3产生1mS的定时信号作为高优先级中断,TMR0作为频率计数溢出中断作为低先级中断。源程序采用MCC18编译器和MPLAB7.50版本的集成开发环境,调试工具采用ICD2;具体源程序如下:
系统时钟:采用外部的12MHz晶振经过内部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 //---中断高优先级---//
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 //---中断低优先级---//
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 //---设置中断优先级---// 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