zsdshuai 发表于 2014-9-1 19:28:10

真心请教,我的PIC定时器中断为啥只能进去1次

小弟最近开始使用PIC单片机,使用的是PIC18F45K80,使用PICKIT3作为调试工具,遇到以下难题:
系统时钟内部的16M,定时器前置4分频,也就是定时器时钟1M,定时10ms,现在调试发现定时器中断只能进去1次,到底是哪里出现了问题?恳请大家不吝赐教,谢谢!

我的程序如下:工程文件在附件中

/** C O N F I G U R A T I O N   B I T S ******************************/

#pragma config XINST = OFF,SOSCSEL=DIG,INTOSCSEL=LOW,RETEN=ON   //Config 1L
#pragma config IESO = OFF,FCMEN=OFF,PLLCFG=OFF,FOSC=INTIO2      //Config 1H
#pragma config BORPWR = LOW,BORV=3,BOREN=OFF,PWRTEN=OFF         //Config 2L
#pragma config WDTPS = 1,WDTEN=OFF                              //Config 2H
#pragma config MCLRE = ON                                       //Config 3H

/** I N C L U D E S **************************************************/
#include "p18f45k80.h"
/** D E C L A R A T I O N S ******************************************/

/* ***********************************************************************************
** 函 数 名: void main (void)
** 功能描述: 主函数
**         
**************************************************************************************/
void main (void)
{
//OSCCON = 0x60;         //选择8M内部时钟
      OSCCON = 0x70;         //选择16M内部时钟
   
      OSCTUNEbits.PLLEN = 0;   // *4 PLL 禁能
//OSCTUNEbits.PLLEN = 1;   // *4 PLL 使能


   T0CON=0b00000001;//前置4分频定时器1M的时钟
   TMR0H=0xD8;
   TMR0L=0xEF;      //0xFFFF-0xD8EF= 10000定时10ms
   T0CONbits.TMR0ON=1;
   
   
   RCONbits.IPEN=1;   
   
   INTCONbits.TMR0IF=0;    /* 清除TMR0的中断标志 */
   INTCON2bits.TMR0IP=1;    /* TMR0中断高优先级 */
   INTCONbits.TMR0IE=1;    /* TMR0中断允许 */
   INTCONbits.PEIE_GIEL=1;
   INTCONbits.GIE_GIEH=1;
   
   
   
while (1);
}

void InterruptServiceHigh ()
{
if(INTCONbits.TMR0IF==1)
   {
    TMR0H=0xD8;
    TMR0L=0xEF;      //0xFFFF-0xD8EF= 10000定时10ms
    INTCONbits.TMR0IF=0;
    INTCONbits.TMR0IE=1;
   }
}


#pragma code InterruptVectorHigh = 0x08
void InterruptVectorHigh (void)
{
_asm
    goto InterruptServiceHigh //jump to interrupt routine
_endasm
}

whangch_sh 发表于 2014-9-10 08:57:44

看看标志位是不是写1清零

yklstudent 发表于 2014-9-10 10:45:21

楼主看资料不细致
void InterruptServiceHigh ()应该需要声明为中断函数,不然系统只当普通函数来处理对待;
解决办法如下所示:
1、方法1
#pragma code
#pragma interrupt InterruptServiceHigh

void InterruptServiceHigh(void)
{
        if(INTCONbits.TMR0IF)       
           {
            TMR0H = 0xD8;               
            TMR0L = 0xEF;                      //0xFFFF-0xD8EF= 10000       定时10ms
            INTCONbits.TMR0IF = 0;
            INTCONbits.TMR0IE = 1;
           }
}
2、方法2
分析void InterruptServiceHigh(void)为普通函数时,系统进中断后,
最高级中断允许标志位清零;当中断处理完退出后,最高级中断允许标志位没有置1;
导致下次没法再进入高级中断。
个人感觉可以人为在函数最后加上如下一句:
void InterruptServiceHigh(void)
{
        if(INTCONbits.TMR0IF)       
           {
            TMR0H = 0xD8;               
            TMR0L = 0xEF;                      //0xFFFF-0xD8EF= 10000       定时10ms
            INTCONbits.TMR0IF = 0;
            INTCONbits.TMR0IE = 1;
           }
        INTCONbits.GIE_GIEH = 1;
}
初步测试可以再次进入中断,但没分析会不会有其它不良影响。

zsdshuai 发表于 2014-9-10 11:53:25

yklstudent 发表于 2014-9-10 10:45
楼主看资料不细致
void InterruptServiceHigh ()应该需要声明为中断函数,不然系统只当普通函数来处理对待 ...

首先非常感谢你专业的回答,问题就在“void InterruptServiceHigh ()应该需要声明为中断函数”,谢谢!
页: [1]
查看完整版本: 真心请教,我的PIC定时器中断为啥只能进去1次