View Single Post
Old 12-05-2009, 05:41 PM   #1
kiwi
Đệ tử 1 túi
 
Tham gia ngày: Jun 2005
Bài gửi: 13
:
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
   }
}

thay đổi nội dung bởi: kiwi, 12-05-2009 lúc 05:57 PM.
kiwi vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn