Аппаратный PWM (ШИМ) #
К СВЕДЕНИЮ
Библиотека WiringRP предоставляет функции для управления встроенным в SoC аппаратным ШИМ-контроллером (PWM0).
-
На Repka Pi 3 (SoC Allwinner H5): Выход PWM0 подключен к контакту PL10 (физический пин 33) и аппаратно доступен только в 5-м варианте распиновки GPIO-разъема.
-
На Repka Pi 4 (SoC Allwinner H6): В текущих версиях образа Repka OS аппаратный ШИМ-контроллер не активирован в дереве устройств (Device Tree). В связи с этим, функции для работы с аппаратным ШИМ на Repka Pi 4 не работают. Для генерации ШИМ-сигнала на Repka Pi 4 используйте функции программного ШИМ (раздел
Soft PWM).
setupPwm() #
Инициализирует функцию управления интегрированным ШИМ контроллером.
Синтаксис #
int setupPwm(void)
Параметры #
Ничего.
Возврат #
0 при успешном выполнении, или отрицательное значение в случае ошибки.
releasePwm() #
Высвобождает ресурсы задействованные функцией управления интегрированным ШИМ контроллером.
Синтаксис #
void releasePwm(void)
Параметры #
Ничего.
Возврат #
Ничего.
pwmSetClock() #
Устанавливает предделитель системной частоты таймера OSC24MHz ШИМ.
Синтаксис #
void pwmSetClock(int divisor)
Параметры #
divisor - значение предделителя частоты таймера OSC24MHz ШИМ, допустимые значения:
PWM_CLK_DIV_120(значение по умолчанию).PWM_CLK_DIV_180.PWM_CLK_DIV_240.PWM_CLK_DIV_360.PWM_CLK_DIV_480.PWM_CLK_DIV_12K.PWM_CLK_DIV_24K.PWM_CLK_DIV_36K.PWM_CLK_DIV_48K.PWM_CLK_DIV_72K.PWM_CLK_DIV_1.
Возврат #
Ничего.
pwmSetMode() #
Устанавливает режим генерирования сигнала ШИМ контроллером.
Синтаксис #
void pwmSetMode(int mode)
Параметры #
mode - значение режима генерирования сигнала ШИМ контроллером, допустимые значения:
PWM_CYCLE_MODE- цикл.PWM_PULSE_MODE- пульс.
Возврат #
Ничего.
pwmSetRange() #
Устанавливает количество полных циклов в тактовой частоте ШИМ.
Синтаксис #
void pwmSetRange(unsigned int range)
Параметры #
range - количество полных циклов в тактовой частоте, вычисляемой по формуле PWM_CLK = 24 MHz / pre-scale. Принимает значение в диапазоне от 0 до 65535.
Возврат #
Ничего.
pwmWrite() #
Устанавливает количество активных циклов в тактовой частоте ШИМ.
Синтаксис #
void pwmWrite(int value)
Параметры #
value - количество активных циклов в тактовой частоте, вычисляемой по формуле PWM_CLK = 24 MHz / pre-scale. Принимает значение в диапазоне от 0 до 65535. Для значения должно выполнятся условие value <= range (см. pwmSetRange() выше).
Возврат #
Ничего.
pwmToneWrite() #
Устанавливает частоту модулируемого ШИМ сигнала. Использоваться для генерации нот и аккордов.
Синтаксис #
void pwmToneWrite(int freq)
Параметры #
freq - частота сигнала. Принимает значение в диапазоне от 0 до 65535.
Возврат #
Ничего.
Пример использования pwmWrite #
Код имитирует аналоговый выход с помощью широтно-импульсной модуляции для изменения яркости свечения светодиода, подключенного к выходу контроллера PWM0 (PL10). Уровень яркости задается в диапазоне от 0% до 100%, и отображается в целевой диапазон от 0 до 1000 с помощью функции map().
предупреждение
Пример может быть запущен только на 5-ом варианте распиновки GPIO-разъема.
#include <stdlib.h>
#include "wiringRP.h"
#include "pwm.h"
// Глобальные переменные и константы
void setup() {
// Инициализация библиотек wiringRP
if(setupWiringRP(WRP_MODE_SUNXI) < 0)
exit(EXIT_FAILURE);
setupPwm();
// Инициализация пользовательских объектов
pwmSetClock(PWM_CLK_DIV_120);
pwmSetMode(PWM_CYCLE_MODE);
pwmSetRange(1000);
}
void loop() {
// Основной цикл программы
for (int i = 0; i < 100; i++) {
int val = map(i, 0, 100, 0, 1000);
pwmWrite(val);
delay(10);
}
for (int i = 100; i > 0; i--) {
int val = map(i, 0, 100, 0, 1000);
pwmWrite(val);
delay(10);
}
}
ONDESTROY() {
// Освобождение занятых ресурсов, выключение напряжения на пинах
pwmWrite(0);
// Завершение работы библиотек
releaseWiringRP();
releasePwm();
exit(0); // выход из программы
}
MAIN_WIRINGRP();
Пример использования pwmTone #
Код запускает функцию частотно-импульсной модуляции (24 MHz) для воспроизведения мелодии на пьезоэлектрическом динамике, подключенном к выходу контроллера PWM0 (PL10).
предупреждение
Пример может быть запущен только на 5-ом варианте распиновки GPIO-разъема.
#include <stdlib.h>
#include "wiringRP.h"
#include "pwm.h"
// Глобальные переменные и константы
const int frq[17] = {440, 165, 440, 440, 165, 440, 330, 294, 262, 494, 440, 494, 262, 294, 330, 165, 440};
const int pause[17] = {250, 250, 250, 250, 250, 250, 125, 125, 125, 125, 125, 125, 125, 125, 250, 250, 250};
void setup() {
// Инициализация библиотек wiringRP
if(setupWiringRP(WRP_MODE_SUNXI) < 0)
exit(EXIT_FAILURE);
setupPwm();
// Инициализация пользовательских объектов
pwmSetClock(PWM_CLK_DIV_120);
pwmSetMode(PWM_CYCLE_MODE);
pwmSetRange(65535);
}
void loop() {
// Основной цикл программы
for (int j = 0; j < 17; j++) {
pwmToneWrite(frq[j]);
delay(pause[j]);
pwmToneWrite(0);
delay(pause[j]);
}
}
ONDESTROY() {
// Освобождение занятых ресурсов, выключение напряжения на пинах
pwmWrite(0);
// Завершение работы библиотек
releasePwm();
releaseWiringRP();
exit(0); // выход из программы
}
MAIN_WIRINGRP();
Пример использования Servo PWM #
Код формирует импульсы для управления серводвигателем SG90, подключенным к выходу контроллера PWM0 (PL10).
предупреждение
Пример может быть запущен только на 5-ом варианте распиновки GPIO-разъема.
// For servo SG90 (5V)
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "wiringRP.h"
#include "pwm.h"
// Глобальные переменные и константы
const int DEG_0 = 110;
const int DEG_180 = 510;
const int PULSE_TIME = 2;
const int STEP_DEG = 1;
const int DECELERATION = 1;
void setup() {
// Инициализация библиотек wiringRP
if(setupWiringRP(WRP_MODE_SUNXI) < 0)
exit(EXIT_FAILURE);
setupPwm();
// Инициализация пользовательских объектов
pwmSetClock(PWM_CLK_DIV_120);
pwmSetMode(PWM_CYCLE_MODE);
pwmSetRange(3999); // 50 Hz
}
void loop() {
// Основной цикл программы
// Поворот вала ротора на 180 градусов по часовой стрелке с максимальной скоростью
for (int i = 0; i <= 180; i += STEP_DEG) {
int val = map(i, 0, 180, DEG_0, DEG_180);
pwmWrite(val);
delay(PULSE_TIME * DECELERATION * STEP_DEG);
}
// Поворот вала ротора на 180 градусов против часовой стрелки с максимальной скоростью
for (int i = 180; i >= 0; i -= STEP_DEG) {
int val = map(i, 0, 180, DEG_0, DEG_180);
pwmWrite(val);
delay(PULSE_TIME * DECELERATION * STEP_DEG);
}
}
ONDESTROY() {
// Освобождение занятых ресурсов, выключение напряжения на пинах
pwmWrite(0);
// Завершение работы библиотек
releaseWiringRP();
releasePwm();
exit(0); // выход из программы
}
MAIN_WIRINGRP();