打印

sdPIC33 不进中断,高手帮忙啊

[复制链接]
4310|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gghhz|  楼主 | 2010-7-16 16:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
sd, pic, TE, os, TI
microchip 官网上下载了外部中断和定时器中断的示例代码。
在没有做任何修改的情况下,编译通过,烧录后无动作

后作了一些小小的修改,依然无动作,用SIM软件仿真,但是不知道
中断如何仿真,IO激励不知道如何使用,E文比较的不好,请大虾们指导一下。
附件中为源代码 external_interrupts.rar (2.97 KB)
以下是修改后的代码:

#include "p33fxxxx.h"
// External Oscillator
_FOSCSEL(FNOSC_FRC);   
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF  & POSCMD_XT);  
        // Clock Switching is enabled and Fail Safe Clock Monitor is disabled
        // OSC2 Pin Function: OSC2 is Clock Output
        // Primary Oscillator Mode: XT Crystal

_FWDT(FWDTEN_OFF);              // Watchdog Timer Enabled/disabled by user software

/* Global Variables and Functions */
void INTx_IO_Init(void);
void __attribute__((__interrupt__)) _INT1Interrupt(void);
void delay(void)
{
  int i,j;
  for(i=6000;i>0;i--)
   for(j=100;j>0;j--);
    //_amp_(nop);
  }
int main (void)
{

PLLFBD=38;     // M=40
CLKDIVbits.PLLPOST=0;  // N1=2
CLKDIVbits.PLLPRE=0;  // N2=2
OSCTUN=0;     // Tune FRC oscillator, if FRC is used
// Disable Watch Dog Timer
    RCONbits.SWDTEN=0;
// Configure the Analog functional pins as digital
AD1PCFGL=0xFFFF;
AD1PCFGH=0xFFFF;      
    TRISD = 0x0000;             // LEDs on dsPICDEM 1.1 board are connected to RD0-RD3
    TRISA = 0XFFFF;
    INTx_IO_Init();             /* Call function to initialize the External Interrupts */
    while (1)                   /* Loop endlessly...anytime an interrupt occurs */
    {
     if(IFS1bits.INT1IF==1)
      LATDbits.LATD5=1;
     else
      LATDbits.LATD6=1;
     if(PORTAbits.RA12)
      LATDbits.LATD4=1;
     }
                                /* the processor will vector to the interrupt and */
                                /* return back to the while(1) loop */
}
void INTx_IO_Init(void)
{
        INTCON1bits.NSTDIS=0;
        SRbits.IPL0=1;
        SRbits.IPL1=0;
        SRbits.IPL1=0;
        INTCON2 = 0x001F;
        IEC1bits.INT1IE =1;    /*Enable INT1 Interrupt Service Routine */
        IPC5bits.INT1IP=5;
}
void __attribute__((interrupt, no_auto_psv)) _INT1Interrupt(void)
{
        LATDbits.LATD1=1;       //Toggle RD0
        delay();
        IFS1bits.INT1IF = 0;    //Clear the INT1 interrupt flag or else
                                //the CPU will keep vectoring back to the ISR
}
沙发
gghhz|  楼主 | 2010-7-19 08:59 | 只看该作者
用SIM跟踪,中断标志位都已经置1了,就是不进中断,是不是中断函数写错了啊?请高手指点啊

使用特权

评论回复
板凳
headwolf_83| | 2010-7-19 09:32 | 只看该作者
中断只是一瞬间,你的灯最多也就瞬间亮下(假设进中断前刚好就查到了IF位),然后就没了。有IF位的时候,一般先进中断,你进了中断又DELAY,然后IF就没了。这时候主循环已经判不到IF了。

你直接在中断中对灯取反不就OK了,能看到有没有进。如果一定认为没有进中断,我认为你还是拿个调试器,设置个段点,不要老是折腾SIM,上硬件最直接。

使用特权

评论回复
地板
gghhz|  楼主 | 2010-7-19 11:48 | 只看该作者
回复3楼:   while (1)                   /* Loop endlessly...anytime an interrupt occurs */
                       {
                            if(IFS1bits.INT1IF==1)
                              LATDbits.LATD5=1;
                           else
                             LATDbits.LATD6=1;
                          if(PORTAbits.RA12)
                             LATDbits.LATD4=1;
                          }
这段代码的就反应了中断有没有进了,因为我是在中断函数中清零中断标志位的。
但是在SIM中,未激励RA12时,RD6=1;当激励RA12后,RD5=1;但是接下来就一直是RD5=1了。
说明中断标志位没有被清零。

我就是在硬件上测试了,没有进中断,所以才用SIM仿真的,至于在线调试器,太贵了,买不起啊。

使用特权

评论回复
5
headwolf_83| | 2010-7-19 12:52 | 只看该作者
把主程序中的代码注释掉,直接在中断中对灯进行取反。在线调试器,也就2,3百。PICKIT2,PICKIT3都可以。

使用特权

评论回复
6
gghhz|  楼主 | 2010-7-19 17:18 | 只看该作者
楼上的高手,能否帮忙给一个调试过的dsPIC33的中断代码啊,搞了几天,都要崩溃了。

使用特权

评论回复
7
gghhz|  楼主 | 2010-7-20 21:24 | 只看该作者
没人回,高手帮忙啊

使用特权

评论回复
8
gghhz|  楼主 | 2010-7-22 16:50 | 只看该作者
问题还没有得到解决,依然盼望高手解决啊

使用特权

评论回复
9
headwolf_83| | 2010-7-22 16:54 | 只看该作者
#include <p33fxxxx.h>


/*
功能说明:本代码将演示利用RD0/OC1输出PWM波形驱动,由RD11/INT4进行高电平时间的测量。
运行环境:外接8M,FOSC 80MHZ,FCY 40MHZ,TCY 25ns
版本说明:V1.1
修改人  :**南 www.PIC591.com
*/
unsigned int ADCVal;
unsigned int HIGHVal;           //OC输出的高电平时间,us
unsigned int INTVal;            //中断测量结果,us
unsigned int i,j;
unsigned char INTType ;         //中断沿类型,含义与INTXEP一致
int main(void)
{
    _PLLPRE = 0 ;   //N1 = 2
    _PLLDIV = 38 ;  //M = 38+2 = 40
    _PLLPOST = 0 ;  //N2 = 2
                    //FOSC = (8/2) * 40 / 2 = 80M
    while(OSCCONbits.LOCK == 0) ;   //等待PLL稳定   
    _DISI = 1 ;     //使能DISI指令,部分内建函数需要,建议开启
   
   
    _TRISB9 = 1 ;               //RB9/AN9为输入口
    _PCFG9 = 0 ;                //RB9/AN9设置为模拟口
   
    /*
    根据勘误,只能配置为300KBPS,带A的型号没这些问题
    则一次转换至少要3.3us,按采样保持3TAD,转换14TAD算,至少17TAD。
    3.3us/17 ~= 200ns,即,TAD至少为8TCY,200ns。
    带A的流行后,建议大家换带A的,改下配置位重新编译后,目前看来几乎是全兼容的。   
    */
    AD1CON1 = 0x04E4 ;          //暂不使能AD,12位AD模式,自动采样模式自动转换
    AD1CON2 = 0x0000 ;          //AVDD,AVSS做看靠,不扫描通道,每次采样完毕中断
    AD1CON3 = 0x0307 ;          //TAD根据PBCLK为基准,TAD = (7+1)*Tcy = 200ns ,
                                //TSAMP = 3TAD
                                //经过以上配置,AD转换时间约为17TAD = 3.4us,略低于300KBPS
    AD1CON4 = 0 ;               //非DMA模式未用到此寄存器
   
    AD1CHS123 = 0 ;             //12BIT模式未用到
    AD1CHS0 = 0x0009 ;          //设置采样通道为AN9/RB9
    AD1CSSL = 0 ;               //不扫描轮询,可设置为0
   
    _AD1IF = 0 ;                //清中断标志位
    _AD1IE = 0 ;                //不启用中断
    _AD1IP = 0 ;                //中断主优先级别设置为0
   
    _ADON = 1 ;                 //AD使能
   
   
    //设置OC1/RD1
    _TRISD0 = 0 ;               //
    T2CON = 0x0020 ;            //暂不使能T2,1:64分频,内部定时器模式
    TMR2 = 0 ;                  //
    PR2 = 12499 ;               //PWM周期 = (PR2+1)*64*(1/40)us = 20ms,50HZ   
   
    OC1CON = 0X0006 ;           //暂不使能模块,选择T2做时钟,16位模式,PWM模式
    OC1RS = 0 ;                 //
    OC1R = 0 ;                  //
   
   
    //设置INT4/RD11
   
    _TRISD11 = 1 ;              //IO置输入
    _INT4EP = 0 ;               //INT4为上升沿中断,注意,级性定义与PIC32是相反的
    _INT4IF = 0 ;               //
    _INT4IP = 7 ;               //中断优先级别为7
    _INT4IE = 1 ;               //中断使能
    INTType = 1 ;               //初使化类型必须与INT4EP相反
    TMR4 = 0 ;                  //利用T4+INT4,测量OC1的高电平时间
    T4CON = 0X0020 ;            //暂不使能T4,1:64分频,内部定时器模式,即1个计数单为1.6us。
   
    T2CONbits.TON = 1 ;          //
    T4CONbits.TON = 1 ;          //   
   
    while(1)
    {
        while(_AD1IF == 0) ;    //等待第一次AD转换结果
        _AD1IF = 0 ;            //
        ADCVal = ADC1BUF0 ;     //
        AD1CON1bits.ASAM = 0 ;  //停止AD
        if(ADCVal >= 4000)      //填入占空比
        {
            PR2 = 12499 ;       //最大周期为20ms            
        }
        else if(ADCVal <= 400)  //
        {
            PR2 = 1249 ;        //最小周期为2ms
        }
        else
        {
            PR2 = ADCVal * 3 + ADCVal / 8 - 1 ;     //
        }
        OC1RS = (PR2 + 1)/2 ;           //占空比固定为一半
        HIGHVal = OC1RS ;               //记录
        
        for(j = 0 ; j < 10 ; j++ )
        {
            for(i = 0 ; i < 0xffff; i++ ) ;      //延时
        }        
        AD1CON1bits.ASAM = 1 ;          //时间到再次启动
    }   
   
}

void __attribute__((__interrupt__,no_auto_psv)) _INT4Interrupt(void)
{
    _INT4IF = 0 ;
    if(_INT4EP == 0)                            //如本次为上升沿中断
    {
        if((INTType == 1) && (_RD11 == 1))      //如果上一次中断类型为下降沿
        {            
            TMR4 = 0 ;                       
        }
        _INT4EP = 1 ;                           //下次下降沿进中断
        INTType = 0 ;                           //记录本次中断类型     
    }
    else                                        //本次为下降沿
    {
        if((_RD11 == 0) && (INTType == 0))      //低电平,且上一次中断类型为高电平
        {
            INTVal = TMR4 ;                     //下降沿来,取走高电平值,随后在低电平期间就让TMR4其自由计数,           
        }
        _INT4EP = 0 ;                           //下次上升沿进中断
        INTType = 1 ;                           //记录本次中断类型        
    }
}

使用特权

评论回复
10
headwolf_83| | 2010-7-22 16:56 | 只看该作者
如果你**盲调,不愿意上个调试器,言尽于此。上个调试器,在中断中设个断点,全速一下,一目了然,就知道到底有没有进中断。我觉得你的主程序逻辑还是有问题。前头已经分析过了。

使用特权

评论回复
11
gghhz|  楼主 | 2010-7-22 17:23 | 只看该作者
KIT3,同学有一个,接过来用一下。看看问题到底出在哪儿。我就不信了,
这个问题解决不了。多谢楼上兄弟的提醒

使用特权

评论回复
12
hotpower| | 2010-8-1 01:52 | 只看该作者
现在的PIC程序看着很顺眼、很舒心~~~

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

70

帖子

2

粉丝