搜索
bottom↓
回复: 3

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

[复制链接]

出0入0汤圆

发表于 2014-9-1 19:28:10 | 显示全部楼层 |阅读模式
小弟最近开始使用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
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-9-10 08:57:44 | 显示全部楼层
看看标志位是不是写1清零

出0入0汤圆

发表于 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;
}
初步测试可以再次进入中断,但没分析会不会有其它不良影响。

出0入0汤圆

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

首先非常感谢你专业的回答,问题就在“void InterruptServiceHigh ()应该需要声明为中断函数”,谢谢!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-5 19:29

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表