atmega16 中斷跑飛,跑錯(cuò)中斷問題,請(qǐng)幫忙解決?
大家好,下面是我寫的一個(gè)程序,實(shí)現(xiàn),外部中斷2觸發(fā)的時(shí)候?qū)崿F(xiàn)電機(jī)向前運(yùn)動(dòng),為什么每次外部中斷來的時(shí)候會(huì)跳進(jìn)外部中斷0里面?請(qǐng)幫忙看下,并且是有時(shí)會(huì),有時(shí)不會(huì),,請(qǐng)問是什么原因,外面接三個(gè)繼電器由PA0-2控制,和一個(gè)電機(jī)由PB0控制。 //貼片機(jī)項(xiàng)目改裝 #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 半流/全流方式 //定義驅(qū)動(dòng)器一圈分布數(shù) //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 //定義步進(jìn)電機(jī)脈沖寬度,前進(jìn)速率 //speed 越小速度越快,電機(jī)轉(zhuǎn)動(dòng)越快 #define speed1 100 #define speed2 100 //定義傳輸給上位機(jī)的脈沖寬度 //pul_interval 越小間隔越小 #define pul_interval 1000 #define wait_1s 20000; #define wait_2s 50000; unsigned int START_NO=1; //板到標(biāo)志 unsigned int NO_Board=1; //步進(jìn)電機(jī)轉(zhuǎn)動(dòng)標(biāo)志 unsigned int NO_Completed=1; //貼片完成標(biāo)志 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--) { //如若貼片機(jī)完成后,等待電機(jī)轉(zhuǎn)動(dòng)時(shí)間稍微有點(diǎn)長(zhǎng)的話,就把55改為更小的數(shù) for(j=55;j>0;j--); //但是如果太小,則無法辨別干擾。 } } void Wait_2S() { unsigned int i,j; i=wait_2s; j=55; while(i--) { //如若貼片機(jī)完成后,等待電機(jī)轉(zhuǎn)動(dòng)時(shí)間稍微有點(diǎn)長(zhǎng)的話,就把55改為更小的數(shù) for(j=55;j>0;j--); //但是如果太小,則無法辨別干擾。 } } //脈沖寬度延遲函數(shù) void Pul_Delay() { unsigned int i=0; i=speed1; while(i--); } //延遲函數(shù) void Delay(int i) { unsigned long x=5000; x*=i; while(x--); } void wait_Soft_Board() { GICR=0x40; //開通中斷0,關(guān)閉中斷1、2 } void Wait_Board_Completed() { PORTA=0x07; //通知上位機(jī)板拿走了 Delay(30); //延遲一段時(shí)間后通知上位機(jī)板就位,延長(zhǎng)時(shí)間100可根據(jù)之前的系統(tǒng)的值進(jìn)行設(shè)置 PORTA=0x06; //通知上位機(jī)板進(jìn)來了 Delay(30); //延遲一段時(shí)間后通知上位機(jī)板就位,延長(zhǎng)時(shí)間100可根據(jù)之前的系統(tǒng)的值進(jìn)行設(shè)置 PORTA=0x05; //通知板就位 GICR=0x60;//開通中斷2,中斷0 }
void Interrupt_Init() { MCUCR |= (1 << ISC01)| (0 << ISC00); //INT0,1為上升沿轉(zhuǎn)換觸發(fā) MCUCSR |= (1<<6); //INT2為下降沿觸發(fā) GICR|=BIT(6)|BIT(5); //GICR|=0xC0; INT0,1中斷允許位為1 GIFR|=BIT(6)|BIT(5); //GIFR|=0xC0; INTO,1中斷標(biāo)志位清零 } void Sensor1_Board_Come() { GICR=0x00; //關(guān)閉中斷0、1、2 Wait_2S(); //適當(dāng)防干擾,時(shí)間數(shù)值調(diào)試中設(shè)定 if((PIND&0x04)==0x00) //保證相當(dāng)一段時(shí)間PD2輸入為低電平 { NO_Board=0; //板到標(biāo)志 restart=1; GICR=0x60; //重新開中斷0 } else { NO_Board=1; // 如果只是一時(shí)的觸動(dòng)干擾,認(rèn)為沒進(jìn)柔性電路板 GICR=0x60; //重新開中斷0 } }
void Sensor3_Board_Completed() { GICR=0x00; //關(guān)閉中斷0、1、2 Wait_1S(); //適當(dāng)防干擾,考慮到擋桿動(dòng)作迅速,時(shí)間可稍微減少, if((PINB&0x04)==0x04) //PB2是否為高電平 { NO_Completed=0; GICR=0x60; } else { NO_Completed=1; GICR=0x60;//開通中斷2,關(guān)閉中斷0、1 } } //IO初始化函數(shù) void Port_Init() { //PA0、1、2為帶上拉輸出,支持上位機(jī)通信,接繼電器 DDRA=0x0f; PORTA=0x0F; //PA0、1、2輸出高電平,繼電器不通 //PB0為輸出,為步進(jìn)電機(jī)輸出脈沖控制電機(jī)轉(zhuǎn)動(dòng) DDRB=0x01; //PB0為輸出狀態(tài),PB2為中斷輸入口 PORTB|=BIT(2); DDRD|=BIT(PD6); //PD6為輸出狀態(tài) PORTD&=~BIT(PD6); //PD6為輸出低電平 DDRD&=~BIT(2)&~BIT(3); //PD2~3為輸入狀態(tài),外部中斷0、1輸入 PORTD|=BIT(2)|BIT(3); //PD2~3帶上拉輸入 } //主函數(shù) void main() { unsigned int j=0; //一圈步數(shù)參數(shù)設(shè)定 unsigned int completed_num; //貼片完成次數(shù) unsigned int rotation_num=0; //轉(zhuǎn)動(dòng)圈數(shù) WDTCR=0x18; //啟動(dòng)看門狗 WDTCR=0x10; //關(guān)閉看門狗 Interrupt_Init(); //中斷初始化 Port_Init(); //端口初始化,PA0、1、2作為三個(gè)接近開關(guān)輸入信號(hào) GICR=0x60; //開通中斷0,2 SREG|=BIT(7); //開總中斷 PORTD&=~BIT(6); //控制步進(jìn)電機(jī)驅(qū)動(dòng)器的使能端,讓其不工作,以免步進(jìn)電機(jī)空載發(fā)熱。 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 ; } } }
|