PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   Cơ bản về vi điều khiển và PIC (http://www.picvietnam.com/forum/forumdisplay.php?f=8)
-   -   Pic 18f452 (http://www.picvietnam.com/forum/showthread.php?t=345)

ahchu 15-04-2006 09:33 PM

Hì hì..
Trong 2 tuần qua em cũng đã tìm được cách chạy PWM rồi. Đây là đoạn code cho PWM

PWM_norm
;set PWM period=1000Hz=0.001s at 50%duty cycle
;Fosc=8Mhz and TMR2 prescale value=16

;1. Set period for PWM=1000Hz
;PR2 = (PWM period)/(4*Tosc*TMR2 prescale value) - 1
;PR2 = 0.001/[4 * (1/8)e-6 * 16) - 1 => PR2 = 124

movlw d'124' ;set period for PWM=1000Hz
movwf PR2

;2. Set duty cycle by writting CCPR1L register and CCPR1CON<5:4> bits

;PWM Duty Cycle = (CCPR1L:CCP1CON<5:4>)*Tosc*TMR2 Prescale Value
;CCPR1L:CCP1Con<5:4> = PWM Duty Cycle / (Tosc * TMR2 Prescale)
;PWM Duty Cycle = 50% of Period
;PWM Duty Cycle = 50% of 0.001 = 0.0005
;CCPR1L:CCP1Con<5:4> = 0.0005 / [(1/8)e-6 * 16] = 250
;=> CCPR1L:CCP1Con<5:4> = 0011111010

bcf CCP1CON, DC1B0 ;set bit 0 = 1
bsf CCP1CON, DC1B1 ;set bit 1 = 1
movlw b'00111110' ;set duty cycle and enable PWM
movwf CCPR1L

;3. Make the CCP1 pin an output by clearing the TRISC<2> bit
movlw b'11111011' ;set PORTC as an CCP1
andwf TRISC

;4. Set The TMR2 prescale value and enable TMR2 by writing to T2CON

movlw b'00000111' ;set prescale = 1:16 and enable TIMER2
movwf T2CON
return

Vì hiện tại em đang làm project về con "line-following robot" nên mới dùng đến PWM để điều khiển tốc độ của con robot, do thấy lâu quá kô ai trả lời nên em tự đọc luôn.
Hiện nay con robot của em đã chạy (mừng quá) cám ơn mọi người (đặc biệt là anh namqn) đã giúp em nhiều từ 1 người chẳng biết gì về PIC sau 1 tuần đã có thể lập trình PIC ở mức cản bản. Cám ơn mọi người nhiều lắm lắm :)

namqn 16-04-2006 08:02 PM

Chúc mừng em nhé!

Em có thấy thắc mắc là tại sao chỉ dùng duty cycle là 50% mà giá trị đặt vào CCPR1L:CCP1Con<5:4> lại khoảng gấp đôi giá trị đặt vào PR2 không?

Thân,

ahchu 19-04-2006 11:41 PM

Trích:

Nguyên văn bởi namqn
Chúc mừng em nhé!

Em có thấy thắc mắc là tại sao chỉ dùng duty cycle là 50% mà giá trị đặt vào CCPR1L:CCP1Con<5:4> lại khoảng gấp đôi giá trị đặt vào PR2 không?

Thân,

Thưa anh,
Đó là do giá trị của prescale em đặt là 16, nếu em đặt là 32 thì nó sẽ bằng (với cùng loại crystal 8Mhz)

ahchu 20-04-2006 12:08 AM

Em đang viết code cho một con line-following robot. Con robot của em dùng IR sensor để nhận biết đường đen và đi theo đường đen đó. 3 senor được đặc thẳng hàng và đưa tín hiệu thông wa Smchitt Trigger rồi vào PIC8F452. Tín hiệu digital như sau:
0: in black line
1: in white surface.

L: PORT A0
C: PORT A1
R: PORT A2

Về căn bản thì con robot này chạy được rồi, thỏa mãn mọi điều kiện về line following. Nhưng có một điều là con robot này kô thể quẹo góc nhọn được. Tất cả các góc khác đều quẹo được kể cả góc 90. Em kèm theo là đoạn code so sánh. Em nghĩ là có thể khắc phục khó khăn khi quẹo góc nhọn bằng cách viết code chứ không cần phải mắc thêm sensor. Em điều khiển bằng cách thay đổi PWM (em kô kèm theo đoạn code về PWM ). Mong mọi người giúp em


Note: Đoạn code em kèm ở dưới.

namqn 20-04-2006 12:15 AM

Trích:

Nguyên văn bởi ahchu
Thưa anh,
Đó là do giá trị của prescale em đặt là 16, nếu em đặt là 32 thì nó sẽ bằng (với cùng loại crystal 8Mhz)

Không đúng á!
Trong cả hai công thức tính PR2 và PWM Duty Cycle thì đều có mặt TMR2 prescale value, em đổi TMR2 prescale value thì vẫn có tỷ lệ giữa giá trị đặt vào CCPR1L:CCP1Con<5:4> và giá trị đặt vào PR2 như vậy.
Suy nghĩ lại xem.

Thân,

À, đối với những đoạn code em post lên thì nên đưa nó vào trong khung định dạng cho code (khi em dán code vào thì chọn đoạn code đó, rồi nhấn vào cái nút có hình # ở thanh công cụ đó).

ahchu 20-04-2006 03:43 AM

hê hê, xin lỗi mọi người nghe... Đoạn code của em
Code:

        org                0x0000
        goto        start

;        case1        equ        0x20        ;PORTA value = 000 -> the robot is in the air
;        case2        equ        0x21        ;PORTA value = 001 -> left hand side
;        case3        equ        0x22        ;PORTA value = 011 -> completely in left hand side
;        case4        equ        0x23        ;PORTA value = 100 -> right hand side
;        case5        equ        0x24        ;PORTA value = 101 -> center the line
;        case6        equ        0x25        ;PORTA value = 110 -> completely in right hand side
;        case7        equ        0x26        ;PORTA value = 111 ->

start
        movlw        d'124'                        ;set period for PWM=1000Hz
        movwf        PR2
        movlw        b'00000111'                ;set prescale = 1:16 and enable TIMER2
        movwf        T2CON

        bcf                TRISC, CCP1
        bcf                TRISB, CCP2

        clrf        PORTB                ;initialize PORTB, PORTA
        clrf        TRISB               
        clrf        PORTA
        clrf        PORTD
        clrf        TRISD

;R_led off <=> PORTB = 11111110
;C_led off <=> PORTB = 11111101
;L_led off <=> PORTB = 11111011

        ;configure PORTA       
        movlw        b'00000110'        ;set all PORTAs as digital input
        movwf        ADCON1
       
        movlw        0xff
        movwf        TRISA                ;set portA as input
       
        movf        PORTA,0                ;read from PORTA and store it to W_reg
        movwf        PORTB       

loop
        movf        PORTA,0
        movwf        PORTB
        goto        case2

s1                                                        ;special case of robot when it turning right and get out of the line
        movlw        b'00000000'
        cpfseq        PORTA                                ;if equal skip
        goto        loop                                ;if equal goto case1

        call        RIGHT_WHEEL_FAST
        call        LEFT_WHEEL_SLOW
        goto        loop       
       
s2                                                        ;special case of robot when it turning left and get out of the line
        movlw        b'00000000'
        cpfseq        PORTA                                ;if equal skip
        goto        loop                                ;if equal goto case1

        call        LEFT_WHEEL_FAST
        call        RIGHT_WHEEL_SLOW
        goto        loop

;s3                                                        ;robot will stop while it follow the center and suddenly did not sence anything
;        movlw        b'00000111'
;        cpfseq        PORTA                                ;if equal skip
;        goto        loop                                ;if equal goto case1
       
;        call        LEFT_WHEEL_STOP       
;        call        RIGHT_WHEEL_STOP


case2                                                        ;in left hand side
        movlw        b'00000001'
        cpfseq        PORTA                                ;if equal skip
        goto        case3
       
        call        LEFT_WHEEL_FAST
        call        RIGHT_WHEEL_NORM
        goto        loop

case3                                                        ;completely in left hand side
        movlw        b'00000011'
        cpfseq        PORTA
        goto        case4
       
        call        LEFT_WHEEL_FAST
        call        RIGHT_WHEEL_SLOW
       
        goto        s2
       
case4                                                        ;right hand side
        movlw        b'00000100'
        cpfseq        PORTA
        goto        case5
       
        call        RIGHT_WHEEL_FAST
        call        LEFT_WHEEL_NORM
        goto        loop

case5                                                        ;center
        movlw        b'00000101'
        cpfseq        PORTA
        goto        case6
       
        call        RIGHT_WHEEL_NORM
        call        LEFT_WHEEL_NORM
        goto        loop

case6                                                        ;completely in right hand side
        movlw        b'00000110'
        cpfseq        PORTA
        goto        loop

        call        RIGHT_WHEEL_FAST
        call        LEFT_WHEEL_SLOW
        goto        s1


ahchu 23-04-2006 10:11 AM

anh Nam,
Mấy bữa bận quá nên chẳng lên mạng gì cà. Sau đây em xin trình bày tại sao lại như thế

Em sẽ viết tắt CCPR1:CCP1CON<5:4> thành CCPR1

PR2 = PWM period/ (4*Tosc*TMR2-1)

(CCPR1) = PWM duty cycle / (Tosc*TMR2)

PR2/(CCPR1) = (PWM period / 4*Tosc*TMR2) * (Tosc*TMR2 / PWM duty cycle)

50% duty cycle = 1/2 PWM period
và em có thể bỏ -1 trong biểu thức tính PR2

=> PR2/(CCPR1) = (2*PWM duty cycle / 4*Tosc*TMR2) * (Tosc*TMR2 / PWM duty cycle)

<=> PR2/(CCPR1) = 2/4 = 1/2

=> CCPR1 = 2*PR2

Em hy vọng là đúng phải kô anh??? Có ai chỉ dùm em đoạn code với....hic con robot của em ko quẹo được góc nhọn.....mà làm lại sensor bây giờ thì lâu lắm á

namqn 23-04-2006 10:57 PM

Như vậy là đúng rồi. Từ công thức tính PR2 và CCPR1:CCP1CON<5:4> thì có thể thấy ngay tỷ lệ giữa chúng. Nhưng điều chúng ta cần hiểu rõ ở đây không phải là công thức tính đó, mà là ưu điểm của việc thiết kế phần cứng của chip như vậy.

Microchip đã có thiết kế rất hay đối với module PWM. Với nhận định rằng chúng ta không cần độ phân giải cao cho tần số chuyển mạch, Microchip đã dùng tần số lệnh (4 lần tần số xung clock) để tạo tần số cho ngõ ra PWM. Tuy nhiên, chu kỳ nhiệm vụ (duty cycle) cần có độ phân giải cao hơn (để chúng ta điều chỉnh độ rộng xung được nhuyễn hơn), do đó Microchip dùng chính tần số xung clock làm đơn vị cho duty cycle. Đó là lý do trong công thức của PR2 có chia cho 4, còn của CCPR1:CCP1CON<5:4> thì không có. Lấy ví dụ bằng số cụ thể, nếu chúng ta dùng một số 8-bit để đặt tần số cho tín hiệu PWM, với 4 đơn vị đặt duty cycle mới bằng một đơn vị đặt tần số cho PWM, như vậy duty cycle của chúng ta đang được biểu diễn bằng một số 10-bit. Nói cách khác, duty cycle có độ phân giải cao hơn 4 lần so với tần số PWM. Đây là đặc điểm mà chúng ta cần nắm được, nếu không chúng ta có thể đánh giá thấp module PWM của PIC.

Bạn nào đang tìm hiểu dsPIC sẽ thấy module PWM của dsPIC chỉ có độ phân giải của duty cycle cao hơn của tần số PWM 2 lần (1-bit cao hơn). Lý do của điều này, theo tôi, là do tần số clock (và do đó tần số lệnh) của dsPIC là khá cao, do đó độ phân giải của tần số PWM đã cao hơn so với của các PIC 8-bit, như vậy độ phân giải của duty cycle so với của tần số PWM không cần thiết phải cao hơn đến 4 lần như trong PIC.

Thân,

ahchu 24-04-2006 01:19 AM

Anh nam có thể giải thích về prescale và resolution cho em biết được kô? Em chưa có khái niệm rõ lắm về 2 dịnh nghĩa này.

ahchu 29-04-2006 10:35 PM

ừm....Em nghĩ ra một cách để khắc phục việc quẹo góc nhọn là như sau: em sẽ tạo ra 2 function định nghĩa về góc nhọn cho robot. 1 function định nghĩa về góc nhọn quẹo trái: 101 -> 100 -> 000 -> 001 -> 011 (giữa line -> đèn bên trái nằm trong line -> cả 3 đèn cùng trên line -> đèn bên trái ra khỏi line trước -> đèn trái và đèn giữa ra khỏi line). Robot đang đi giữa line sẽ check điều kiện đặc biệt này, nếu như kô đúng thì sẽ nhảy về những trường hợp bình thường. (Đèn trái là bit 0, đèn giữa là bit 1 và đèn phải là bit 2).
Tuy nhiên lúc em đặt đoạn code trên như sau:
Code:

loop
        movf        PORTA,0
        movwf        PORTB
        goto        case1

STL
        movlw        b'00000100'
        cpfseq        PORTA       
        return
        movlw        b'00000000'
        cpfseq        PORTA                                                               
        return
        movlw        b'00000001'
        cpfseq        PORTA                               
        return
        movlw        b'00000011'
        cpfseq        PORTA       
        return
s1       
        call        RIGHT_WHEEL_FAST
        call        LEFT_WHEEL_SLOW       
       
        movlw        b'00000101'
        cpfseq        PORTA       
        return
        goto        s1

STR
        movlw        b'00000001'
        cpfseq        PORTA       
        return
        movlw        b'00000000'
        cpfseq        PORTA                                                               
        return
        movlw        b'00000100'
        cpfseq        PORTA                               
        return
        movlw        b'00000110'
        cpfseq        PORTA       
        return
s2
        call        RIGHT_WHEEL_SLOW
        call        LEFT_WHEEL_FAST
       
        movlw        b'00000101'
        cpfseq        PORTA       
        return
        goto        s2

special
        call        STL
        call        STR
        goto        case2
       
case1                                                        ;center
        movlw        b'00000101'
        cpfseq        PORTA                                ;if equal skip
        goto        special
       
        call        LEFT_WHEEL_NORM
        call        RIGHT_WHEEL_NORM

        goto        loop

case2                                                        ;on left hand side
        movlw        b'00000001'
        cpfseq        PORTA
        goto        case3
       
        call        LEFT_WHEEL_FAST
        call        RIGHT_WHEEL_NORM
        goto        loop

.... như đoạn code ở bài trên

thì dường như là nó kô check được điều kiện đăc biệt

STL: Sharp Turn Left (góc nhọn bên trái)
STR: Sharp Turn Right (góc nhọn bên phải)

Em nghĩ là phải cần có interupt để can thiệp vào nhưng kô biết phải làm sao cả. Mong mọi người giúp em.
Hay em nghĩ là 3 sensor đặt ngang hàng thì kô thể nào quẹo góc nhọn được....em cũng chẳng biết nữa....em bó tay rồi. hic. Em đọc tài liệu trên mạng thì thấy sensor toàn đặt theo kiểu mũi tên chứ kô đặt thẳng hàng....

namqn 30-04-2006 07:22 PM

Trích:

Nguyên văn bởi ahchu
Anh nam có thể giải thích về prescale và resolution cho em biết được kô? Em chưa có khái niệm rõ lắm về 2 dịnh nghĩa này.

Tình cờ xem lại mới phát hiện ra em hỏi câu này cách đây 1 tuần rồi, có lẽ hôm đó có nhiều bài mới quá nên cái post này của em đã đi khỏi danh sách bài mới trước khi anh vào lại forum.

Prescale thông thường là một mạch đếm theo lũy thừa của 2, dùng để hạ thấp tần số đưa vào các ngoại vi. Chẳng hạn, em muốn tính thời gian trôi qua bằng cách đếm số chu kỳ lệnh đã được thực hiện. Nhưng nếu đếm trực tiếp thì số lệnh cần đếm cho một số ứng dụng lại quá lớn (như làm trễ một vài phần mười giây thì cần đến hàng triệu chu kỳ lệnh), vì các timer thông thường trong các vi xử lý 8-bit cũng chỉ có thể đếm đến 16-bit (tức là tối đa là 65536 chu kỳ lệnh). Khi chúng ta dùng prescaler với hệ số thì chúng ta chỉ đếm thêm một đơn vị mỗi khi có chu kỳ lệnh đã trôi qua. Tuy nhiên với các ứng dụng cần tốc độ cao thì chúng ta sẽ cần đếm nhanh hơn, với prescaler có hệ số gần với 1:1. Việc dùng prescaler cho phép chúng ta dùng cùng một phần cứng cho nhiều mục đích khác nhau một cách linh hoạt.

Về độ phân giải (resolution), có thể giải thích qua ví dụ như sau. Lấy ví dụ chúng ta cần điều chỉnh độ rộng xung (PWM) của một bộ biến đổi điện áp DC sang DC. Bộ biến đổi này có điện áp ra trung bình phụ thuộc vào điện áp vào cho bởi:

với D là chu kỳ nhiệm vụ (duty cycle) của tín hiệu PWM, thay đổi từ 0 đến 1.
Bây giờ giả sử chúng ta dùng 2 bit để biểu diễn D của tín hiệu PWM. Như vậy '00' sẽ cho D=0, '01' sẽ cho D=0.25, '10' sẽ cho D=0.5, và '11' sẽ cho D=0.75. Như vậy không tốt lắm phải không? Tất nhiên, vì chúng ta chỉ dùng 2 bit để biểu diễn D, do đó mỗi đơn vị sẽ tương ứng với của toàn bộ phạm vi thay đổi của D. Với cách thực hiện này, chúng ta sẽ gặp khó khăn khi cần có D=0.6. Để có thể biểu diễn phạm vi thay đổi của D một cách tương đối liên tục hơn, chúng ta sẽ cần dùng nhiều bit. Hy vọng đến đây em có thể nắm được khái niệm này. Em có thể tự tính ra xem mức độ liên tục của các giá trị D được biểu diễn bằng 8-bit, và 10-bit.

Còn cái vụ robot thì anh mù tịt, hy vọng các bạn khác có thể giúp em.

Thân,

ahchu 07-05-2006 10:16 AM

2 Attachment(s)
Anh Nam,
Đây là con robot của em :) (làm lần đầu cho nên dùng băng keo kô). À tiện thể hỏi anh luôn là anh biết anh Hùng và anh Thông ở khoa điện tử DHBK TPHCM kô?

namqn 07-05-2006 06:31 PM

Em làm lần đầu mà được như vậy là quá tốt rồi.

Bên BM Điện tử của ĐHBK Tp. HCM có anh Hoàng Phi Hùng (chắc bây giờ đang ở Arkansas), anh Võ Tấn Thông, và anh Lê Chí Thông (nghe nói đang học ở Úc). Những người đó anh đều biết rõ, vì làm việc với nhau thường xuyên.

Thân,

minhpic 08-05-2006 04:09 PM

Cám ơn trưởng lão, quả không hỗ danh. Ông anh quả siêu phàm, ngay từ những ngày đầu khi làm về PWM em cũng đã tự đặt ra câu hỏi tại sao chỉ dùng 8 bit cho tần số PWM mà lại có độ phân giải 1/1024. Vấn đề này em cũng đã tranh luận cùng với Bác BA bên DTVN, xin cám ơn trưởng lão, như vậy là đàn em cũng đã không sai.

ayuh 13-01-2008 10:10 PM

Ahchu!
Mình cũng đang làm về 18f452.bạn có thể cho mình nịck để tiện liên lạc không.
Nick của mình là bk_mammam@yahoo.com


Múi giờ GMT. Hiện tại là 09:13 AM.

Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam