Chức năng QEI được thiết kế chủ yếu cho việc đọc encoder tương đối, do đó nó được ứng dụng chủ yếu trong việc điều khiển chuyển động có hồi tiếp, chức năng QEI có một số đặc điểm sau:
Có 3 ngõ vào QEI: hai ngõ tín hiệu pha (QEA và QEB dành cho hai xung A,B) và một ngõ tín hiệu reset dành cho xung Z.
Thanh ghi đếm 16 - bit có thể đếm lên hoặc xuống, và có thể đọc được xung có tần số cao.
Đọc encoder ở hai chế độ x2 hoặc x4
Mỗi chân ngõ vào điều có hỗ trợ bộ lọc nhiễu (noise filter) tần số cao.
Có hai chế độ reset thanh ghi đếm, giúp linh hoạt trong việc điều khiển.
Có thể tạo ra ngắt nội.
Hình 7.7: Sơ đồ khối bộ QEI
Do các chân có chức năng Qadrature Encoder Interfac (QEI) và Input capture (IC) nằm cùng trên một chân của vi điều khiển, nên không thể sử dụng cùng một lúc hai chức năng, nếu cả hai chức năng đều được cho phép, thì chức năng QEI sẽ được ưu tiên, chức năng IC sẽ không hoạt động.
Trong đó:
VELM: Bit cho phép chế độ đo tốc độ
1:Tắt chế độ đo tốc độ 0:Cho phép chế độ đo tốc độ.
QERR: Bit báo lỗi QEI
1:Lỗi thanh ghi báo vị trí. 0: Không có lỗi xảy ra.
UP/DOWN: Bit chỉ trạng thái chiều quay
1:Quay thuận 0:Quay nghịch
QEIM2:QEIM0: Bit chọn chế độ cho khối QEI
110:QEI ở chế độ x4,thanh ghi đếm reset khi POSCNT=MAXCNT 101: QEI ở chế độ x4,tín hiệu chân INDEX sẽ reset thanh ghi đếm. 010: QEI ởchế độ x2,thanh ghi đếm reset khi POSCNT=MAXCNT 001: QEI ở chế độ x2,tín hiệu chân INDEX sẽ reset thanh ghi đếm. 000: Không sử dụng.
PDEC1:PDEC0: Bit chọn tỉ số bộ chia cho chế độ đo vận tốc
11: tỉ số bộ chia là 1/64 10: tỉ số bộ chia là 1/16 01: tỉ số bộ chia là 1/4 00: tỉ số bộ chia là 1/1
Độ phân giải của kết quả đo vị trí phụ thuộc vào việc thay đổi giá trị thanh ghi đếm POSCNT, giá trị thanh ghi đếm POSCNT có thể hoạt động với hai chế độ là: x2 và x4.
Chế độ QEI x2
Ở chế độ này, thanh ghi đếm POSCNT tăng (hay giảm) một đơn vị khi có một cạnh lên hoặc một cạnh xuống ở chân QEA. Giá trị của thanh ghi đếm sẽ reset về 0 khi có xung ở chân INDEX (QEIM2:QEIM0=001), hoặc bằng thanh ghi MAXCNT (QEIM2:QEIM0=010).
QEA
QEB
POSCNT 1 1 1 1 1 1 1 1
Hình 7.8: Chế độ QEI x2
Chế độ QEI x4
Trong chế độ QEIx4, thanh ghi đếm POSCNT tăng (hay giảm) một đơn vị khi có một cạnh lên hoặc một cạnh xuống ở cả hai chân QEA và QEB. Giá trị của thanh ghi đếm sẽ reset về 0 khi có xung ở chân INDEX nếu quay thuận, giá trị thanh ghi đếm sẽ bằng thanh ghi MAXCNT khi có xung INDEX nếu quay nghịch (QEIM2:QEIM0=001), hoặc bằng thanh ghi MAXCNT (QEIM2:QEIM0 =010).
QEA
QEB
POSCNT11 1 1 1 1 1 1 1 1 1 1 11 1 1
Hình 7.8: Chế độ QEI x4
Ví dụ 1: Viết chương trình đếm số xung encoder của động cơ DC motor, và hiển thị lên terminal (baudrate 9600).
Yêu cầu:
Động cơ DC có Incremental encoder độ phân giải 100xung/vòng. Sử dụng chế độ QEIx2, giá trị lớn nhất bộ đếm đạt được là 5000. Hiển thị trạng thái chiều quay.
Sơ đồ phần cứng: Code chương trình: #include<htc.h> #include<stdio.h> __CONFIG(1,FCMEN&RCIO); __CONFIG(2,BORDIS&WDTDIS); __CONFIG(3,XCLKRC3&MCLREN); __CONFIG(4,LVPEN); #define _XTAL_FREQ 8000000 void main() { IRCF2=IRCF1=IRCF0=1; //Tần số 8Mhz
ANSEL0=ANSEL1=0; //Tắt tín hiệu tương tự //Khởi tạo UART baud rate 9600
TXEN=1;SYNC=0;SPEN=1; BRG16=1;BRGH=0;
SPBRGH=0;SPBRG=51;
//Khởi tạo QEI x2, reset thanh ghi đếm khi bằng MAXCNT
VELM=1; //Tắt chế độ đo vận tốc
QEIM1=1; QEIM0=0;
PDEC1=1;PDEC0=0; //Tỉ số chia 1:1
MAXCNTH=19; //Giá trị đếm lớn nhất để reset
MAXCNTL=136;//MAXCNT=MAXCNTH*256+MAXCNTL
while(1) {
printf("\fXung encoder:%u\r Chieu:%d\r", POSCNTH*256+POSCNTL,UPDOWN); __delay_ms(80); } } void putch(char c) { while(!TXIF); TXREG=c; }
Tiến hành biên dịch chương trình, điều chỉnh tốc độ động cơ ở chế độ chậm nhất để quan sát quá trình tăng, giảm biến đếm counter phụ thuộc vào chân QEA, sau đó tăng tốc độ động cơ để quan sát thời điểm reset của biến đếm, và chiều của động cơ.
Ví dụ 2: Viết chương trình đếm số xung encoder của động cơ DC motor, và hiển thị lên terminal (baudrate 9600).
Yêu cầu:
Động cơ DC có Incremental encoder độ phân giải 8xung/vòng. Sử dụng chế độ QEIx4, giá trị lớn nhất bộ đếm MAXCNT= 100. Hiển thị trạng thái chiều quay.
Sơ đồ phần cứng: Code chương trình: #include<htc.h> #include<stdio.h> __CONFIG(1,FCMEN&RCIO); __CONFIG(2,BORDIS&WDTDIS); __CONFIG(3,XCLKRC3&MCLREN); __CONFIG(4,LVPEN); #define _XTAL_FREQ 8000000 void main() { IRCF2=IRCF1=IRCF0=1; //Tần số 8Mhz
ANSEL0=ANSEL1=0; //Tắt tín hiệu tương tự
//Khởi tạo UART baud rate 9600
TXEN=1;SYNC=0;SPEN=1; BRG16=1;BRGH=0;
SPBRGH=0;SPBRG=51;
//Khởi tạo QEI x2, reset thanh ghi đếm khi bằng MAXCNT
VELM=1; //Tắt chế độ đo vận tốc
QEIM2=1; //QEIx4, INDEX reset
QEIM0=1;
PDEC1=1;PDEC0=0; //Ratio 1:1
MAXCNTH=0; //giá trị lớn nhất của bộ đếm là 100
MAXCNTL=100;
while(1) {
printf("\fXung encoder:%u\rChieu:%d\r", POSCNTH* 256+POSCNTL,UPDOWN); __delay_ms(80); } } void putch(char c) { while(!TXIF); TXREG=c; }
Biên dịch chương trình, điều chỉnh encoder là 8xung/vòng, chạy phần mềm mô phỏng, ta thấy chỉ số bộ đếm tăng tới 32(8x4) sẽ bị reset về không, tuy nhiên khi động cơ quay ngược lại, thì giá trị đếm sẽ bắt đầu là 100 (MAXCNT=100).