PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   Cảm biến (http://www.picvietnam.com/forum/forumdisplay.php?f=18)
-   -   Hỏi về thuật toán và bài tập với encoder? (http://www.picvietnam.com/forum/showthread.php?t=1265)

Mecha 12-07-2007 06:04 PM

Ví dụ đây là một "khung chương trình" của 89C52


Code:

;********************************************************
;*  Clock 24 MHz, 1 chu ky 0.5 us
;********************************************************

; Khai bao cac hang so khoi dong ban dau o day

; Khai bao bien o day

;-----------------------------
Start:
        mov  a,#0Ch
        da      a
        djnz    r0,$
        clr    EA
        clr    ET0
        clr    ET1
        clr    EX0
        clr    EX1
        jmp    Clear_RAM
;----------------------------------------------------------------------------
;                Clear RAM internal 20h - 0FFh for 89C52
;----------------------------------------------------------------------------
Clear_RAM:
        mov    r0,#20h
CLR_loop:
        mov    @r0,#0
        inc    r0
        cjne    r0,#0ffh,CLR_loop
        mov    sp,#Stack
;----------------------------------------------------------------------------
; Setup cac tham so khac o day

;--------------------------------------------------------
; Vong quet chuong trinh chinh
;--------------------------------------------------------
Main:
        jbc        flg_time.0,prg10us
n100us:
        jbc        flg_time.1,prg100us
n1ms:
        jbc        flg_time.2,prg1ms
n10ms:
        jbc        flg_time.3,prg10ms
n100ms:
        jbc        flg_time.4,prg100ms
n1sec:
        jbc        flg_time.5,prg1sec
n1minute:
        jmp        Main


;~~~~~~~~~~~~~~~~~~~~~~~~~~
prg10us:
        ;cac lenh cua vong quet 10us
        jmp        n100us

;~~~~~~~~~~~~~~~~~~~~~~~~~~
prg100us:
        ;cac lenh cua vong quet 100us
        jmp        n1ms

;~~~~~~~~~~~~~~~~~~~~~~~~~~
prg1ms:
        ;cac lenh cua vong quet 1ms
        jmp        n10ms

;~~~~~~~~~~~~~~~~~~~~~~~~~~
prg10ms:
        ;cac lenh cua vong quet 10ms
        jmp        n100ms

;~~~~~~~~~~~~~~~~~~~~~~~~~~
prg100ms:
        ;cac lenh cua vong quet 100ms
        jmp        n1sec


;----------------------------------------------------------
; Thu tuc xu ly cac ngat
;----------------------------------------------------------

IntTimer0:
        push    0
        clr          TR0                ; cam timer 0
;cac lenh trong ngat Timer0
endtimer0:
        setb        TR0                ; Cho phep timer 0
        pop        0
        reti

;----------------------------
;Tao chu ky vong quet khac nhau
IntTimer1:
        push    0
        clr        TR1                ; cam timer 1

        setb        flg_time.0                ;bit 0 : da thay doi 10us
        mov        r0,#cn_10us
        inc        @r0
        cjne        @r0,#10,endtimer1

        setb        flg_time.1                ;bit 1: da thay doi 100us
        mov        @r0,#0
        mov        r0,#cn_100us
        inc        @r0
        cjne        @r0,#10,endtimer1

        setb        flg_time.2                ;bit 2: da thay doi 1ms=1000us
        mov        @r0,#0
        mov        r0,#cn_1ms
        inc        @r0
        cjne        @r0,#10,endtimer1

        setb        flg_time.3                ;bit 3: da thay doi 10ms
        mov        @r0,#0
        mov        r0,#cn_10ms
        inc        @r0
        cjne        @r0,#10,endtimer1

        setb        flg_time.4                ;bit 4: da thay doi 100ms
        mov        @r0,#0
        mov        r0,#cn_100ms
        inc        @r0
        cjne        @r0,#10,endtimer1

        setb        flg_time.5                ;bit 5: da thay doi 1sec=1000ms
        mov        @r0,#0
        mov        r0,#cn_1sec
        inc        @r0
        cjne        @r0,#60,endtimer1

        setb        flg_time.6                ;bit 6: da thay doi 1minute=60s
        mov        @r0,#0
        mov        r0,#cn_1minute
        inc        @r0
        cjne        @r0,#60,endtimer1

        setb        flg_time.7                ;bit 7: da thay doi 1hour=60minutes
        mov        @r0,#0
        mov        r0,#cn_1hour
        inc        @r0
       
endtimer1:
        mov        TL1,#Low(MotorPulse)
        mov        TH1,#High(MotorPulse)
        setb        TR1
        pop        0
        reti

;----------------------------
IntEx0:
        reti
;----------------------------
IntRS232:
        reti
;----------------------------
IntEx1:
        reti

;----------------------------
endprog: db ' End of program at here, bye!'
        END


RedRose 16-07-2007 10:28 AM

Xin hỏi rằng nếu tốc độ xử lý không xử lý được số xung thì có thể dùng biện pháp phần cứng nào để xử lý ko?
(liệu có thể dùng bộ đếm như kiểu chia tần không?, lúc đó pha còn chính xác ko nhỉ)

Giúp em với nhé, em đang phải đọc 1 encoder quang mà vẫn chưa thành công.
Cám ơn mọi người trước!

namqn 16-07-2007 06:31 PM

Trích:

Nguyên văn bởi RedRose (Post 10093)
Xin hỏi rằng nếu tốc độ xử lý không xử lý được số xung thì có thể dùng biện pháp phần cứng nào để xử lý ko?
(liệu có thể dùng bộ đếm như kiểu chia tần không?, lúc đó pha còn chính xác ko nhỉ)

Giúp em với nhé, em đang phải đọc 1 encoder quang mà vẫn chưa thành công.
Cám ơn mọi người trước!

Bạn có thể dùng một bộ đếm nhị phân để giảm tốc độ xung vào vi điều khiển, kết hợp với việc đọc giá trị tức thời của bộ đếm ngoài đó, bạn sẽ có được độ phân giải cần thiết mà không làm quá tải bộ vi điều khiển. Ví dụ, dùng bộ đếm nhị phân 4-bit, lúc đó tốc độ xung vào vi điều khiển sẽ giảm 16 lần, bạn sẽ đọc các bit thấp nhất của số đếm xung bằng cách đọc giá trị tức thời của bộ đếm ngoài qua 4 đường I/O của PIC, các bit cao hơn sẽ nằm trong vi điều khiển.

Thân,

RedRose 17-07-2007 11:59 AM

Cảm ơn anh Nam, em cũng đã nghĩ như vậy.
Em chưa hiểu đoạn anh nói về cách "đọc giá trị tức thời của bộ đếm ngoài qua 4 đường I/O của PIC, các bit cao hơn sẽ nằm trong vi điều khiển" lắm

Em nghĩ đơn giản là dùng bộ đếm 4bit thì tốc độ xung sẽ giảm 16 lần, và xung đó chính là xung thể hiện ở bit cao nhất bộ đếm. Như vậy thì ta tiến hành đếm xung ở chân này của bộ đếm?
(vì vậy mà em mới hỏi về pha, em định cho cả 2 kênh A,B qua 2 bộ đếm để giảm tốc độ xung, sau đó giải mã như bình thường?)

Mecha 17-07-2007 05:08 PM

Trích:

Nguyên văn bởi RedRose (Post 10128)
Cảm ơn anh Nam, em cũng đã nghĩ như vậy.
Em chưa hiểu đoạn anh nói về cách "đọc giá trị tức thời của bộ đếm ngoài qua 4 đường I/O của PIC, các bit cao hơn sẽ nằm trong vi điều khiển" lắm

Em nghĩ đơn giản là dùng bộ đếm 4bit thì tốc độ xung sẽ giảm 16 lần, và xung đó chính là xung thể hiện ở bit cao nhất bộ đếm. Như vậy thì ta tiến hành đếm xung ở chân này của bộ đếm?
(vì vậy mà em mới hỏi về pha, em định cho cả 2 kênh A,B qua 2 bộ đếm để giảm tốc độ xung, sau đó giải mã như bình thường?)

- Trường hợp encoder chỉ phát xung trên một chân, hướng (chiều) của xung được quy định bởi 1 chân khác: Dùng bộ đếm nhị phân 4 bit, tốc độ xung sẽ được giảm xuống 4^2=16 lần. Khi đó việc đọc trực tiếp xung phát ra từ encoder sẽ chuyển sang đọc giá trị logic tại 4 cổng tín hiệu ra của bộ đếm nhị phân 4 bit (từ 2^0 đến 2^3). Vấn đề bây giờ là chốt giá trị logic tức thời trên 4 cổng này (giả sử chốt khi trạng thái 4 cổng là 1111). Có thể dùng 1 con AND 4 đầu vào, khi 4 cổng đều ở giá trị 1111 thì đầu ra của AND sẽ là 1 và bạn có thể dùng nó để tạo ngắt (chương trình ngắt cập nhập giá trị của bộ đếm xung thêm 16 xung). Vấn đề còn lại là phải chú ý đến chân đại diện cho chiều xung hay chiều quay của encoder. Trong chương trình ngắt sẽ phải đọc trạng thái của chân này và bộ đếm xung sẽ cộng thêm hay trừ đi 16 xung phụ thuộc vào trạng thái của chân này (thường là quay thuận thì cộng, quay ngược thì trừ). Tuy nhiên có một trường hợp khi bộ đếm nhị phân đang đọc xung thì chiều quay thay đổi, khi đó ta sẽ bị sai số một số xung nhất định.

- Trường hợp encoder phát xung trên hai kênh A và B: mình nghĩ là không dùng được giải pháp bộ đếm nhị phân ngoài được vì khi đó thông tin về độ lệch pha giữa A và B (để quyết định chiều quay của encoder) bị mất hay nói cách khác là không thể nhận biết được khi lập trình trên PIC.

Tôi nghĩ thông tin đã đủ, bạn làm mạch thử nghiệm và thông báo kết quả cho mọi người nhé.

namqn 17-07-2007 08:12 PM

Trích:

Nguyên văn bởi Mecha (Post 10131)
- Trường hợp encoder phát xung trên hai kênh A và B: mình nghĩ là không dùng được giải pháp bộ đếm nhị phân ngoài được vì khi đó thông tin về độ lệch pha giữa A và B (để quyết định chiều quay của encoder) bị mất hay nói cách khác là không thể nhận biết được khi lập trình trên PIC.
...

Vẫn làm được đấy Phong, dùng mạch logic ở bên ngoài luôn. Sinh viên của anh đã làm cách đây 3, 4 năm gì đó, chỉ cần 1 con D-FF và 2 kênh A, B đó thôi.

Thân,

Mecha 17-07-2007 08:39 PM

Trích:

Nguyên văn bởi namqn (Post 10139)
Vẫn làm được đấy Phong, dùng mạch logic ở bên ngoài luôn. Sinh viên của anh đã làm cách đây 3, 4 năm gì đó, chỉ cần 1 con D-FF và 2 kênh A, B đó thôi.

Thân,

Nếu chỉ dùng thêm bộ đếm nhị phân thì không giải quyết được vấn đề cho kiểu phát xung AB. Tuy nhiên nếu dùng thêm Flip-Flops (FF) thì sẽ giải quyết được, nhưng theo em là phải dùng thêm 1 con SR-FF chứ 1 con D-FF không làm được vì nó chỉ có 1 đầu vào D, không kham nổi hai cổng AB.

Nguyên lý của SR-FF:
http://i13.photobucket.com/albums/a2..._FlipFlops.jpg

Theo hình vẽ, giả sử nếu sử dụng chân Set (S) cho cổng A, chân Reset (R) cho cổng B thì:
- Nếu A sớm pha hơn B (S=1, R=0) thì suy ra encoder quay thuận (Q=1)
- Nếu A chậm pha hon B (S=0, R=1) thì suy ra encoder quay nghịch (Q=0)
Vì vậy ta có thể sử dụng chân Q như chân địch chiều quay. Vấn đề giờ có thể quy về "Trường hợp encoder chỉ phát xung trên một chân, hướng (chiều) của xung được quy định bởi 1 chân khác".

namqn 17-07-2007 10:36 PM

Trích:

Nguyên văn bởi Mecha (Post 10140)
Nếu chỉ dùng thêm bộ đếm nhị phân thì không giải quyết được vấn đề cho kiểu phát xung AB. Tuy nhiên nếu dùng thêm Flip-Flops (FF) thì sẽ giải quyết được, nhưng theo em là phải dùng thêm 1 con SR-FF chứ 1 con D-FF không làm được vì nó chỉ có 1 đầu vào D, không kham nổi hai cổng AB.

Nguyên lý của SR-FF:
http://i13.photobucket.com/albums/a2..._FlipFlops.jpg

Theo hình vẽ, giả sử nếu sử dụng chân Set (S) cho cổng A, chân Reset (R) cho cổng B thì:
- Nếu A sớm pha hơn B (S=1, R=0) thì suy ra encoder quay thuận (Q=1)
- Nếu A chậm pha hon B (S=0, R=1) thì suy ra encoder quay nghịch (Q=0)
Vì vậy ta có thể sử dụng chân Q như chân địch chiều quay. Vấn đề giờ có thể quy về "Trường hợp encoder chỉ phát xung trên một chân, hướng (chiều) của xung được quy định bởi 1 chân khác".

Dùng SR-FF thì như Phong đã nói, còn dùng D-FF thì 1 kênh đưa vào chân D, một kênh là clock cho D-FF. Cũng sẽ xác định được chiều quay.

Chẳng hạn, kênh A đưa vào chân D và kênh B đưa vào chân clock:
- Nếu A sớm pha hơn B, thì lúc có clock (tức là B lên 1) logic '1' được đưa vào FF (chiều thuận)
- Nếu A chậm pha hơn B, thì lúc có clock (tức là B lên 1) logic '0' được đưa vào FF (chiều nghịch)

Thân,

sandro_bk 19-07-2007 03:17 PM

mình dùng con 18f4331 để đọc encoder,con này có module đọc encoder nhưng trong tập lệnh của CCS ko thấy có lệnh nào sử dụng cho module này cả,có bạn nào làm đọc encoder rồi chỉ mình với,


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