×
单片机 > 单片机程序设计 > 详情

PIC18F中断定时器

发布时间:2020-06-08 发布时间:
|

//基于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

138     i=0;

139     while(temp)

140       {

141      NumberLED.Buffer[i]=temp%10;

142      temp/=10;

143      i++;    

144     }

145     TMR0L=0;

146     TMR0H=0;

147     My_T0.Low_Byte=0;

148     My_T0.High_Byte=0;

149     Timer1S.Enable=FALSE;

150     T0CONbits.TMR0ON=TRUE;

151    }

152 }

153 }





『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
Keil(MDK-ARM)系列教程(七)_菜单