atmega16 中断跑飞,跑错中断问题,请帮忙解决?
[复制链接]
大家好,下面是我写的一个程序,实现,外部中断2触发的时候实现电机向前运动,为什么每次外部中断来的时候会跳进外部中断0里面?请帮忙看下,并且是有时会,有时不会,,请问是什么原因,外面接三个继电器由PA0-2控制,和一个电机由PB0控制。
//贴片机项目改装 #include "iom16v.h" #include "macros.h" #pragma interrupt_handler Sensor1_Board_Come:2 #pragma interrupt_handler Sensor3_Board_Completed:19 //1. SW1 ON SW2 ON SW3 ON 2A //2. SW1 OFF SW2 ON SW3 ON 2.57A //3. SW1 ON SW2 OFF SW3 ON 3.14A //4.SW1 OFF SW2 OFF SW3 ON 3.71A //5.SW1 ON SW2 ON SW3 OFF 4.28A //6.SW1 OFF SW2 ON SW3 OFF 4.86A //7.SW1 ON SW2 OFF SW3 OFF 5.43A //8.SW1 OFF SW2 OFF SW3 OFF 6.0A //9.SW4 半流/全流方式 //定义驱动器一圈分布数 //SW5 ON SW6 OFF SW7 ON SW8 ON //SW5 OFF SW6 ON SW7 ON SW8 OFF #define bushu0 2000 //SW5 ON SW6 OFF SW7 ON SW8 OFF #define bushu1 4000 //SW5 OFF SW6 OFF SW7 ON SW8 OFF #define bushu2 5000 //SW5 ON SW6 ON SW7 OFF SW8 OFF #define bushu3 8000 //SW5 OFF SW6 ON SW7 OFF SW8 OFF #define bushu4 10000 //SW5 ON SW6 OFF SW7 OFF SW8 OFF #define bushu5 20000 //SW5 OFF SW6 OFF SW7 OFF SW8 OFF #define bushu6 42680
//定义步进电机脉冲宽度,前进速率 //speed 越小速度越快,电机转动越快 #define speed1 100 #define speed2 100 //定义传输给上位机的脉冲宽度 //pul_interval 越小间隔越小 #define pul_interval 1000 #define wait_1s 20000; #define wait_2s 50000;
unsigned int START_NO=1; //板到标志 unsigned int NO_Board=1; //步进电机转动标志 unsigned int NO_Completed=1; //贴片完成标志 unsigned int restart=1;
void pul_delay2() { unsigned int i=0; i=speed2; while(i--); } void Wait_1S() { unsigned int i,j; i=wait_1s; j=55; while(i--) { //如若贴片机完成后,等待电机转动时间稍微有点长的话,就把55改为更小的数 for(j=55;j>0;j--); //但是如果太小,则无法辨别干扰。 } }
void Wait_2S() { unsigned int i,j; i=wait_2s; j=55; while(i--) { //如若贴片机完成后,等待电机转动时间稍微有点长的话,就把55改为更小的数 for(j=55;j>0;j--); //但是如果太小,则无法辨别干扰。 } }
//脉冲宽度延迟函数 void Pul_Delay() { unsigned int i=0; i=speed1; while(i--); } //延迟函数 void Delay(int i) { unsigned long x=5000; x*=i; while(x--); } void wait_Soft_Board() { GICR=0x40; //开通中断0,关闭中断1、2 }
void Wait_Board_Completed() { PORTA=0x07; //通知上位机板拿走了 Delay(30); //延迟一段时间后通知上位机板就位,延长时间100可根据之前的系统的值进行设置 PORTA=0x06; //通知上位机板进来了 Delay(30); //延迟一段时间后通知上位机板就位,延长时间100可根据之前的系统的值进行设置 PORTA=0x05; //通知板就位 GICR=0x60;//开通中断2,中断0 }
void Interrupt_Init() { MCUCR |= (1 << ISC01)| (0 << ISC00); //INT0,1为上升沿转换触发 MCUCSR |= (1<<6); //INT2为下降沿触发 GICR|=BIT(6)|BIT(5); //GICR|=0xC0; INT0,1中断允许位为1 GIFR|=BIT(6)|BIT(5); //GIFR|=0xC0; INTO,1中断标志位清零 }
void Sensor1_Board_Come() { GICR=0x00; //关闭中断0、1、2 Wait_2S(); //适当防干扰,时间数值调试中设定 if((PIND&0x04)==0x00) //保证相当一段时间PD2输入为低电平 { NO_Board=0; //板到标志 restart=1; GICR=0x60; //重新开中断0 } else { NO_Board=1; // 如果只是一时的触动干扰,认为没进柔性电路板 GICR=0x60; //重新开中断0 } }
void Sensor3_Board_Completed() { GICR=0x00; //关闭中断0、1、2 Wait_1S(); //适当防干扰,考虑到挡杆动作迅速,时间可稍微减少, if((PINB&0x04)==0x04) //PB2是否为高电平 { NO_Completed=0; GICR=0x60; } else { NO_Completed=1; GICR=0x60;//开通中断2,关闭中断0、1 } }
//IO初始化函数 void Port_Init() { //PA0、1、2为带上拉输出,支持上位机通信,接继电器 DDRA=0x0f; PORTA=0x0F; //PA0、1、2输出高电平,继电器不通 //PB0为输出,为步进电机输出脉冲控制电机转动 DDRB=0x01; //PB0为输出状态,PB2为中断输入口 PORTB|=BIT(2); DDRD|=BIT(PD6); //PD6为输出状态 PORTD&=~BIT(PD6); //PD6为输出低电平 DDRD&=~BIT(2)&~BIT(3); //PD2~3为输入状态,外部中断0、1输入 PORTD|=BIT(2)|BIT(3); //PD2~3带上拉输入 }
//主函数 void main() { unsigned int j=0; //一圈步数参数设定 unsigned int completed_num; //贴片完成次数 unsigned int rotation_num=0; //转动圈数 WDTCR=0x18; //启动看门狗 WDTCR=0x10; //关闭看门狗 Interrupt_Init(); //中断初始化 Port_Init(); //端口初始化,PA0、1、2作为三个接近开关输入信号 GICR=0x60; //开通中断0,2 SREG|=BIT(7); //开总中断 PORTD&=~BIT(6); //控制步进电机驱动器的使能端,让其不工作,以免步进电机空载发热。 while(1) { wait_Soft_Board(); NO_Board=1; while(NO_Board); Wait_Board_Completed(); restart=0; for(completed_num=0;completed_num<11;completed_num++) { NO_Completed=1; while(NO_Completed); if(restart) break; else ; PORTA=0x03; PORTD|=BIT(6); for(rotation_num=0;rotation_num<2;rotation_num++) { j=0; while(j<=bushu6) { PORTB&=~BIT(0); //PB0输出低电平 Pul_Delay(); PORTB|=BIT(0); //PB0输出高电平 Pul_Delay(); j++; } } PORTD&=~BIT(6); if(completed_num<10) Wait_Board_Completed(); else ; } } }
[ 本帖最后由 wuyiliwenjie 于 2012-7-7 11:22 编辑 ]
|