xj_1232005 发表于 2008-7-6 20:08:00

to 傻孩子和各位大侠:为什么进不了PCINT0中断

这是在傻孩子的旋转编码器代码基础上做的用PCINT0接收A相,PCINT1接收B相,并做四倍频的代码,但是不知道为什么进不了PCINT0 和PCINT1中断,因为担心数显影响了四倍频的信号采集,把数显注释掉了.当我从PB0输入编码器的脉冲信号,则程序相当于RESET的效果,居然从main()函数重新执行.而PlusCounter仍然不变.保持为0
用的环境:AVR studio 4.14, 仿真器用的是jtagice MKII. 用的是debugwire仿真,编码器用的是500线,通过代码来使之四倍频.所以写成了2000线
#include <iom48v.h>
#include <macros.h>
#include "display.h"

#define DIS_Qian 0                                     //定义显示千位数
#define DIS_Bai 1                                     //定义显示百位数
#define DIS_Shi 2                                     //定义显示十位数
#define DIS_Ge 3                                     //定义显示个位数
#define PLUS_MAX 2000                              //定义编码器旋转1周对应的脉冲数
#define PLUS_90   (unsigned int)(500)   //定义一个多少脉冲(0.18度/脉冲)为90度,此处为500

#define SIG_A_PIN   PINB                            //A相信号接入的引脚PB.0
#define SIG_A_BIT   0b00000001                      //PB.0作为A相信号读入端

#define SIG_B_PIN   PINB                            //B相信号接入的引脚PB.1
#define SIG_B_BIT   0b00000010                      //PB.1作为B相信号读入端

unsigned int PlusCounter=0;                         //脉冲计数器,用于计算从上电开始计算的相对脉冲个数
unsigned int Angle=0;                              //角度计数器

#pragma interrupt_handler pcint0_isr:iv_PCINT0
void pcint0_isr(void)                                 //PCINT0中断服务函数
{
// PlusCounter+=1;这一行仅是为了验证有没有进入中断时用的

    if((SIG_A_PIN&SIG_A_BIT)!=0x00)
        {
   
      if ((SIG_B_PIN&SIG_B_BIT)==0x00)
          {                                             //顺时针方向旋转,角度增大
          PlusCounter=(PlusCounter<PLUS_90)?(PlusCounter+1):PLUS_90;
      }
      else
      {                                             //逆时针方向旋转,角度减小
          PlusCounter=(PlusCounter>0)?(PlusCounter-1):0;
      }
        }
       
        else
        {
   
      if ((SIG_B_PIN&SIG_B_BIT)!=0x00)
          {                                             //顺时针方向旋转,角度增大
          PlusCounter=(PlusCounter<PLUS_90)?(PlusCounter+1):PLUS_90;
      }
      else
      {                                             //逆时针方向旋转,角度减小
          PlusCounter=(PlusCounter>0)?(PlusCounter-1):0;
      }
        }
}

#pragma interrupt_handler pcint1_isr:iv_PCINT1
void pcint1_isr(void)                                 //PCINT1中断服务函数
{
   // PlusCounter+=1;这一行仅是为了验证有没有进入中断时用的
        if((SIG_B_PIN&SIG_B_BIT)!=0x00)
        {
           if ((SIG_A_PIN&SIG_A_BIT)!=0x00)
       {                                             //顺时针方向旋转,角度增大
          PlusCounter=(PlusCounter<PLUS_90)?(PlusCounter+1):PLUS_90;
       }
      else
      {                                             //逆时针方向旋转,角度减小
         PlusCounter=(PlusCounter>0)?(PlusCounter-1):0;
      }
        }
       
        else
        {
           if ((SIG_A_PIN&SIG_A_BIT)==0x00)
       {                                             //顺时针方向旋转,角度增大
          PlusCounter=(PlusCounter<PLUS_90)?(PlusCounter+1):PLUS_90;
       }
      else
      {                                             //逆时针方向旋转,角度减小
         PlusCounter=(PlusCounter>0)?(PlusCounter-1):0;
      }
        }
       
}

void Init_Device (void)
{
    CLI();

/************************Port Init************************/

    DDRD=0b11001111;
    DDRC=0b11111111;
    DDRB=0b00000000;

    PORTD=0b00111111;
    PORTC=0b11000001;
    PORTB|=0b00111111;

/*******************EX. Interrupt Init********************/
    EIMSK=0x00;
    PCMSK0|=((1<<PCINT1)|(1<<PCINT0));
    PCICR|=(1<<PCIE0);                           //使能PCINT0和PCINT1

    SEI();
}

void main (void)
{
    unsigned char DisArr;

    Init_Device();

    while(1);
   /* {
      Angle=PlusCounter*18;          //用脉冲个数计算角度
      DisArr=(Angle/1000);                //拆分角度千,百,十和个位,送显
      DisArr=(Angle%1000/100);
                DisArr=(Angle%100/10);
                DisArr=(Angle%10);
      LED_Show(DisArr,DisArr,DisArr,DisArr);
    }*/
}

Gorgon_Meducer 发表于 2008-7-7 19:08:44

我想楼主可能理解错了。
引脚电平变化中断实际上只有3个中断向量:
寄存器PCICR中PCIE0中断使能标志位掌管PCINT0~PCINT7引脚上的电平变化,
也就是说,PCINT0~PCINT7引脚上的任何变化都对应中断向量0x0003;
寄存器PCICR中PCIE1中断使能标志位掌管PCINT8~PCINT15引脚上的电平变化,
也就是说,PCINT8~PCINT15引脚上的任何变化都将触发中断向量0x0004所指
定的中断处理程序;
寄存器PCICR中PCIE2以此类推。

楼主用了PCINT0和PCINT1实际上只是PB0和PB1引脚上的引脚电平变化中断,
它们都对应中断向量0x0003所指向的中断处理程序。可以理解为,无论PB0
还是PB1任意一个引脚发生了电平变化中断,都经触发同一个中断处理程序
我们可以通过系统提供的寄存器PCMSK0来选择,同一个中断向量实际上可以
由8个引脚电平变化中断引脚中的哪一个或哪几个来触发。

Gorgon_Meducer 发表于 2008-7-7 19:17:50

这是一个使用M88实现两个A/B项编码器同时4倍频的程序。希望对你有所帮助。

# define LEFT_COUNTER_INSERT_INTA_ISR_CODE\
            {\
                if (ENCODER_LEFT_INTA_PIN == ENCODER_LEFT_INTB_PIN)\
                {\
                  g_lCounterL++;\
                }\
                else\
                {\
                  g_lCounterL--;\
                }\
            }
# define LEFT_COUNTER_INSERT_INTB_ISR_CODE\
            {\
                if (ENCODER_LEFT_INTA_PIN == ENCODER_LEFT_INTB_PIN)\
                {\
                  g_lCounterL--;\
                }\
                else\
                {\
                  g_lCounterL++;\
                }\
            }
            
# define RIGHT_COUNTER_INSERT_INTA_ISR_CODE \
            {\
                if (ENCODER_RIGHT_INTA_PIN == ENCODER_RIGHT_INTB_PIN)\
                {\
                  g_lCounterR--;\
                }\
                else\
                {\
                  g_lCounterR++;\
                }\
            }
# define RIGHT_COUNTER_INSERT_INTB_ISR_CODE \
            {\
                if (ENCODER_RIGHT_INTA_PIN == ENCODER_RIGHT_INTB_PIN)\
                {\
                  g_lCounterR++;\
                }\
                else\
                {\
                  g_lCounterR--;\
                }\
            }

# define INSERT_INT0_ISR_CODE         SEI();LEFT_COUNTER_INSERT_INTA_ISR_CODE
# define INSERT_PCINT1_ISR_CODE         SEI();LEFT_COUNTER_INSERT_INTB_ISR_CODE

# define INSERT_INT1_ISR_CODE         SEI();RIGHT_COUNTER_INSERT_INTA_ISR_CODE
# define INSERT_PCINT0_ISR_CODE         SEI();RIGHT_COUNTER_INSERT_INTB_ISR_CODE


/***********************************************************
*   函数说明:外中断初始化函数                           *
*   输入:    无                                           *
*   输出:    无                                           *
*   调用函数:无                                           *
***********************************************************/
static void Extend_INT_INIT(void)
{
    //INT0INT1
    EICRA = BIT(ISC10)|BIT(ISC00);                        //任意电平变化
    EIMSK = BIT(INT1)|BIT(INT0);                            //中断使能
   
    //Pin Change Int
    PCICR= BIT(PCIE0)|BIT(PCIE1);
    PCMSK1 = BIT(PCINT11);
    PCMSK0 = BIT(PCINT0);
}

/***********************************************************
*   函数说明:INT0中断处理程序                           *
*   输入:    无                                           *
*   输出:    无                                           *
*   调用函数:INSERT_INT0_ISR_CODE                         *
***********************************************************/
void INT0_ISR(void)
{
    INSERT_INT0_ISR_CODE
}

/***********************************************************
*   函数说明:INT1中断处理程序                           *
*   输入:    无                                           *
*   输出:    无                                           *
*   调用函数:INSERT_INT1_ISR_CODE                         *
***********************************************************/
void INT1_ISR(void)
{
    INSERT_INT1_ISR_CODE
}

/***********************************************************
*   函数说明:PCINT1中断处理程序                           *
*   输入:    无                                           *
*   输出:    无                                           *
*   调用函数:INSERT_PCINT1_ISR_CODE                     *
***********************************************************/
void PCINT1_ISR(void)
{
    INSERT_PCINT1_ISR_CODE
}

/***********************************************************
*   函数说明:PCINT0中断处理程序                           *
*   输入:    无                                           *
*   输出:    无                                           *
*   调用函数:INSERT_PCINT0_ISR_CODE                     *
***********************************************************/
void PCINT0_ISR(void)
{
    INSERT_PCINT0_ISR_CODE
}

xj_1232005 发表于 2008-7-8 14:26:57

to 【2楼】 Gorgon Meducer 傻孩子
谢谢 傻孩子兄 的热心帮助.
页: [1]
查看完整版本: to 傻孩子和各位大侠:为什么进不了PCINT0中断