Tại sao một số chân có tần số PWM khác nhau?


20

Theo tài liệu tham khảo Arduino choanalogWrite() , tần số PWM trên hầu hết các chân là ~ 490 Hz. Tuy nhiên, đó là ~ 980 Hz cho chân 5 và 6 trên Uno và cho chân 3 và 11 trên Leonardo.

Tại sao những điều này khác nhau? Đây có phải là một tính năng thiết kế có chủ ý, hoặc bằng cách nào đó được quyết định bởi phần cứng?

Câu trả lời:


23

Chúng không phải là tần số duy nhất có sẵn cho các tín hiệu PWM. Tuy nhiên, chúng là các tần số được xác định bởi bộ đếm gộp được áp dụng (mà bạn có thể dễ dàng thay đổi như chi tiết bên dưới).

Mỗi trong số 3 cặp chân PWM được gắn với một bộ đếm thời gian, mỗi cặp có tần số cơ bản riêng, như sau:

  • Các chân 5 và 6 được ghép nối trên timer0, với tần số cơ bản là 62500Hz
  • Các chân 9 và 10 được ghép nối trên bộ định thời1, với tần số cơ bản là 31250Hz
  • Các chân 3 và 11 được ghép nối trên bộ đếm thời gian2, với tần số cơ bản là 31250Hz

Sau đó, mỗi bộ chân có một số giá trị bộ đếm gộp có thể được chọn, nó sẽ chia tần số cơ sở của cặp chân đó. Các giá trị prescaler có sẵn là:

  • Các chân 5 và 6 có các giá trị đặt trước là 1, 8, 64, 256 và 1024
  • Các chân 9 và 10 có các giá trị bộ đếm trước là 1, 8, 64, 256 và 1024
  • Các chân 3 và 11 có các giá trị đặt trước là 1, 8, 32, 64, 128, 256 và 1024

Các kết hợp khác nhau mang lại tần số khác nhau trong một chân PWM nhất định. Lưu ý rằng bộ định thời 2 (gắn với chân 3 và 11) có sẵn nhiều giá trị bộ đếm gộp hơn, dẫn đến tần số khả dụng nhiều hơn.

Bây giờ, tại sao bộ đếm thời gian 2 lại khác, đó là một câu hỏi riêng biệt.

Chỉnh sửa: Đây là danh sách các tần số PWM có thể có trên mỗi pin (từ bài viết này ):

Đối với chân 6 và 5 (OC0A và OC0B):

  • Nếu TCCR0B = xxxxx001, tần số là 64kHz
  • Nếu TCCR0B = xxxxx010, tần số là 8 kHz
  • Nếu TCCR0B = xxxxx011, tần số là 1kHz (đây là mặc định từ bộ tải khởi động Diecimila)
  • Nếu TCCR0B = xxxxx100, tần số là 250Hz
  • Nếu TCCR0B = xxxxx101, tần số là 62,5 Hz

Đối với các chân 9, 10, 11 và 3 (OC1A, OC1B, OC2A, OC2B):

  • Nếu TCCRnB = xxxxx001, tần số là 32kHz
  • Nếu TCCRnB = xxxxx010, tần số là 4 kHz
  • Nếu TCCRnB = xxxxx011, tần số là 500Hz (đây là mặc định từ bộ tải khởi động Diecimila)
  • Nếu TCCRnB = xxxxx100, tần số là 125Hz
  • Nếu TCCRnB = xxxxx101, tần số là 31,25 Hz

TCCRnBlà nơi bạn đặt các bit đặt trước cho bộ định thời n, thay thế nbằng 0, 1 hoặc 2, tùy thuộc vào bộ định thời bạn muốn đặt. Nếu bạn vẫn không chắc chắn về các phép toán bitwise, hãy đọc hướng dẫn toán học bit này .

Nguồn của tôi:

Lưu ý rằng dường như có sự khác biệt trong các nguồn đó về việc liệu chân 9 và 10 có hành vi tương tự như 5 và 6 hoặc 3 và 11 hay không, nhưng dù sao bạn cũng hiểu ý. Tôi đang đọc bảng dữ liệu để thử và tìm ra cái nào là chính xác, hoặc liệu đây có phải là sự khác biệt giữa các bảng không.


1
Câu trả lời này của ATmega là gì? Tôi đã không kiểm tra, nhưng tôi cá là nó hơi khác nhau trên mỗi bộ điều khiển.
jippie

@jippie Điểm hay! Các nguồn tham khảo ATmega168 và 328.
Ricardo

@jippie Chỉ cần làm rõ, trong câu trả lời của tôi, số pin đề cập đến cách chúng được gán trên bảng Uno (ví dụ: pin 1 có nghĩa là Pin kỹ thuật số 1, hoặc D1), chứ không phải IC (pin ATmega328 1 được đặt lại).
Ricardo

1
Tôi tin rằng những chi tiết đó cũng thay đổi với các bảng, Uno, Duemilanove, Mega, ...
jippie

@jippie Chắc chắn, vâng.
Ricardo

8

Tôi không biết về các cân nhắc thiết kế, nhưng nếu bạn kiểm tra biểu dữ liệu cho vi điều khiển trên Arduino của bạn, bạn sẽ nhận thấy rằng các chân PWM được nhóm lại với nhau và mỗi nhóm được kết nối với bộ hẹn giờ. Tốc độ mà bộ đếm thời gian này được tăng lên thay đổi tùy theo bộ đếm gộp được cấu hình. Nếu bạn thay đổi bộ đếm gộp trước cho một bộ định thời gian nhất định, bạn sẽ thay đổi tần số PWM cho các chân PWM liên quan. Tôi tin rằng một số bộ định thời tăng gấp đôi cho các mục đích khác như millis();chức năng. Nếu bạn thay đổi bộ đếm gộp cho bộ định thời gian đó, các giá trị được trả về millis()sẽ bị tắt theo cùng một yếu tố.

Bạn có thể tính toán cài đặt cho bộ đếm gộp như sau:

$$ \ text {prescaler} = \ dfrac {f_ {CPU}} {PWMresolution × f_ {PWM}} = \ dfrac {16 \ text {MHz}} {256 × 490} \ khoảng 128 $$

prescaler = f [CPU] / (PWMresolution × f [PWM]) = 16000000 / (256 × 490) = khoảng 128.

Kiểm tra biểu dữ liệu và bạn sẽ thấy rằng 128 thực sự là một trong những giá trị đặt trước mà bạn có thể chọn.


2
Cậu bé, chúng ta nhớ MathJax hay sao? Tôi hy vọng chúng tôi sẽ kích hoạt nó sau phiên bản beta.
Ricardo

1
@Ricardo Tôi có nút MathJax trong trình duyệt của mình; o) meta.arduino.stackexchange.com/questions/13/ mẹo
jippie
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.