PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   Lỗi lập trình ngôn ngữ cấp cao (http://www.picvietnam.com/forum/forumdisplay.php?f=65)
-   -   Lỗi thường gặp với set_pwm1_duty() của CCS C (http://www.picvietnam.com/forum/showthread.php?t=5772)

namqn 20-01-2010 11:43 AM

Lỗi thường gặp với set_pwm1_duty() của CCS C
 
Trong tài liệu hướng dẫn của CCS C có phần mô tả về hàm set_pwm1_duty() (và các hàm tương tự khác, set_pwmx_duty, x = 2 .. 5), được trích dẫn dưới đây:
Trích:

Writes the 10-bit value to the PWM to set the duty. An 8-bit value may be used if the least significant bits are not required. If value is an 8 bit item, it is shifted up with two zero bits in the lsb positions to get 10 bits. The 10 bit value is then used to determine the amount of time the PWM signal is high during each cycle as follows:
• value*(1/clock)*t2div
Vì đã có nhiều trường hợp hiểu sai về cách dùng hàm, nên tôi lược dịch phần mô tả này và giải thích dưới đây:
Trích:

Ghi giá trị 10-bit vào module PWM để thiết lập duty cycle. Có thể dùng một giá trị 8-bit nếu các bit có trọng số thấp nhất là không cần thiết. Nếu giá trị là một số 8-bit, nó được dịch trái 2 bit để có được giá trị 10-bit. Giá trị 10-bit này sẽ được dùng để xác định khoảng thời gian mà tín hiệu PWM ở mức cao trong mỗi chu kỳ như sau:
• value*(1/clock)*t2div
Giải thích: Nếu đối số của hàm là một biến thì trình dịch tự nhiên có thể xác định được kích thước của đối số (8-bit hay 16-bit). Nhưng nếu đối số là một hằng số thì trình dịch sẽ tự quyết định kích thước của đối số dựa vào giá trị (nếu giá trị <= 255 thì cần 8-bit, còn giá trị > 255 thì cần 16-bit). Trong trường hợp đối số là một hằng số <= 255, cần chú ý rằng giá trị của đối số sẽ được dịch trái 2 bit rồi mới dùng để thiết lập duty cycle cho module PWM.

Nói tóm lại, nếu đối số value là một giá trị 8-bit thì duty cycle sẽ được tính là: duty cycle = value/(PR2 + 1). Nếu đối số là một giá trị 10-bit (chứa trong một ô nhớ 16-bit) thì duty cycle sẽ được tính là: duty cycle = value/[4*(PR2 + 1)].

Thân,

minhcuong1122 20-01-2010 01:19 PM

vậy nghĩa là nếu e muốn tạo sóng 120Khz, duty 50% với
Fosc = 7.680Mhz, chọn prescaler T2 = 16,
-> PR2 = 0
Thì không thể nào dùng hàm set_PWMx_duty() để đặt giá trị value được.
Thay vào đó, hoặc phải dùng cách gán trực tiếp giá trị cho thanh ghi (10bits)
hoặc chọn lại prescaler, rồi tính lại PR2 và tính lại giá trị value.
E hiểu vậy có đúng không a Nam?

namqn 20-01-2010 10:01 PM

Trích:

Nguyên văn bởi minhcuong1122 (Post 33208)
vậy nghĩa là nếu e muốn tạo sóng 120Khz, duty 50% với
Fosc = 7.680Mhz, chọn prescaler T2 = 16,
-> PR2 = 0
Thì không thể nào dùng hàm set_PWMx_duty() để đặt giá trị value được.
Thay vào đó, hoặc phải dùng cách gán trực tiếp giá trị cho thanh ghi (10bits)
hoặc chọn lại prescaler, rồi tính lại PR2 và tính lại giá trị value.
E hiểu vậy có đúng không a Nam?

Nếu bạn thiết lập như vậy thì quả thực chỉ có cách gán giá trị cho các thanh ghi (vì chỉ còn có 2 bit để thay đổi duty cycle một cách có ý nghĩa, mà 2 bit này thì hàm set_pwmx_duty() trong trường hợp này luôn luôn đặt là 0).

Thân,

minhcuong1122 21-01-2010 12:42 AM

E có một thắc mắc về công thức tính giá trị đặt cho PR2 và Duty. Trong tài liệu về Mid-range (phần PWM trang 211), e thử dịch lại là:
Duty được xác định bằng cách ghi giá trị vào thanh ghi CCPRXL và 2 bits (CCPxCON<5:4>).
Ta có thể có độ phân giải 10 bits: CCPRxL chứa 8 bit MSB và CCPxCON<5:4> chứa 2 bit LSB
Gía trị 10 bits này được xem như chứa trong 1 thanh ghi DCxB9:DCxB0
Biểu thức sau dùng để tính duty PWM:
PWM duty cycle = (DCxB9:DCxB0 bits value) • Tosc • (TMR2 prescale value) , (PWM duty tính theo đơn vị thời gian)
Có thể ghi giá trị cho (DCxB9:DCxB0) bất cứ lúc nào, nhưng giá trị duty này sẽ không ảnh hưởng tới xung ngõ ra,
cho đến khi kết thúc chu kì xung hiện tại (TMR2 = PR2), và cho tới lúc đó giá trị duty mới được chốt vào thanh ghi CCPRxH
Khi khối CCP hoạt động ở chế độ PWM thì không thể ghi trực tiếp giá trị vào thanh ghi CCPRxH (read-only)
Thanh ghi CCPRxH và 2bit (...) có chức năng như một bộ đệm duty thứ 2 để tránh những lỗi có thể xảy ra khi nạp lại giá trị duty
Khi giá trị (TMR2 ghép với 2 bit bộ chia T2) bằng với (CCPRxH và 2 bit) thì chân CCPx sẽ xuống mức [0] và nghĩa là kết thúc duty.

minhcuong1122 21-01-2010 12:55 AM

Trong này có đề cập tới 2 bit cuối thêm vào TMR2 (prescaler) để cũng tạo thành một giá trị 10 bits, giá trị này được so với cái value (CCPRxH . CCPxCON<5:4>) để khi nào bằng nhau thì clear chân CCPx.
E thật tình không hiểu nỗi tại sao giá trị (2bit LSB của 10bit mình tính ra) lại liên quan được với prescaler của timer 2 ???

Thêm nữa,
Công thức tính PWM chu kì:
PWM period = [(PR2) + 1] • 4 • TOSC • (TMR2 prescale value), specified in units of time
Công thức tính duty:
PWM duty cycle = (DCxB9 : DCxB0 bits value) • Tosc • (TMR2 prescale value), in units of time
Theo e hiểu, xung thạch anh phải qua bộ chia 4, rồi qua thêm bộ chia TMR2 thì mới làm cho TMR2 tăng lên 1 đơn vị, khi TMR2 tăng lên bằng (PR2+1) thì hết 1 chu kì
Còn ở phần duty thì công thức đã không còn số "4", thay vào đó thì hình như số 4 này đã nằm đâu đó trong giá trị thanh ghi 10 bits mình tính ra rồi???
E thấy có gì đó khó hiểu chỗ này, hình như việc sử dụng 2 bit này có ý đồ gì đó, các anh chị giúp e nhé.
@A Nam: Cảm ơn a Nam một lần nữa.


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