View Single Post
Old 21-08-2008, 11:44 AM   #4
phamminhtuan
Super Moderator
 
phamminhtuan's Avatar
 
Tham gia ngày: Feb 2006
Bài gửi: 150
:
Trích:
Nguyên văn bởi bazooka2006 View Post
Code:
#include <16F877A.h>
...
#priority rb,rda  

...
#int_RB
void rb_isr()            // ham phuc vu ngat RB
 {     
   int current; 
   int last;
   set_tris_b(0xff);
   current=input_b();
   last=current;
   delay_ms(50);
   set_tris_b(0xff);
   current=input_b();
   if (current==last)          
     {
      clear_interrupt(int_RDA);  
      if (!bit_test(current,4))     // ctac tren mam xoay bao ngat
       {   
        if (home)                     // chi thuc hien khi o che do home:
         {                              // quay mam ben phai 60 do 
           en_step1=0;
           count1=70;
           dir1=1;
           en_step1=1;
           while (count1>0)
            {
              count1--;
              if ((count1>30)&&(count1<(70-30)))
               {
                 rotate_high1();
               }
              else
               {
                 rotate_low1(); 
               }
            }
            count1=0;
 
          }
       }  
                  
      if (!bit_test(current,5))    // ctac trong bao ngat
       {                           
         en_step3=0;
         delay_ms(500);
         count3=2000;
         dir3=0;
         in_out();
       }
      
      if (!bit_test(current,6))     //ctac tren bao ngat   
       { 
         en_step2=0;
         delay_ms(500);
         count2=500;
         dir2=1;
         go_up_down();
         count2=0;
       }
          
      if (!bit_test(current,7))    // cam bien phat hien co vat den
       {
         putc('y');
         delay_ms(10);
       }
     }   
   clear_interrupt(int_RB);
 }

//**************************************************************** 
#int_RDA                  // ham phuc vu ngat noi tiep
void  RDA_isr() 
 {
   delay_us(50);
   ss=getc();
   if (ss=='u')           // di len
    {
       count2=2000;
       dir2=0;
       go_up_down();
       printf("done");
    }
      
   if (ss=='d')             // di xuong
    {
       count2=2000;
       dir2=1;
       go_up_down();
       printf("done");
    }
     
   if (ss=='l')              // quay trai
    {
       count1=70;            //1 lan quay 60 do
       dir1=0;
       left_right();
       printf("done");
    } 
    
   if (ss=='r')              // quay phai
    {
       count1=70;
       dir1=1;
       left_right();
       printf("done");
    }    
    
   if (ss=='i')               //di vao
    {
       count3=4000;           //1 lan di chuyen 30mm
       dir3=1;
       in_out();
       printf("done");
    }     
    
   if (ss=='o')              // di ra
    {
       count3=4000;
       dir3=0;
       in_out();
       printf("done");
    }   
    
   if (ss=='#')        // test comm
     {
       putc('!');
       delay_us(100);
     } 
    
   if (ss=='O')        // go home: dieu khien tay may 
    {                    // ve vi tri home
      home=1;
      count1=100;
      dir1=0;
      left_right();
      count2=2000;
      dir2=0;
      go_up_down();
      count3=2666;
      dir3=1;
      in_out();
      home=0;
    }
   
  if (ss=='1')        // chuong trinh di chuyen cho vat 1
    {
      count2=10000;   // chay xuong
      dir2=1;
      go_up_down();
      
      catch=1;        // gap vat
      
      count2=10000;   // di len
      dir2=0;     
      go_up_down();
      
      count1=102;    // xoay 90 do
      dir1=1;
      left_right();
      
      count3=13333;  // di ra
      dir3=0;
      in_out();
      
      count2=10000;   // ha xuong
      dir2=1;
      go_up_down();
      
      catch=0;        // nha vat
      
      count2=10000;   // di len
      dir2=0;     
      go_up_down();
      
      count1=102;     // xoay 90 do
      dir1=0;
      left_right();
      
      count3=13333;   // di vao
      dir3=1;
      in_out();

   }
   clear_interrupt(int_rda);
 }

void main() 
{   
    enable_interrupts(INT_RB|H_TO_L);
    enable_interrupts(GLOBAL);
    ext_int_edge(H_TO_L);
    enable_interrupts(INT_RDA);
    set_tris_d(0x00);
    set_tris_b(0xff);
    set_tris_a(0x00);
    printf("reset");

       
    while (1)
     { 
 
     }
}
Mình có quote cho bạn những đoạn code trên, bạn cần lưu ý những điều sau để tự sửa lại chương trình:
  • Trong PIC16F877A không có ưu tiên ngắt, do đó chỉ dẫn #priority không có tác dụng
  • Khi xảy ra bất kì 1 ngắt nào, thì GIE = 0 để tránh xảy ra các ngắt chồng nhau, nó chỉ được set = 1 khi có lệnh RETFIE, có nghĩa là khi xảy ra 1 ngắt bất kì thì chỉ khi thực hiện xong ngắt đó mới có thể giải quyết ngắt tiếp theo
  • Khi xử lý 1 ngắt, trước khi kết thúc trình phục vụ ngắt, bạn phải xóa cờ ngắt đó bằng lệnh clear_interrupt();, nếu không sau khi thoát ra khỏi ngắt đó, nó sẽ quay trở lại
  • enable_interrupts(INT_RB|H_TO_L); không có OR với H_TO_L, tuy nhiên do giá trị H_TO_L = 0, nên chương trình bạn không bị ảnh hưởng
  • Dưới đây là file list C/ASM đơn giản để bạn thấy rõ điều đó
PHP Code:
#include<16f877a.h>
#use delay(clock=4Mhz)
#use rs232(baud=9600, UART1)
#INT_RDA
void rda(){
   
unsigned char c;
   
getc(); //Lệnh này sau khi đọc xong kí tự, thì cờ ngắt tự động bị xóa
   
output_b(0xAA);
}

#INT_RB
void rb(){
   
output_b(0x55);
   
clear_interrupt(INT_RB);
}

void main(){
   
enable_interrupts(INT_RDA);
   
enable_interrupts(INT_RB);
   
enable_interrupts(GLOBAL);
   
   while(
1);

đây là file list, lược bớt đoạn đầu, là đoạn chỉ lưu các thanh ghi và lựa chọn nhảy đến vị trí các chương trình phục vụ ngắt, không hề có lệnh nào xóa cờ ngắt
PHP Code:
.................... #INT_RDA 
.................... void rda(){ 
....................    
unsigned char c
....................    
getc(); 
003C:  BTFSS  0C.5
003D
:  GOTO   03C
003E
:  MOVF   1A,W
003F
:  MOVWF  28
....................    output_b(0xAA); 
0040:  BSF    03.5
0041
:  CLRF   06
0042
:  MOVLW  AA
0043
:  BCF    03.5
0044
:  MOVWF  06
.................... } 
....................  
0045:  BCF    0C.5
0046
:  BCF    0A.3
0047
:  BCF    0A.4
0048:  GOTO   023
.................... #INT_RB 
.................... void rb(){ 
....................    
output_b(0x55); 
0049:  
BSF    03.5
004A
:  CLRF   06
004B
:  MOVLW  55
004C
:  BCF    03.5
004D
:  MOVWF  06
....................    clear_interrupt(INT_RB); 
004E:  BCF    0B.0 //Chỉ khi có lệnh này, thì cờ ngắt của INT_RB mới được xóa
.................... } 
phamminhtuan vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn