Thông báo

Collapse
No announcement yet.

Vấn đề xung đột ngắt trong PIC16F877A

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Vấn đề xung đột ngắt trong PIC16F877A

    Mình đang viết 1 chương trình điều khiển động cơ 1 chiều, dữ liệu được nhập từ máy tính. Trong chương trình có dùng 3 ngắt là RDA, RB0 và ngắt của timer1 để tạo chu kỳ trích mẫu.
    Có điều đáng nói là khi chạy thì chương trình thường bị treo sau khoảng 1-2s. Mình nghĩ là có xung đột về ngắt nên đã disable ngắt RDA sau khi nhận được dữ liệu từ máy tính. Và quả thật sau khi disable thì chương trình chạy ngon.
    Tuy nhiên, khi đang chạy mà muốn truyền thêm dữ liệu từ PC xuống để thay đổi các thông số thì lại ko được (Vì đã disable ngắt RDA). Mình đã thử nhiều cách nhưng vẫn không thay đổi được gì.
    Mong mọi người cho ý kiến để cải thiện chương trình của mình. Thanks.
    Sau đây là chương trình của mình, dùng trình biên dich CCS:
    Code:
    #include <16f877a.h>
    #include <def_877a.h>
    #include <stdlib.h>
    #fuses  NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT 
    #use delay(clock=20000000)
    #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8) 
    #include <lcd_lib_4bit.c>
    void ht(int16 a);
    void init();
    void pid();
    void nhapheso();
    void display(int16 n);
    void truyen();
    int16 count=0, tocdo=0, C, temp, temp1, k, tocdodat ;
    signed int16 e2=0;
    signed int16 e1=0;
    int16 e_sum=0;
    int16 e_del=0;
    int16 duty=0;
    float Kp=0;
    float Ki=0;
    float Kd=0;
    int flag=0;
    float u, T=0.01;
    
    unsigned char text[30], text2[5] ;
    unsigned char a1[5], dem=0, i=0, j=0,i1=0;
    
    #INT_RDA
    void Receive_isr() 
    {
    text[dem]=getc();
    if(text[dem]=='@') //kiem tra dieu kien ket thuc
       {
       flag =1;    //ket thuc nhan, bat co bao
       dem=0;
       }
    else dem++;
    }
    #INT_EXT
    void ngatR0()  {
          
          count++;//set_timer0(0);
             
          }
    #int_timer1
    void Timer11_isr() {                // Ham duoc goi khi TImer1 tran (65535->0)
    
          set_timer1(53036);
          tocdo= 30*(count + get_timer0());
         // printf("%ld\t",tocdo);
          count = 0;
          set_timer0(0);
    
        }
    void main(){
    init();
    lcd_putcmd(0x01);
    while(true){
    truyen();                //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
          pid();
    if(RC1==0) set_PWM1_duty(duty);
    if(RC1==1) set_PWM1_duty(1023 - duty);  
    lcd_putcmd(0x80);
    ht(tocdo);
    printf("n%4Lu",tocdo);
    display(tocdo);
    
    //lcd_putchar("hi");
    
    
    }
    }
    void init()
    {
       lcd_init();
       nhapheso();
       setup_timer_0 (RTCC_DIV_1|RTCC_EXT_L_TO_H);  // Timer0 is Counter
       setup_timer_1(T1_INTERNAL | T1_DIV_BY_4);
       setup_ccp1(CCP_PWM);
       setup_timer_2(T2_DIV_BY_4, 255, 1);//4*4*256*1/20000000=204.8us=4.8khz
       set_timer0(0);
       set_timer1(53036);
       enable_interrupts(INT_RTCC);
       enable_interrupts(int_timer1);
       enable_interrupts(int_ext);
       ext_int_edge(L_TO_H);
       enable_interrupts(GLOBAL);
       lcd_putcmd(0x80);
       count=0;
       trisc=0;
       trisd=0;
       trisa=255;
       trisb=1;
    
       }
    void pid(){
       e2 = tocdodat - tocdo;
       e_sum += e2;
    //   e_del = e2 - e1;
    //   e1 = e2;
       u = u + Kp*e2 + Ki*e_sum*T;
       if (u>24){
       u=24;
       e_sum -=e2;
       }
       if (u<0){
       u = 0;
       e_sum -=e2;
       }
      duty = u*1023/24;
    }
    void ht(long a) {
         int nghin,tram,chuc,dvi;
         nghin=a/1000;
         tram=(a%1000)/100;
         chuc=(a%100)/10;
         dvi=(a%10);
         lcd_putchar(nghin+48);
         lcd_putchar(tram+48);
         lcd_putchar(chuc+48);
         lcd_putchar(dvi+48);
    }
    void nhapheso(){
       lcd_putchar("nhap tu PC");
       enable_interrupts(int_rda);
       enable_interrupts(GLOBAL);   
    while(!flag) ;
    
    }
    void truyen()
    {
       enable_interrupts(int_rda);
       enable_interrupts(GLOBAL);       
    if(flag){
    
                  //if ((strchr(text,'T')) && (strrchr(text, '@')))
             
                    text2[0] = text[0];
                    text2[1] = text[1];
                    text2[2] = text[2];
                    text2[3] = text[3];
                    text2[4] = text[4];
                    tocdodat = atol(text2);
                   
                    //----------------------------------------
                      while (text[i] != 'P')
                        i++;
                      while (text[j] != 'I')
                        j++;
                      i1 = i;
                      temp = j - i;                  
                      for (i = 0; i < temp; i++)
                        a1[i] = text[i1 + i + 1];
                        
                      Kp = atof(a1);
                     
                      printf("P%f",Kp);
                       delay_ms(100);   
                      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
                      i = j;
                      while (text[j] != 'D')
                        j++;
                      i1 = i;
                      temp = j - i;                  
                      for (i = 0; i < temp; i++)
                        a1[i] = text[i1 + i + 1];
                        
                      Ki = atof(a1);
                      printf("I%f",Ki);
                         delay_ms(100);
                      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
                      i = j;
                      while (text[j] != 'C')
                        j++;
                      i1 = i;
                      temp = j - i;                  
                      for (i = 0; i < temp; i++)
                        a1[i] = text[i1 + i + 1];
                        
                      Kd = atof(a1);
                      printf("D%f",Kd);
                         delay_ms(100);
                      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
                      i = j;
                      while (text[j] != '@')
                        j++;
                      i1 = i;
                      temp = j - i;                  
                      for (i = 0; i < temp; i++)
                        a1[i] = text[i1 + i + 1];
                        
                      C = atol(a1);
                      printf("C%Lu",C);
                      flag=0;
                      i=0; j=0;
                      dem=0;
                      if(C==1) RC1=1;
                      If(C==0) RC1=0;
                      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
                                                    
              } 
    disable_interrupts(int_rda);
    disable_interrupts(global);
    }
    void display(int16 n){
    int nghin,tram,chuc,dvi;
    nghin = n/1000;
    tram = (n%1000)/100;
    chuc = (n%100)/10;
    dvi = n%10;
    PORTB=dvi<<1; RD0=0; delay_ms(1);RD0=1;
    PORTB=chuc<<1; RD1=0; delay_ms(1);RD1=1;
    PORTB=tram<<1; RC4=0; delay_ms(1);RC4=1;
    PORTB=nghin<<1; RC5=0; delay_ms(1);RC5=1;
    
    }

  • #2
    Trong vòng lặp của chương chình chính bạn nên đặt đoạn cod kiểm tra xem có dử liệu từ PC truyền đến(đầu vòng lặp) .Nếu có thì xử lý theo ý bạn nếu không thì thực hiện theo ct hiện có.
    Chúc bạn thành công.

    Comment

    Về tác giả

    Collapse

    tungbka Tìm hiểu thêm về tungbka

    Bài viết mới nhất

    Collapse

    Đang tải...
    X