PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   Cơ bản về vi điều khiển và PIC (http://www.picvietnam.com/forum/forumdisplay.php?f=8)
-   -   Sử dụng nhiều ngắt, cần chú ý những gì? (http://www.picvietnam.com/forum/showthread.php?t=4104)

kiwi 12-05-2009 05:41 PM

Sử dụng nhiều ngắt, cần chú ý những gì?
 
Trong chương trình điều khiển động cơ bằng PWM của Pic 16F877A, mình muốn dùng các ngắt sau cho chương trình:
- ngắt TIMER0 ở chế độ counter, ngắt TIMER1 ở chế độ timer phục vụ cho việc xác định tốc độ.
- ngắt RB dùng cho bàn phím để nhập tốc độ vào.
Như vậy có ổn không, nếu được thì cần chú ý những gì?
Rất mong sự giúp đỡ.
Mình là chương trình em mới viết (không chạy được, vì sao?)
Code:

#include <Doc encoder.h>
#include <def_877a.h>
#include <lcd_lib_4bit.c>
#use delay(clock=4000000)

int8 int_count1;
int16 tddc,count;
int16 tocdodat;
int16 value;

int8  key;
int16 tocdomoi;//tocdomoi: toc do dang nhap, tocdodat: toc do duoc chon

void row_check(int8 row);

#define So_lan_tran_T1 1
//so_lan_tran_t1 = 1 => cu 1*50000*4=200000us=0.2s thi T1 se tran
#define  key_port PORTB
#define  key_tris TRISB

#int_rtcc // Ngat Timer 0
void Timer0_isr()//ngat timer0
{
  count++;
}

#INT_TIMER1 // Chuong trinh ngat Timer 1
void Timer1_isr()
{
  if(--int_count1==0)
  {
      tddc = (count * 256 + get_timer0()) * 3; // cu 0.2s thi dem xung, tddc(v/p)= soxung*(60s/0.2s)/100
      int_count1 = So_lan_tran_T1;
      count = 0;
      set_timer0(0);
  }
  SET_TIMER1(15535);
}

#INT_RB
void key_scan(int8 count)
{
  if((RBIF)&&(RBIE))
  {
      for(count = 4;count <= 7; count++)
      {
        key_tris = 0xF0;                    // hang ngo vao, cot ngo ra
        key_port = 0xF0;                    // hang muc 1, cot muc 0
        if(!bit_test(key_port,count))      // hang count xuong 0 chua?
        {
            delay_ms(10);                    // sau 10ms
            if(!bit_test(key_port,count))    // kiem tra lai hang count co xuong 0 ko?
            {
              key_tris = 0x0F;              // hang ngo ra, cot ngo vao
              switch(count)
              {
                  case 4:
                  {
                    key_port = 0xEF;        // hang 0 xuong 0
                    row_check(0);          // kiem tra cot ung voi hang 0
                  }
                  break;
                  case 5:
                  {
                    key_port = 0xDF;        // hang 1 xuong 0
                    row_check(1);          // kiem tra cot ung voi hang 1
                  }
                  break;
                  case 6:
                  {
                    key_port = 0xBF;        // hang 2 xuong 0
                    row_check(2);          // kiem tra cot ung voi hang 2
                  }
                  break;
                  case 7:
                  {
                    key_port = 0x7F;        // hang 3 xuong 0
                    row_check(3);          // kiem tra cot ung voi hang 3
                  }
                  break;
              }
            }
        }
      }
     
      if(tocdomoi>9999)
      {
        tocdomoi = 0;
        LCD_PutCmd(0x01);
      }
      if(key==11)
      {
        tocdodat=tocdomoi;
        LCD_SetPosition(line_1);
        printf(lcd_putchar,"Tocdodc: %04lu",tddc);
        LCD_SetPosition(line_2);
        printf(lcd_putchar,"Tocdodat: %04lu",tocdodat);
      }
        else
        {
            LCD_SetPosition(line_1);
            printf(lcd_putchar,"Tocdodc: %04lu",tddc);
            LCD_SetPosition(line_2);
            printf(lcd_putchar,"Nhaptocdo: %04lu",tocdomoi);
        }           
      set_tris_b(0b11110000);
  }
  RBIF=0; //Xoa co ngat RB
}

void row_check(int8 row)

  switch(row)
  {
//.............................//
      case 0:                                  // truong hop hang 0 bang 0
      {
        if(!bit_test(key_port,0))              // neu cot 0 bang 0
        {
            while(!bit_test(key_port,0));
            key = 7;
            tocdomoi = tocdomoi*10 + key;
            //printf("%u\n\r",led_port);
        }
        if(!bit_test(key_port,1))              // neu cot 1 bang 0
        {
            while(!bit_test(key_port,1));
            key = 8;
            tocdomoi = tocdomoi*10 + key;
            //printf("%u\n\r",led_port);
        }
        if(!bit_test(key_port,2))              // neu cot 2 bang 0
        {
            while(!bit_test(key_port,2));
            key = 9;
            tocdomoi = tocdomoi*10 + key;
            //printf("%u\n\r",led_port);
        }
        if(!bit_test(key_port,3))              // neu cot 3 bang 0
        {
            while(!bit_test(key_port,3));
            key = 0;
            tocdomoi = tocdomoi*10 + key;
            //printf("%u\n\r",led_port);
        }
        break;
      }
//.............................//
        case 1:                                // truong hop hang 1 bang 0
      {
        if(!bit_test(key_port,0))
        {
            while(!bit_test(key_port,0));
            key = 4;
            tocdomoi = tocdomoi*10 + key;
            //printf("%u\n\r",led_port);
        }
        if(!bit_test(key_port,1))
        {
            while(!bit_test(key_port,1));
            key = 5;
            tocdomoi = tocdomoi*10 + key;
            //printf("%u\n\r",led_port);
        }
        if(!bit_test(key_port,2))
        {
            while(!bit_test(key_port,2));
            key = 6;
            tocdomoi = tocdomoi*10 + key;
            //printf("%u\n\r",led_port);
        }
        if(!bit_test(key_port,3))
        {
            while(!bit_test(key_port,3));
//            tocdodat = tocdomoi;                      //===>>> phim OK, dong y toc do
            key = 11;
            //printf("%u\n\r",led_port);
        }
        break;
      }
//.............................//
      case 2:
      {
        if(!bit_test(key_port,0))
        {
            while(!bit_test(key_port,0));
            key = 1;
            tocdomoi = tocdomoi*10 + key;
            //printf("%u\n\r",led_port);
        }
        if(!bit_test(key_port,1))
        {
            while(!bit_test(key_port,1));
            key = 2;
            tocdomoi = tocdomoi*10 + key;
            //printf("%u\n\r",led_port);
        }
        if(!bit_test(key_port,2))
        {
            while(!bit_test(key_port,2));
            key = 3;
            tocdomoi = tocdomoi*10 + key;
            //printf("%u\n\r",led_port);
        }
        if(!bit_test(key_port,3))
        {
            while(!bit_test(key_port,3));
            bit_clear(tocdomoi,0);
            tocdomoi=tocdomoi/10;                //===>>> phim back, xoa 1 so
           

            //printf("%u\n\r",led_port);
        }
        break;
      }
//.............................//
      case 3:
      {
        if(!bit_test(key_port,0))
        {
            while(!bit_test(key_port,0));
//            if(lcd_on_off)            //===>>> bat tat LCD
//              lcd_Putcmd(0x08);
//            else
//              lcd_Putcmd(0x0C);
//            lcd_on_off++;

            //printf("%u\n\r",led_port);
        }
        if(!bit_test(key_port,1))
        {
            while(!bit_test(key_port,1));
            key = 14;                    //===>>> Dung dong co

            //printf("%u\n\r",led_port);
        }
        if(!bit_test(key_port,2))
        {
            while(!bit_test(key_port,2));
            key = 15;                    //===>>> quay thuan

            //printf("%u\n\r",led_port);
        }
        if(!bit_test(key_port,3))
        {
            while(!bit_test(key_port,3));
            key = 16;                    //===>>> quay nguoc

            //printf("%u\n\r",led_port);
        }
        break;
      }
  }
}

void init()

  int_count1 = So_lan_tran_T1;//5 lan 1 giay
  setup_timer_0 (RTCC_DIV_1|RTCC_EXT_H_TO_L);  // Timer0 is Counter
  set_timer0(0);
  set_timer1(15535);
  setup_timer_1(T1_INTERNAL | T1_DIV_BY_4);    // Timer1 is Timer
  enable_interrupts(INT_RTCC);
  enable_interrupts(INT_TIMER1);
  enable_interrupts(GLOBAL);
 
  enable_interrupts(int_RB);
  ext_int_edge(H_to_L);
  set_tris_b(0b11110000);
 
  tddc=0;
  tocdodat=3000;
  tocdomoi=0;
  value=800;
  key=0;
 
  count = 0;
///////////////////////
  setup_ccp2(CCP_PWM);
  setup_timer_2(T2_DIV_BY_4, 249, 1);//1khz
 
  lcd_init();
  delay_ms(200);
  RD2 = 1;
  trisD = 0;
  TRISA = 0xFF;
 
}

void main()
{
  init();
  while(1) // doan chuong trinh tinh toan gia tri pwm, hien thi len LCD
  {
///////////TINH TOAN ON DINH TOC DO///////////////////
      if(value<=1000)
      {
        if (tddc>tocdodat)
        {
            if((tddc-tocdodat)>200)
              value=value-10;
            else
              value=value-1;
        }
            else
            {
              if((tocdodat-tddc)>200)
                  value=value+10;
              else
                  value=value+1;
            }
      set_pwm2_duty(value);
      }
      else
        value=1000;
///////////////////////////////////////////////////////////
      LCD_PutCmd (0x01);//clear lcd
  }
}


lequocbao 14-05-2009 12:58 PM

vậy thì làm sao bác xác định chiều quay?
theo mình bạn nên chọn :
-timer1 chế độ couter 16 bit để đếm xung vào từ encoder.
-rb0 kiểm tra chiều quay.
- còn lại timer2 lấy mẩu để bít tốc độ của thằng ku dcdc.
- timer0 làm việc khác khè ...khè...


Múi giờ GMT. Hiện tại là 02:51 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