PIC Vietnam

Go Back   PIC Vietnam > Microchip PIC > Cơ bản về vi điều khiển và PIC

Tài trợ cho PIC Vietnam
Trang chủ Đăng Kí Hỏi/Ðáp Thành Viên Lịch Bài Trong Ngày Vi điều khiển

Cơ bản về vi điều khiển và PIC Những bài hướng dẫn cơ bản nhất để làm quen với vi điều khiển PIC

 
 
Ðiều Chỉnh Xếp Bài
Prev Previous Post   Next Post Next
Old 13-05-2010, 11:13 AM   #1
baquyen
Đệ tử 2 túi
 
baquyen's Avatar
 
Tham gia ngày: May 2007
Bài gửi: 31
:
Cool Hỏi về cơ chế ngắt trong PIC 16F1887

Chào mọi người , mình đang làm luận văn tốt nghiệp về đề tài điều khiển động cơ DC bằng PIC 16f887. Mình dùng ngắt ngoài (chân RB0 và RB1) để đếm giá trị từ encoder . Đây là bản demo nên việc xác định góc quay của động cơ được xác định giá trị theo từng thời điểm thông qua timer0, có một việc lạ xảy ra trên mạch thực tế như sau: ban đầu mọi hoạt động của mạch đều như ý muốn, tuy nhiên sau đó do kênh B của encoder bị hỏng (RB1 ko nhận đc tín hiệu từ encoder) : chỉ cần cấp nguồn cho mạch là động cơ chạy luôn, như vậy nó đã bỏ qua 10.752s đầu tiên trong ngắt timer0 --> nó tiến hành ngay tức thời ngay lúc đóng mạch, động cơ quay liên tục không có giới hạn. Mình không hiểu điều gì đã xảy ra với ngắt Timer0, sự liên quan của nó với ngắt ngoài trên chân RB0, tại sao thiếu kênh B tại ngõ vào Rb1 lại làm VDK chạy bất thường như vậy, nhất là việc Timer0 định thời gian 10.752s--->0s ?
Đây là đoạn code:
Code:
//            : Dung Interrupt timer0 dinh cac vi tri dong co theo thoi gian
//======================================================== 

#include <16f887.h>
#device adc=8
#include <def_877a.h>
#include <stdio.h>
#include <stdlib.h>
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use fast_io(D)
#use fast_io(b)
#use delay(clock=12000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C7,rcv=PIN_C6,bits=8) 
                         //thiet ke nguoc hai chan C7 va C6//
int8 q;                  // q = 1 chieu thuan, q = 0 chieu nghich
signed int16 gtdem = 0;  // dem vi tri encoder 
signed int16 gtdat = 0;  // gia tri dat 
signed int16 y     = 0;  // do lech giua vi tri dat va gt dem 
int16 count        = 0;  // bien dem trong timer0, max = 65536       

//=============== ngat TIMER0 ========================//
         // thoi diem khac nhau thi gidat khac nhau //
 
#int_timer0
void interrupt_timer0()
{
   set_timer0(4); // 256 - 4 = 252 so nay chia het cho 3
   count++; // count tang len  1 sau 256*(256-4)*4/12M = 21.504 ms
   
   if(count==500) // 21.504*500 = 10.752 s
      {
      gtdat=100;  //90 do
      }
   if(count==1000) //21.504 s
      {
      gtdat=200; //180 do
      }
   if(count==1500) //32.256 s
      {
      gtdat=300;  //270 do
      }
   if(count==2000) //43.008 s
      {
      gtdat=400;  //360 do
      }
   if(count==2500)   //53.76 s
      {
      count=0;
      gtdat=0;
      }
   
}


//=============== ngat ngoai RB0 va RB1 ========================//
        //dem vi tri encoder (gtdem) va chieu quay (q)//
        
#INT_EXT
void encoder_EXT()
{
  // y=gtdat-gtdem;// de o day la ko on//
  
   if(rb1==0) // chieu thuan
   {
      gtdem++;
      q=0x00;
   }
   else       // chieu nghich
   {
      gtdem--;
      q=0xff;
   }
}

//====================== HAM CHINH ==============================//

void main()
{ 
   
   //=================== INTERRUPT ====================//
   
   //set_tris_b(0xff);
   set_tris_D(0x00);            // tat ca ngo d la output
   //portd=0x00;
   set_timer0(4);
   enable_interrupts(int_timer0);
   setup_timer_0(RTCC_internal|RTCC_div_256);
   ext_int_edge(l_to_h);
   //ext_int_edge(h_to_l);
   enable_interrupts(INT_EXT);
   enable_interrupts(Global);
   
   //===================== PWM ========================//
   
   setup_ccp1(ccp_pwm);
   setup_ccp2(ccp_pwm);
   setup_timer_2(T2_div_by_4,140,1); //TR2 = 140, prescale = 4
      // T = 4/12M*(140+1)*4 = 1.88*10^-4 s
      // f = 1/T = 5.319 kHz
      // Prescale value = ((1/PWM Frequency)/Prescale value * (4/OSC frequency))-1
      // PWM resolution = ( log ( OSC freq / PWM freq ) ) / log 2
   set_pwm1_duty(0);
   set_pwm2_duty(0);
      
   //================== DIEU KHIEN ===================//
   
   
 
   while(true)
     {
         y=gtdat-gtdem;
         portd=q; // xem chieu dong co qua tt PORTD
         if(y>0) // chua toi vi tri nen cho dc chay theo chieu thuan
           {
               set_pwm2_duty(0);
               set_pwm1_duty(30);
           }
         if(y==0) // ok roi`
           {
               set_pwm1_duty(0);
               set_pwm2_duty(0);
           }
         if(y<0)    // chay qua' roi, cho chay nguoc lai 
                    //(tai sao ko dung ELSE o day dc?)
           {
               set_pwm1_duty(0);
               set_pwm2_duty(30);
           }
     }

}

 //========================== KET THUC=============================//
Mạch thực tế được thiết kế tương tự trong file đính kèm (dùng proteus).
Nếu có ai phát hiện đc cái ko tối ưu trong đoạn code mong đc chỉ bảo thêm.
Hình Kèm Theo
File Type: jpg kkkkkkk.jpg (41.2 KB, 72 lần tải)
File Kèm Theo
File Type: zip LVTN.zip (25.3 KB, 260 lần tải)

thay đổi nội dung bởi: baquyen, 09-06-2010 lúc 08:42 PM.
baquyen vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
 


Quyền Sử Dụng Ở Diễn Ðàn
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is Mở
Smilies đang Mở
[IMG] đang Mở
HTML đang Tắt

Chuyển đến


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


Được sáng lập bởi Đoàn Hiệp
Powered by vBulletin®
Page copy protected against web site content infringement by Copyscape
Copyright © PIC Vietnam