[参考设计] PIC18F中断定时器

[复制链接]
61|3
 楼主 | 2019-11-8 15:01 | 显示全部楼层 |阅读模式
    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执行。

使用特权

评论回复
 楼主 | 2019-11-8 15:01 | 显示全部楼层
  1. //基于MCC18编译器,使用HI-PICC不可用
  2. //--------------------------------------------   #include <p18F452.h>
  3. //----------------------------------------------------------------------------
  4. void main (void);
  5. void InterruptHandlerHigh (void);  
  6. unsigned int Timeout;  
  7. //----------------------------------------------------------------------------
  8. // Main routine
  9. void main ()
  10. {   
  11.         Timeout = 0;   
  12.         INTCON = 0x20;                 //disable global and enable TMR0 interrupt      
  13.         INTCON2 = 0x84;               //TMR0 high priority  
  14.         RCONbits.IPEN = 1;            //enable priority levels  
  15.         TMR0H = 0;                      //clear timer  
  16.         TMR0L = 0;                      //clear timer   
  17.         T0CON = 0x82;                //set up timer0 - prescaler 1:8  
  18.         INTCONbits.GIEH = 1;       //enable interrupts  
  19.         TRISD = 0; /* configure PORTD for output */  
  20.         PORTD=0X00;   
  21.         while (1)   
  22.         {      
  23.              if (Timeout == 1)         
  24.             {                                  //timeout?         
  25.                    Timeout = 0;          //clear timeout indicor                       
  26.                    PORTD++;              //PORTD端口二进制计数        
  27.           }   
  28.         }
  29. }

  30. PIC18F452定时器中断@ZSTU
  31. //----------------------------------------------------------------------------
  32. // High priority interrupt vector  
  33. #pragma code InterruptVectorHigh = 0x08
  34. void  InterruptVectorHigh (void)
  35. {    _asm   
  36.       goto InterruptHandlerHigh //jump to interrupt routine
  37.     _endasm
  38. }  
  39. //----------------------------------------------------------------------------
  40. // High priority interrupt routine  
  41. #pragma code
  42. #pragma interrupt InterruptHandlerHigh
  43. void  InterruptHandlerHigh ()
  44. {   
  45.       if (INTCONbits.TMR0IF)     
  46.      {   //check for TMR0 overflow      
  47.          INTCONbits.TMR0IF = 0;            //clear interrupt flag      
  48.          Timeout = 1;                          //indicate timeout   
  49.       }
  50. }
  51. //----------------------------------------------------------------------------
复制代码

使用特权

评论回复
 楼主 | 2019-11-8 15:01 | 显示全部楼层
下面是在SP9608-PIC增强型单片机开发板利用PIC18F4520单片机来实现的数字频率计数器功能,程序中使用了T0用为外部信号源输入,通TMR0来实现对信号源的频率计数。TMR3作为定时器,来产生1mS数码管扫描时基和1S秒时基信号。为了提高频率计数的准确度,采用中断嵌套技术来完成,将TMR3产生1mS的定时信号作为高优先级中断,TMR0作为频率计数溢出中断作为低先级中断。源程序采用MCC18编译器和MPLAB7.50版本的集成开发环境,调试工具采用ICD2;具体源程序如下:
   系统时钟:采用外部的12MHz晶振经过内部PLL的4倍频到48MHz。(HS-PLL配置位)

使用特权

评论回复
 楼主 | 2019-11-8 15:02 | 显示全部楼层
  1. #include <p18cxxx.h>
  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. void main(void)
  85. {
  86. unsigned int i;
  87. unsigned long temp;

  88. Timer1S.Enable=FALSE;
  89. Timer1S.Interval=0;
  90. My_T0.High_Byte=0;
  91. My_T0.Low_Byte=0;
  92. My_T1.High_Byte=0;
  93. My_T1.Low_Byte=0;
  94. for(i=0;i<sizeof(NumberLED.Buffer);i++)NumberLED.Buffer[i]=0;
  95. NumberLED.ScanPointer=0;
  96. NumberLED.DotPointer=0;
  97. TRISAbits.TRISA0=0;
  98. LATAbits.LATA0=0;
  99. TRISD=0;
  100. LATD=0;
  101. TRISE=0;
  102. LATE=0;
  103. T0CONbits.TMR0ON=FALSE;
  104. TMR0L=0;
  105. TMR0H=0;
  106. T0CONbits.T0CS=1;
  107. T0CONbits.T0SE=0;
  108. T0CONbits.PSA=1;
  109. T0CONbits.T08BIT=1;
  110. INTCONbits.T0IF=FALSE;
  111. INTCONbits.T0IE=TRUE;
  112. T0CONbits.TMR0ON=TRUE;
  113. T3CON=0x00;
  114. TMR3H=(65536-12000)/256;
  115. TMR3L=(65536-12000)%256;
  116. PIR2bits.TMR3IF=FALSE;
  117. PIE2bits.TMR3IE=TRUE;
  118. T3CONbits.TMR3ON=TRUE;
  119. INTCONbits.GIEH=TRUE;
  120. INTCONbits.GIEL=TRUE;
  121. RCONbits.IPEN=TRUE;
  122. //---设置中断优先级---//
  123. INTCON2bits.TMR0IP=FALSE;
  124. IPR2bits.TMR3IP=TRUE;

  125. while(1)
  126.     {
  127.    if(TRUE==Timer1S.Enable)
  128.      {
  129.     My_T0.Result=0;
  130.     My_T0.Result=My_T0.High_Byte;
  131.     My_T0.Result<<=8;
  132.     My_T0.Result|=TMR0L;
  133.     temp=My_T0.Result;
  134.     for(i=0;i<sizeof(NumberLED.Buffer);i++)NumberLED.Buffer[i]=0;
  135.     i=0;
  136.     while(temp)
  137.       {
  138.      NumberLED.Buffer[i]=temp%10;
  139.      temp/=10;
  140.      i++;   
  141.     }
  142.     TMR0L=0;
  143.     TMR0H=0;
  144.     My_T0.Low_Byte=0;
  145.     My_T0.High_Byte=0;
  146.     Timer1S.Enable=FALSE;
  147.     T0CONbits.TMR0ON=TRUE;
  148.    }
  149. }
  150. }
复制代码

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 投诉建议 创建版块 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表