搜索
bottom↓
回复: 4

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

[复制链接]

出0入0汤圆

发表于 2008-7-6 20:08:00 | 显示全部楼层 |阅读模式
这是在傻孩子的旋转编码器代码基础上做的用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[4];

    Init_Device();

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

出0入296汤圆

发表于 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个引脚电平变化中断引脚中的哪一个或哪几个来触发。

出0入296汤圆

发表于 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)
{
    //INT0  INT1
    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
}

出0入0汤圆

 楼主| 发表于 2008-7-8 14:26:57 | 显示全部楼层
to 【2楼】 Gorgon Meducer 傻孩子
谢谢 傻孩子兄 的热心帮助.
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-5-5 05:02

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

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