|
这是在傻孩子的旋转编码器代码基础上做的用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]);
}*/
} |
|