PDA

View Full Version : Cách update duty cycle cho PWM của PIC16f877a


uydanh
14-01-2008, 05:09 PM
Xin chào!
Mình đang tìm cách update duty cyce cho mudule PWM nhưng đang bị bế tắc (bằng hợp ngữ).
Dutycycle của PWM phụ thuộc vào việc cài đặt giá trị cho 10 bit : 8 bit của thanh ghi CCPRxL và 2 bit DCxB1 : DCxB0. Mình muốn cứ 10ms thì sẽ tăng hoặc giảm giá trị duty cycle này (thí dụ tăng hoặc giảm 1 chẳng hạn), chẳng lẽ mình phải giảm 2 bit DCxB1 : DCxB0 trước, rồi sao đó phải "canh" 2 bit này về 0 hay chưa rồi giảm 8 bit còn lại? Bạn nào có kinh nghiệm giúp mình với. Cảm ơn rất nhiều. Mình viết bằng hợp ngữ nha các bạn!

namqn
14-01-2008, 08:16 PM
Bạn có thể làm đơn giản hơn: viết một đoạn code cập nhật các bit <DCxB1>:<DCxB0> và thanh ghi CCPRxL mỗi khi bạn muốn cập nhật duty cycle của module CCP ở chế độ PWM. Như vậy bạn có thể đảm bảo là mỗi lần bạn cập nhật duty cycle thì PIC sẽ dùng cùng số chu kỳ máy, thay vì có số chu kỳ máy thay đổi tùy theo việc có cần cập nhật 8 bit cao hơn hay chỉ cập nhật 2 bit thấp.

Thân,

uydanh
15-01-2008, 09:49 AM
Em vẫn chưa hiểu! Ví dụ như ban đầu em đặt duty cycle là 30%(thế vào công thức tìm ra giá trị thanh ghi CCPR1L và 2 bit DCxB1 : DCxB0), sau đó em muốn cập nhật duty cycle là 50%, em nghĩ để làm được như vậy em lại phải "giải phương trình" công thức tính duty cycle của PWM, để tìm giá trị của DCxB9 : DCxB0. Cho em hởi có cách nào khác để cập nhật không? chứ làm như vậy viết bằng hợp ngữ khó quá!

namqn
15-01-2008, 07:06 PM
Đương nhiên là bạn phải tính toán để có giá trị 10-bit mới rồi mới ghi vào các bit và thanh ghi tương ứng. Tất nhiên viết bằng hợp ngữ thì sẽ khó khăn hơn so với viết bằng các ngôn ngữ cấp cao như C, Pascal hay Basic.

Với mục đích học tập, bạn có thể chấp nhận một công thức gần đúng: 2^10 gần bằng 1000. Như vậy 100% duty tương ứng với 1000, có nghĩa là 1% tương ứng với 10. Do đó, mỗi khi thay đổi duty cycle (tính bằng %), bạn chỉ cần nhân nó với 10 để có giá trị 10-bit cần thiết. Trong hợp ngữ, nhân với 10 cũng khá đơn giản, chính là lấy số đó nhân 8 (dịch trái 3 bit) cộng với số đó nhân 2 (dịch trái 1 bit). Chỉ cần chú ý vấn đề tràn số khi dịch trái 3 bit (vì số của bạn chỉ <= 100 nên dịch trái 1 bit sẽ không bao giờ bị tràn).

Thân,