PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   Các ngôn ngữ lập trình khác (CCS C, HT PIC,...) (http://www.picvietnam.com/forum/forumdisplay.php?f=12)
-   -   Cần giúp đỡ về ngắt (http://www.picvietnam.com/forum/showthread.php?t=8247)

foremostpirate 24-03-2011 11:33 PM

Cần giúp đỡ về ngắt
 
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

1 Attachment(s)
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

Trích:

Nguyên văn bởi caremlanh (Post 42959)
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:
Code:

#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;}
  }
}

}

Trích:

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

Trích:

Nguyên văn bởi tdm (Post 42962)

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

1 Attachment(s)
Trích:

Nguyên văn bởi foremostpirate (Post 42978)
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)
Code:

#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;
}


Múi giờ GMT. Hiện tại là 08:20 PM.

Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam