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
;
}
}
}
歡迎光臨 (http://www.raoushi.com/bbs/) | Powered by Discuz! X3.1 |