Kiểm soát tần số phần cứng PWM


21

Tôi đang sử dụng đầu ra PWM phần cứng với hệ thống dây dẫn. Nó cung cấp chức năng pwmSetClock để có thể thay đổi tần số. ( https://projects.drogon.net/raspberry-pi/wirespi/fifts/ ). Tôi tin rằng vì mặc định là 200 Mhz, việc đặt ước số thành 200000000 sẽ làm cho một đèn LED được nối với đèn flash đầu ra rõ ràng, nhưng đó không phải là trường hợp.

Điều này có thể được thay đổi?


1
Tôi đang thực hiện một số thử nghiệm với phần cứng PWM và dường như nó không có tần số fiexd. Nó thay đổi dựa trên độ rộng xung được đặt trong pwmWrite(). Không có điều gì tôi mong đợi sẽ xảy ra
TheMeaningfulEngineer

Câu trả lời:


25

Gần đây tôi đã có một số lý do để bắt đầu thử nghiệm với PWM, và thấy rằng (như được chỉ ra bởi một trong những ý kiến) tần số dường như thay đổi theo chu kỳ nhiệm vụ - bizzare, phải không? Nó chỉ ra rằng Broadcom đã triển khai PWM "cân bằng" để làm cho các xung PWM bật và tắt phân bố đều nhất có thể. Họ đưa ra một mô tả về thuật toán và một số thảo luận thêm trên trang 139 của bảng dữ liệu của họ: http://www.element14.com/community/servlet/JiveServlet/doadBody/43016-102-1-231518/Broadcom.Datasheet.pdf

Vì vậy, những gì bạn thực sự muốn là đặt PWM ở chế độ không gian đánh dấu, sẽ cung cấp cho bạn các PWM truyền thống (và có thể dự đoán được) mà bạn đang tìm kiếm:

pwmSetMode(PWM_MODE_MS);

Phần còn lại của câu trả lời cho rằng chúng ta đang ở chế độ không gian đánh dấu.

Tôi cũng đã thực hiện một số thử nghiệm với phạm vi giá trị cho phép pwmSetClock()pwmSetRange(). Như đã lưu ý trong một trong những câu trả lời khác, phạm vi hợp lệ pwmSetClock()dường như đi từ 2 đến 4095, trong khi phạm vi hợp lệ pwmSetRange()lên tới 4096 (tôi không cố gắng tìm giới hạn thấp hơn).

Phạm vi và đồng hồ (một tên tốt hơn có lẽ là ước số) cả hai đều ảnh hưởng đến tần số. Phạm vi cũng ảnh hưởng đến độ phân giải, do đó, trong khi có thể sử dụng các giá trị rất thấp, có một giới hạn thực tế về mức độ thấp mà bạn có thể muốn đi. Ví dụ: nếu bạn đã sử dụng phạm vi 4, bạn có thể đạt được tần số cao hơn, nhưng bạn sẽ chỉ có thể đặt chu kỳ nhiệm vụ thành 0/4, 1/4, 2/4, 3/4 hoặc 4/4.

Đồng hồ Raspberry Pi PWM có tần số cơ bản là 19,2 MHz. Tần số này, được chia cho đối số pwmSetClock()là, tần số mà bộ đếm PWM được tăng lên. Khi bộ đếm đạt giá trị bằng phạm vi đã chỉ định, nó sẽ đặt lại về không. Trong khi bộ đếm nhỏ hơn chu kỳ nhiệm vụ được chỉ định, đầu ra cao, nếu không thì đầu ra thấp.

Điều này có nghĩa là, nếu bạn muốn đặt PWM có tần số cụ thể, bạn có thể sử dụng mối quan hệ sau:

pwmFrequency in Hz = 19.2e6 Hz / pwmClock / pwmRange.

Nếu bạn sử dụng các giá trị tối đa cho phép cho pwmSetClock()pwmSetRange(), bạn sẽ kết thúc với tần số PWM phần cứng tối thiểu có thể đạt được là ~ 1,14 Hz. Điều này chắc chắn sẽ cung cấp ánh sáng nhấp nháy có thể nhìn thấy (thực sự nhiều hơn một đèn flash) cho đèn LED. Tôi đã xác nhận phương trình trên với một máy hiện sóng, và nó dường như giữ. Giới hạn tần số trên sẽ bị ảnh hưởng bởi độ phân giải bạn cần, như được mô tả ở trên.


Liên quan đến giới hạn dưới trên pwmRange: Tôi đặt thành công thành 2 (để có được chu kỳ thuế là 50%).
Ted Pudlik

Từ nguồn nào bạn biết rằng đồng hồ pwm có tần số 19,2 mhz?
thi gg

10

Theo công thức này:

pwmFrequency in Hz = 19.2e6 Hz / pwmClock / pwmRange

Chúng ta có thể thiết lập pwmClock=1920pwmRange=200nhận pwmFrequency=50Hz:

50 Hz = 19.2e6 Hz / 1920 / 200

Tôi kiểm tra nó trên alarmpi:

$ pacman -S wiringpi
$ gpio mode 1 pwm
$ gpio pwm-ms
$ gpio pwmc 1920
$ gpio pwmr 200     # 0.1 ms per unit
$ gpio pwm 1 15     # 1.5 ms (0º)
$ gpio pwm 1 20     # 2.0 ms (+90º)
$ gpio pwm 1 10     # 1.0 ms (-90º)

Lưu ý: Servo của tôi mong đợi tín hiệu 50Hz .


Làm thế nào để bạn đến: 'gpio pwmr 200 # 0,1 ms mỗi đơn vị'
mxlian

50Hz ---> 20ms mỗi chu kỳ. 20ms / 200 đơn vị =
0,1ms

5

Đây là mã tôi đang sử dụng. Tôi đang cố gắng xem những gì sẽ thay đổi khi tôi thay đổi cài đặt.

#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

int main (void)
{
  printf ("Raspberry Pi wiringPi test program\n") ;

  if (wiringPiSetupGpio() == -1)
    exit (1) ;

  pinMode(18,PWM_OUTPUT);
  pwmSetClock(2);
  pwmSetRange (10) ;
  pwmWrite (18, 5);

for (;;) delay (1000) ;
}

pwmSetClock (1); -> 2.342kHz

pwmSetClock (2); -> 4,81 MHz

pwmSetClock (3); -> 3,19 MHz

pwmSetClock (4); -> 2.398 MHz

pwmSetClock (5); -> 1.919 MHz

pwmSetClock (6); -> 1.6 MHz

pwmSetClock (7); -> 1,3 MHz

pwmSetClock (8); -> 1,2 MHz

pwmSetClock (9); -> 1.067 MHz

pwmSetClock (10); -> 959kHz

pwmSetClock (11); -> 871kHz

pwmSetClock (20); -> 480kHz

pwmSetClock (200); -> 48kHz

pwmSetClock (500); -> 19kHz

pwmSetClock (1000); -> 9,59kHz

pwmSetClock (2000); -> 4.802kHz

pwmSetClock (4000); -> 2.401kHz

pwmSetClock (5000); -> 10,58kHz

Từ những gì tôi đã kiểm tra, có vẻ như số chia đi từ 2 đến một số nhỏ hơn 5000. Tôi đoán nó có liên quan đến biểu diễn nhị phân của những số đó được đặt trực tiếp trong thanh ghi. Khi biểu diễn nhị phân số có nhiều bit hơn thanh ghi có thể lấy, chỉ cần lấy các bit đầu tiên và diễn giải các số theo cách đó. Đó là lý do tại sao các hành vi lạ xuất hiện khi đi từ 4000 đến 5000.


1
Làm thế nào tôi thay đổi chu kỳ nhiệm vụ?
noufal

Làm thế nào bạn đo được tần số?
Seanny123
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.