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

Trả lời
 
Ðiều Chỉnh Xếp Bài
Old 30-03-2009, 07:24 PM   #1
vagabondtt1503
Đệ tử 2 túi
 
Tham gia ngày: Dec 2008
Bài gửi: 33
:
XIn các bạn chỉ giúp mình module QEI trong 18f4431

Mình muốn dùng QEI đọc encoder x 4 để thưc hiện bộ điều khiển PID nhưng mình chưa hiểu cách cấu hình trong CCS như thế nào,bạn nào làm rồi có thể cho mình xin ít kinh nghiệm được không?nếu được có thể share code cho mình không?

Mình có tìm các thread trong diễn đàn nhưng vẫn không tự làm được

cảm ơn sự giúp đỡ của mọi người
vagabondtt1503 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 30-03-2009, 07:34 PM   #2
cong1810
Đệ tử 4 túi
 
Tham gia ngày: Sep 2007
Bài gửi: 62
:
Send a message via Yahoo to cong1810
thật may vì cũng có người đang hỏi về QEI.
các anh cho em hỏi luôn!
em định dùng QEI ở chế độ x2 để đo tốc độ động cơ.
cách hoạt động và các chân thì em đọc datasheet, em có nắm được!
vấn đề của em là em chưa biết cách nào để lấy số xung ra?
nếu set timer 5 làm bộ đếm thì lại phải mất thêm 1 timer nữa để lấy mẫu thời gian.
nếu em dùng ngắt ở chế độ period - match ( em ko muốn dùng chân indx) và dùng timer 5 lấy mẫu thời gian thì em nghĩ phải set cho thanh ghi MAXCNT là 0xffff.Nhưng em vẫn chưa thấy ổn lắm.
các anh tư vấn thêm giúp em với!!
chúc mọi ngưởi luôn vui khỏe!!
cong1810 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 30-03-2009, 10:49 PM   #3
vagabondtt1503
Đệ tử 2 túi
 
Tham gia ngày: Dec 2008
Bài gửi: 33
:
Trích:
Nguyên văn bởi cong1810 View Post
thật may vì cũng có người đang hỏi về QEI.
các anh cho em hỏi luôn!
em định dùng QEI ở chế độ x2 để đo tốc độ động cơ.
cách hoạt động và các chân thì em đọc datasheet, em có nắm được!
vấn đề của em là em chưa biết cách nào để lấy số xung ra?
nếu set timer 5 làm bộ đếm thì lại phải mất thêm 1 timer nữa để lấy mẫu thời gian.
nếu em dùng ngắt ở chế độ period - match ( em ko muốn dùng chân indx) và dùng timer 5 lấy mẫu thời gian thì em nghĩ phải set cho thanh ghi MAXCNT là 0xffff.Nhưng em vẫn chưa thấy ổn lắm.
các anh tư vấn thêm giúp em với!!
chúc mọi ngưởi luôn vui khỏe!!
bạn biết cách khởi động ban đầu cho bộ QEI không? giúp mình với
vagabondtt1503 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 30-03-2009, 11:56 PM   #4
cong1810
Đệ tử 4 túi
 
Tham gia ngày: Sep 2007
Bài gửi: 62
:
Send a message via Yahoo to cong1810
hix! em vẫn đang mày mò và quan trọng là vẫn chưa làm được.anh thử đọc phần 16.2 trong datasheet xem có giúp ích gì ko. em cũng đang đọc nó. cứ đọc đi đọc lại rồi thử từng ứng dụng nhỏ một. mỗi lần đọc lại thấy thấm 1 tí. xin lỗi.em chưa giúp được huynh!!
cong1810 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 31-03-2009, 08:37 AM   #5
sandro_bk
Đệ tử 4 túi
 
sandro_bk's Avatar
 
Tham gia ngày: Jul 2007
Bài gửi: 66
:
đây là đoạn chương trình khởi tạo và đọc QEI,các bác xem tham khảo,khi đọc encoder thường sử dụng chế độ đọc xung khi ở tốc độ cao,còn đọc theo kiểu capture thời gian sử dụng Timer5 chỉ nên dùng ở tốc độ thấp.

#byte QEICON=0xFB6
#byte POSCNTH=0xF67
#byte POSCNTL=0xF66
#byte MAXCNTH=0xF65
#byte MAXCNTL=0xF64

int16 Read_QEI() //doc QEI
{
int16 tmp=0;
tmp = make16(POSCNTH, POSCNTL);
POSCNTH = 0x3F;
POSCNTL = 0xFF;
return tmp;
}

void Init_QEI() //khoi tao QEI
{
set_tris_A(0xFF);
MAXCNTL=0xFF;
MAXCNTH=0xFF;
POSCNTH = 0x3F;
POSCNTL = 0xFF;
QEICON = 0b10111000;
}
sandro_bk vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 31-03-2009, 12:36 PM   #6
cong1810
Đệ tử 4 túi
 
Tham gia ngày: Sep 2007
Bài gửi: 62
:
Send a message via Yahoo to cong1810
Trích:
Nguyên văn bởi sandro_bk View Post
đây là đoạn chương trình khởi tạo và đọc QEI,các bác xem tham khảo,khi đọc encoder thường sử dụng chế độ đọc xung khi ở tốc độ cao,còn đọc theo kiểu capture thời gian sử dụng Timer5 chỉ nên dùng ở tốc độ thấp.

#byte QEICON=0xFB6
#byte POSCNTH=0xF67
#byte POSCNTL=0xF66
#byte MAXCNTH=0xF65
#byte MAXCNTL=0xF64

int16 Read_QEI() //doc QEI
{
int16 tmp=0;
tmp = make16(POSCNTH, POSCNTL);
POSCNTH = 0x3F;
POSCNTL = 0xFF;
return tmp;
}

void Init_QEI() //khoi tao QEI
{
set_tris_A(0xFF);
MAXCNTL=0xFF;
MAXCNTH=0xFF;
POSCNTH = 0x3F;
POSCNTL = 0xFF;
QEICON = 0b10111000;
}
anh cho em hỏi. với đoạn chương trình trên nếu em muốn tính tốc độ của nó thì vẫn phài cần 1 timer để đến thời gian. khi mà POSCNT= MAXCNT.có phải anh dùng cờ ngắt để nhảy đến đoạn read_qei.nhưng như thế đâu biết thời gian bao nhiêu. trước đến h em cứ nghĩ tính vận tốc thì phải lấy mẫu thời gian rồi mới đọc xung.ko biết có ngược lại được ko.tức là lấy đủ xung rồi tính thời gian.nhưng như vậy ko hợp lý!! em chưa rõ mong anh chỉ giáo.
chúc anh luôn vui khỏe!!
cong1810 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 31-03-2009, 12:59 PM   #7
sandro_bk
Đệ tử 4 túi
 
sandro_bk's Avatar
 
Tham gia ngày: Jul 2007
Bài gửi: 66
:
Mình thường làm như sau.Dùng 1 cái timer để tạo pwm,(chẳng hạn xuất xung 5khz)thời gian đó cũng chính là chu kỳ lấy mẩu số xung encoder,cứ ngắt pwm xảy ra là lấy mẩu encoder tính ra tốc độ rồi,đó là cách đọc encoder ở tốc độ cao,tức là khi động cơ quay nhanh,
còn ở tốc độ thấp tức là khi động cơ quay chậm thì có thể dùng cách đo thời gian của 1 xung encoder,cho nên người ta mới cung cấp timer5 chung với module encoder cho mình dùng chức năng capture,
sandro_bk vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 31-03-2009, 01:19 PM   #8
vagabondtt1503
Đệ tử 2 túi
 
Tham gia ngày: Dec 2008
Bài gửi: 33
:
Trích:
Nguyên văn bởi sandro_bk View Post
Mình thường làm như sau.Dùng 1 cái timer để tạo pwm,(chẳng hạn xuất xung 5khz)thời gian đó cũng chính là chu kỳ lấy mẩu số xung encoder,cứ ngắt pwm xảy ra là lấy mẩu encoder tính ra tốc độ rồi,đó là cách đọc encoder ở tốc độ cao,tức là khi động cơ quay nhanh,
còn ở tốc độ thấp tức là khi động cơ quay chậm thì có thể dùng cách đo thời gian của 1 xung encoder,cho nên người ta mới cung cấp timer5 chung với module encoder cho mình dùng chức năng capture,
mình sử dụng hàm Read_QEI() của bạn viết sau đó đưa pha A và B vào 2 chân QEA và QEB của vi đièu khiển,sau đó lấy giá trị trả về của hàm Read_QEI() xuất LCD trong vòng while,nhưng giá trị xuất ra rất khó hiểu,hinh như không phải tính xung đưa vào 2 chân QEA và QEB.

Mong bạn chỉ bảo giúp
vagabondtt1503 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 31-03-2009, 05:57 PM   #9
sandro_bk
Đệ tử 4 túi
 
sandro_bk's Avatar
 
Tham gia ngày: Jul 2007
Bài gửi: 66
:
hàm read_QEI() trả giá trị 16 bit về nên bạn dùng như sau:
int16 a;
a = read_QEI();

bạn thử xem
sandro_bk vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 01-04-2009, 04:50 PM   #10
cong1810
Đệ tử 4 túi
 
Tham gia ngày: Sep 2007
Bài gửi: 62
:
Send a message via Yahoo to cong1810
Trích:
Nguyên văn bởi sandro_bk View Post
Mình thường làm như sau.Dùng 1 cái timer để tạo pwm,(chẳng hạn xuất xung 5khz)thời gian đó cũng chính là chu kỳ lấy mẩu số xung encoder,cứ ngắt pwm xảy ra là lấy mẩu encoder tính ra tốc độ rồi,đó là cách đọc encoder ở tốc độ cao,tức là khi động cơ quay nhanh,
còn ở tốc độ thấp tức là khi động cơ quay chậm thì có thể dùng cách đo thời gian của 1 xung encoder,cho nên người ta mới cung cấp timer5 chung với module encoder cho mình dùng chức năng capture,
em hỏi thêm chỗ này!
tại sao anh lại đặt POSCNT=3fff vậy! bởi em nghĩ nếu đặt là 0 thì lúc tính toán mình ko cần trừ đi 3fff? ko biết em hiểu vậy có đúng ko nhỉ!
cong1810 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 01-04-2009, 08:16 PM   #11
sandro_bk
Đệ tử 4 túi
 
sandro_bk's Avatar
 
Tham gia ngày: Jul 2007
Bài gửi: 66
:
bạn đặt câu hỏi rất đúng,vì module QEI có thể đếm lên hay đếm xuống tùy theo chiều của xung A,B(bạn xem thêm trong datasheet),đặt giá trị đó là giá trị chính giữa của bộ đếm 16bit 0xffff,sẽ ko sợ bị tràn khi đo tốc độ,thực tế với tốc độ lấy mẫu 200us mình hay dùng chắc chắn chẳng bao giờ tràn cả,
Thân
sandro_bk vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 01-04-2009, 11:30 PM   #12
cong1810
Đệ tử 4 túi
 
Tham gia ngày: Sep 2007
Bài gửi: 62
:
Send a message via Yahoo to cong1810
.em có dùng thêm cả bộ filter trong pic mà sao QEI của em vẫn nhiễu kinh khủng.em dùng LCD để hiển thị nó thì chưa lần nào đúng cả.nhưng nếu dùng ngắt ngoài thì lại chính xác.
em đang thử đo xung tốc độ chậm thôi.do em đang thử nghiệm với nút nhấn và xoay tay để đo tốc độ thằng động cơ brushless sau này .nên em dùng chế độ x2 để đọc.
mong anh chỉ giáo!!
cong1810 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 02-04-2009, 12:37 PM   #13
sandro_bk
Đệ tử 4 túi
 
sandro_bk's Avatar
 
Tham gia ngày: Jul 2007
Bài gửi: 66
:
mình chưa gặp hiện tượng này bao giờ,bạn có thể post code lên,biết đâu có ai đó có thể giúp bạn,
Cùng nhau học tập,ko dám chỉ giáo,
Thân
sandro_bk vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 02-04-2009, 05:25 PM   #14
cong1810
Đệ tử 4 túi
 
Tham gia ngày: Sep 2007
Bài gửi: 62
:
Send a message via Yahoo to cong1810
Code:
#include <18f4431.h>
#include <def_4431.h>
#fuses  XT,NOWDT,NOPROTECT,NOLVP//,NOBROWNOUT,NOPUT,NOCPD,NODEBUG,NOFCMEN,NOCPB,NOPWMPIN,STVREN
#use delay(clock=4000000)
#use fast_io(a)
#use fast_io(d)
#use fast_io(c)
#use fast_io(e)
#include <lcd.c>
#define use_portd_lcd true

int16 duty_cycle0=0;
int16 velocity=0;
int16 dem=0;
void display_lcd();
void Read_QEI(); //doc QEI 
 
#INT_PWMTB
void interrupt_pwmtb()
{  
   dem++;
   if(dem==3000)
   {dem=0;
   Read_QEI();
   }
   }

void main()
{
set_tris_b(0);    // port B la xuat
portb=0;
set_tris_c(0);
portc=0xff;
set_tris_d(0);
portd=0;
set_tris_a(0xff);
porta=0xff;

//setup LCD
lcd_init();
display_lcd();

//setup power PWM
PTCON1=0b10000000;   // dung che do ngat time base
SETUP_POWER_PWM(PWM_CLOCK_DIV_64|PWM_FREE_RUN,1,0,1249,0,1,0);//5khz hay chu ki là 200ms
SETUP_POWER_PWM_PINS(PWM_COMPLEMENTARY,PWM_COMPLEMENTARY,PWM_OFF,PWM_OFF);
SET_POWER_PWM0_DUTY(0);
duty_cycle0=250;

//setup QEI
MAXCNTL=0xFF;
MAXCNTH=0xFF;
POSCNTH = 0x00;
POSCNTL = 0x00; 
QEICON = 0b10101000;
DFLTCON =  0b00010011;//filter tren chan QEA clock devider 1:16

//interrupts
enable_interrupts(INT_PWMTB);
enable_interrupts(global);

while(1)
{
display_lcd();
SET_POWER_PWM0_DUTY(duty_cycle0);
SET_POWER_PWM2_DUTY(duty_cycle0);
if(RC1==0)
   {
      delay_ms(50);
      if(RC1==0)
         {

            if(duty_cycle0==500)duty_cycle0=500;
             else duty_cycle0=duty_cycle0+5;
         }
      
   }
if(RC2==0)
   {
      delay_ms(50);
      if(RC2==0)
         {

            if(duty_cycle0==250)duty_cycle0=250;
             else duty_cycle0=duty_cycle0-5;
         }
      
   }
}

}
void display_lcd()
{
lcd_gotoxy(1,1);
printf(lcd_putc,"duty=%lu",duty_cycle0);
lcd_gotoxy(10,1);
printf(lcd_putc,"%lu",dem);
lcd_gotoxy(1,2);
printf(lcd_putc,"V=%lu",velocity/2);
}
void Read_QEI() //doc QEI 
{
velocity = make16(POSCNTH,POSCNTL);
POSCNTH = 0x0;
POSCNTL = 0x0; 
}
đây là đoạn code em dùng để test thử.mục đích ban đầu chỉ là muốn tính và hiển thị số xung trên chân QÉA.
khi em để hở chân này.giá trị hiển thị rất lớn cỡ mấy chục ngàn.khi em cho nó xuống mass thì có trở về 0 nhưng chỉ cần rung jump 1 tí là lại nhảy lên.
em nối nó vào 1 nút nhấn có điện trở kéo nguồn .nhấn thì xuống mass còn bình thường thì đo là 5v.nó cũng ko chính xác tí nào.nhưng nếu em đổi dùng ngắt ngoài thì chính xác.
em nghĩ do phần cứng nhiều hơn.anh xem giúp em nhé!!
cong1810 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 20-03-2013, 09:19 PM   #15
tien168bn
Đệ tử 1 túi
 
Tham gia ngày: Feb 2012
Bài gửi: 12
:
Mọi người cho em hỏi cái này ngoài lề một xíu:
SETUP_POWER_PWM(PWM_CLOCK_DIV_64|PWM_FREE_RUN,1,0, 1249,0,1,0);//5khz hay chu ki là 200ms
Em muốn hỏi là cái này tình toán làm sao ra được 5kHz vậy ạ, e mới tìm hiểu về pic nên còn nhiều thứ muốn biết lắm ạ. cảm ơn mọi người
tien168bn vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Trả lời


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à 03:09 AM.


Đượ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