PDA

View Full Version : Cần giúp đỡ về ngắt


foremostpirate
24-03-2011, 11:33 PM
Hiện tại em đang viết 1 chương trình sử dụng ngắt ngoài #INT_EXT và lệnh while(1), Switch(bien), case .Mỗi khi có ngắt bien sẽ tăng dần (bien++). Giả sử chương trình đang thực hiện lặp ở case 1, khi có ngắt xảy ra. Em muốn hỏi làm sao khi chương trình thoát ngắt, chương trình không quay lại vị trí cũ (trong case 1) để thực hiện tiếp mà sẽ chạy 1 case khác trong chương trình chính.

caremlanh
25-03-2011, 10:25 AM
khi đang ở case 1, có ngắt thì bien++, tức là sẽ chuyển sang case 2 chứ ko quay lại case1.
còn nếu muốn chuyển sang case 3 chẳng hạn thì mình dùng lệnh goto. bạn xem chương trình mình viết nha :)

tdm
25-03-2011, 10:59 AM
khi đang ở case 1, có ngắt thì bien++, tức là sẽ chuyển sang case 2 chứ ko quay lại case1.
còn nếu muốn chuyển sang case 3 chẳng hạn thì mình dùng lệnh goto. bạn xem chương trình mình viết nha :)
code của bạn:

#include <16f877a.h>
#include <def_877a.h>
#device *=16
#FUSES NOWDT, HS
#use delay(clock=20Mhz)

int8 bien=0, i=0;

#INT_EXT
void ngat_ngoai()
{

bien++;
if(bien>3)bien=0;//dem=0->3
if(bien==2)i=1;
else i=0;
}

void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_EXT);
ext_int_edge(H_TO_L);

trisb=0x01;
trisd=0;
portd=0x00;

while(true)
{
if(i==1)goto here;
switch(bien)
{
case 0: {portd=0x01;delay_ms(500); break;}
case 1: {portd=0x02;delay_ms(500); break;}
case 2: {portd=0x04;delay_ms(500); break;}
case 3: here: {portd=0x08;delay_ms(500); break;}
}
}

}


khi đang ở case 1, có ngắt thì bien++, tức là sẽ chuyển sang case 2 chứ ko quay lại case1.
nó sẽ không chuyển ngay mà phải đợi làm xong case 1 rồi nó mới chuyển.

caremlanh
25-03-2011, 02:16 PM
nó sẽ không chuyển ngay mà phải đợi làm xong case 1 rồi nó mới chuyển.

em nhầm, vậy có cách nào ko anh? Em bí luôn rồi :D

foremostpirate
25-03-2011, 05:44 PM
Vậy không có cách nào sao ? Hhuhuhu!!!!!!

tdm
25-03-2011, 08:31 PM
Vậy không có cách nào sao ? Hhuhuhu!!!!!!
tại sao lại không (nhưng cũng phải mất vài chu kỳ máy)

#include <16F877A.h>
#include <def_877a.h>
#include <DEFS_16F877A.h>
#device *=16 //su dung het ram trong pic
# fuses NOWDT, XT, NOPROTECT, NOLVP, PUT
# use delay (clock = 4000000)
void DELAY();
int8 bien=0,x=0,quay;
#int_ext
void ngat()
{
x=0xaa;
bien++;
if(bien>1)bien=0;//dem=0->2

}

void main()
{;
enable_interrupts(GLOBAL);
enable_interrupts(INT_EXT);
ext_int_edge(H_TO_L);
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8 );
set_timer1(0x0000);//thiet lap gia tri ban dau cho timer1
trisb=0x01;
trisd=0;
portd=0x00;

while(true)
{
switch(bien)
{
case 0: {
portd=0x01;
delay();
for(quay=0;quay<=7;quay++)
{
portd<<=1;//quay trai
delay();
if(x==0xaa)
{
x=0;
break;
}
}
break;}
case 1: {
portd=0x80;
delay();
for(quay=0;quay<=7;quay++)
{
portd>>=1;//quay phai
delay();
if(x==0xaa)
{
x=0;
break;
}
}
break;}

}
}

}
void delay(void)
{
int8 tam;
for(tam=0;tam<=2;tam++)
{
if(x==0xaa)
break;
set_timer1(0x0000);//thiet lap gia tri ban dau cho timer1
while(TMR1IF==0)
{
if(x==0xaa)
break;
}
TMR1IF=0;
}
}

tuthantuthuc
23-05-2011, 11:15 PM
Anh cho e hỏi trong chương trình trên khai báo timer 1 dùng để làm gì vậy? Có phải là dùng trong phần hàm delay ở cuối k? e k hiểu lắm ở chỗ này, khi cờ tràn TMRIF1==0 tức là cờ chưa tràn thì xét giá trị x, nếu x==0xaa thì lại thoát khỏi vòng lặp và cho TMRIF1=0, mục đích của việc này dùng để làm gì? và khi nó tràn(TMRIF1=1) thì sẽ ra sao?
while(TMR1IF==0)
{
if(x==0xaa)
break;
}
TMR1IF=0;
}