|
Tài trợ cho PIC Vietnam |
Lỗi lập trình ngôn ngữ cấp cao Những lỗi trường gặp trong lập trình. Khóa luồng khi bug được lỗi. |
|
Ðiều Chỉnh | Xếp Bài |
|
20-01-2010, 11:43 AM | #1 | ||
Trưởng lão PIC bang
|
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:
Trích:
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,
__________________
Biển học mênh mông, sức người có hạn. Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau: http://www.picvietnam.com/forum/showthread.php?t=1263 |
||
20-01-2010, 01:19 PM | #2 |
Đệ tử 1 túi
Tham gia ngày: Jan 2009
Bài gửi: 17
: |
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? |
20-01-2010, 10:01 PM | #3 | |
Trưởng lão PIC bang
|
Trích:
Thân,
__________________
Biển học mênh mông, sức người có hạn. Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau: http://www.picvietnam.com/forum/showthread.php?t=1263 |
|
21-01-2010, 12:42 AM | #4 |
Đệ tử 1 túi
Tham gia ngày: Jan 2009
Bài gửi: 17
: |
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 DCxB9CxB0 Biểu thức sau dùng để tính duty PWM: PWM duty cycle = (DCxB9CxB0 bits value) • Tosc • (TMR2 prescale value) , (PWM duty tính theo đơn vị thời gian) Có thể ghi giá trị cho (DCxB9CxB0) 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. |
21-01-2010, 12:55 AM | #5 |
Đệ tử 1 túi
Tham gia ngày: Jan 2009
Bài gửi: 17
: |
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. |
|
|