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);
}*/
} 我想楼主可能理解错了。
引脚电平变化中断实际上只有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个引脚电平变化中断引脚中的哪一个或哪几个来触发。 这是一个使用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
} to 【2楼】 Gorgon Meducer 傻孩子
谢谢 傻孩子兄 的热心帮助.
页:
[1]