PIC18F中断定时器

时间:2024-05-21 19:03:38
//基于MCC18编译器,使用HI-PICC不可用
//-------------------------------------------- #include <p18F452.h>
//----------------------------------------------------------------------------
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配置位)

 #include <p18cxxx.h>
#define TRUE 1
#define FALSE 0
#define HIGH 1
#define LOW 0
rom unsigned char LEDDATA[]=
{
0x3F,0x06,0x5B,0x4F,0x66,
0x6D,0x7D,0x07,0x7F,0x6F,
0x40,0x00,
};
struct TIMER_STRUCT
{
unsigned int Interval;
unsigned char Enable;
};
struct TIMER_STRUCT Timer1S;
struct T0_T1_STRUCT
{
unsigned int High_Byte;
unsigned int Low_Byte;
unsigned long Result;
};
struct T0_T1_STRUCT My_T0,My_T1;
struct LED_STRUCT
{
unsigned char DotPointer;
unsigned char ScanPointer;
unsigned char Buffer[];
};
struct LED_STRUCT NumberLED;
void PIC18F_High_isr (void);
void PIC18F_Low_isr (void);
#pragma code high_vector_section=0x8
void high_vector (void)
{
_asm goto PIC18F_High_isr _endasm
}
#pragma code low_vector_section=0x18
void low_vector (void)
{
_asm goto PIC18F_Low_isr _endasm
}
#pragma code
//---中断高优先级---//
#pragma interrupt PIC18F_High_isr
void PIC18F_High_isr (void)
{
if(TRUE==PIR2bits.TMR3IF)
{
PIR2bits.TMR3IF=FALSE;
TMR3H=(-)/;
TMR3L=(-)%; if(FALSE==Timer1S.Enable)
{
Timer1S.Interval++;
if(==Timer1S.Interval)
{
T0CONbits.TMR0ON=FALSE;
Timer1S.Interval=;
Timer1S.Enable=TRUE;
}
} if(LOW==LATAbits.LATA0)LATAbits.LATA0=HIGH;
else LATAbits.LATA0=LOW; LATD=LEDDATA[NumberLED.Buffer[NumberLED.ScanPointer]];
LATE=NumberLED.ScanPointer;
NumberLED.ScanPointer++; if(NumberLED.ScanPointer==sizeof(NumberLED.Buffer))NumberLED.ScanPointer=;
}
}
//---中断低优先级---//
#pragma interruptlow PIC18F_Low_isr
void PIC18F_Low_isr (void)
{
if(TRUE==INTCONbits.TMR0IF)
{
INTCONbits.TMR0IF=FALSE;
My_T0.High_Byte++;
} }
void main(void)
{
unsigned int i;
unsigned long temp; Timer1S.Enable=FALSE;
Timer1S.Interval=;
My_T0.High_Byte=;
My_T0.Low_Byte=;
My_T1.High_Byte=;
My_T1.Low_Byte=;
for(i=;i<sizeof(NumberLED.Buffer);i++)NumberLED.Buffer[i]=;
NumberLED.ScanPointer=;
NumberLED.DotPointer=;
TRISAbits.TRISA0=;
LATAbits.LATA0=;
TRISD=;
LATD=;
TRISE=;
LATE=;
T0CONbits.TMR0ON=FALSE;
TMR0L=;
TMR0H=;
T0CONbits.T0CS=;
T0CONbits.T0SE=;
T0CONbits.PSA=;
T0CONbits.T08BIT=;
INTCONbits.T0IF=FALSE;
INTCONbits.T0IE=TRUE;
T0CONbits.TMR0ON=TRUE;
T3CON=0x00;
TMR3H=(-)/;
TMR3L=(-)%;
PIR2bits.TMR3IF=FALSE;
PIE2bits.TMR3IE=TRUE;
T3CONbits.TMR3ON=TRUE;
INTCONbits.GIEH=TRUE;
INTCONbits.GIEL=TRUE;
RCONbits.IPEN=TRUE;
//---设置中断优先级---//
INTCON2bits.TMR0IP=FALSE;
IPR2bits.TMR3IP=TRUE; while()
{
if(TRUE==Timer1S.Enable)
{
My_T0.Result=;
My_T0.Result=My_T0.High_Byte;
My_T0.Result<<=;
My_T0.Result|=TMR0L;
temp=My_T0.Result;
for(i=;i<sizeof(NumberLED.Buffer);i++)NumberLED.Buffer[i]=;
i=;
while(temp)
{
NumberLED.Buffer[i]=temp%;
temp/=;
i++;
}
TMR0L=;
TMR0H=;
My_T0.Low_Byte=;
My_T0.High_Byte=;
Timer1S.Enable=FALSE;
T0CONbits.TMR0ON=TRUE;
}
}
}