Широкоимпульсная модуляция
Код может быть уже понятен, но обратите внимание на следующие детали:
- Эта функция выбирает конфигурацию IOF для всех 4 пинов GPIO, связанных с устройством ШИМ. Это не всегда то, что нам нужно. На самом деле, в данном примере мы хотим использовать только PWM1_1, который использует GPIO0, вывод 19. Поэтому, возможно, мы захотим изменить значение io_en после использования этой функции. Об этом позаботится функция metal_gpio_disable_pinmux(). Пины GPIO, связанные с PWM1, - это 19, 20, 21 и 22, поэтому мы можем вызвать эту функцию для тех пинов, которые мы хотим использовать в качестве GPIO.
- metal_pwm_set_freq() Эта функция получает в качестве третьего аргумента частоту, которую вы хотите получить от этого ШИМ-сигнала. Это хорошая функция, которая избавляет вас от необходимости вычислять период в единицах предварительно масштабированного счетчика.
- metal_pwm_set_duty() Эта функция получает в качестве третьего аргумента нужный вам рабочий цикл, поэтому он должен быть числом от 0 до 100. Более того, это беззнаковое число. В четвертом аргументе мы имеем макрос METAL_PWM_PHASE_CORRECT_DISABLE, что нормально. Альтернативой этому является генерация выровненного по центру ШИМ-сигнала, но это невозможно в выбранном нами режиме
- metal_pwm_trigger() Это запускает счетчик в непрерывном режиме
Функции ШИМ НЕ в библиотеке Freedom Metal
Вспомните, что код, который мы только что рассмотрели, будет генерировать ШИМ-сигнал с активным низким уровнем. Другими словами, рабочий цикл выходного сигнала будет составлять 30% вместо 70%. Это может быть нормально, если вы управляете нагрузкой с активным низким уровнем, но, если вам нужно инвертировать логику, вы можете просто установить бит XOR для используемого пина GPIO. В случае с PWM1_1 это будет пин 19 GPIO0.
Мы также можем использовать высокий уровень выходного сигнала, чтобы иметь возможность управлять уровнем яркости внешнего светодиода. Как и в случае с включением подтягивающих резисторов, в библиотеке Freedom Metal Library нет функций для включения или отключения высокой выходной мощности или XOR выхода для инвертирования его значения. Поэтому мы можем использовать макрофункции Red_V_enable_XOR() и Red_V_enable_DS(), приведенные ниже.
#define Red_V_enable_DS(x) *((uint32_t *) 0x10012014) |= (1<<(x)) #define Red_V_enable_XOR(x) *((uint32_t *) 0x10012040) |= (1<<(x)) // Мы будем использовать PWM1_1, который использует GPIO0_19. Red_V_enable_DS(19); // Высокий уровень сигнала на выходе Red_V_enable_XOR(19); // Инвертируем выход для активно-высокого ШИМ
Адреса регистров ШИМ в библиотеке Freedom Metal Library
Как и в случае с GPIO, макроопределения базового адреса и смещения регистра можно найти в файле./bsp/install/include/metal/machine/platform.h:
/* Из pwm@10015000 */ #define METAL_SIFIVE_PWM0_10015000_BASE_ADDRESS 268521472UL #define METAL_SIFIVE_PWM0_0_BASE_ADDRESS 268521472UL #define METAL_SIFIVE_PWM0_10015000_SIZE 4096UL #define METAL_SIFIVE_PWM0_0_SIZE 4096UL /* Из pwm@10025000 */ #define METAL_SIFIVE_PWM0_10025000_BASE_ADDRESS 268587008UL #define METAL_SIFIVE_PWM0_1_BASE_ADDRESS 268587008UL #define METAL_SIFIVE_PWM0_10025000_SIZE 4096UL #define METAL_SIFIVE_PWM0_1_SIZE 4096UL /* Из pwm@10035000 */ #define METAL_SIFIVE_PWM0_10035000_BASE_ADDRESS 268652544UL #define METAL_SIFIVE_PWM0_2_BASE_ADDRESS 268652544UL #define METAL_SIFIVE_PWM0_10035000_SIZE 4096UL #define METAL_SIFIVE_PWM0_2_SIZE 4096UL #define METAL_SIFIVE_PWM0 #define METAL_SIFIVE_PWM0_PWMCFG 0UL #define METAL_SIFIVE_PWM0_PWMCOUNT 8UL #define METAL_SIFIVE_PWM0_PWMS 16UL #define METAL_SIFIVE_PWM0_PWMCMP0 32UL #define METAL_SIFIVE_PWM0_PWMCMP1 36UL #define METAL_SIFIVE_PWM0_PWMCMP2 40UL #define METAL_SIFIVE_PWM0_PWMCMP3 44UL
Забавный факт: PWM0_0, PWM0_1 и PWM0_2 - это имена, которые библиотека присвоила PWM0, PWM1 и PWM2 соответственно.
Если вы обратитесь к таблицам 88 и 89 в руководстве FE310, то увидите, что это базовые адреса ШИМ и смещения регистров. Вот они, для вашего удобства:
![Базовые адреса ШИМ и смещения регистров конфигурации (Изображение из руководства пользователя FE310-G002, воспроизведено с разрешения компании SiFive, Inc.)](/EDI/20_01_25_2/1737325222-1077/tutorial/1372/objects/5/files/04-11.jpg)
Рис. 4.11. Базовые адреса ШИМ и смещения регистров конфигурации (Изображение из руководства пользователя FE310-G002, воспроизведено с разрешения компании SiFive, Inc.)
Управление яркостью светодиодов
Пришло время для другого проекта.
В этой демонстрации будут использоваться те же входные переключатели, что и в демонстрации GPIO, для управления яркостью светодиода с помощью ШИМ. Теперь мы не сможем управлять яркостью встроенного светодиода, потому что он подключен к GPIO0_5, а этот вывод не поддерживает ШИМ в качестве IOF. Однако мы будем использовать бортовой светодиод для чего-то другого.
Из-за этого ограничения мы будем использовать ШИМ1_1 для управления внешним светодиодом с активным высоким уровнем. Помните, что этот выход ШИМ является IOF GPIO0_19.
Вот принципиальная схема:
Кнопка 0 уменьшит яркость на ступень, а кнопка 1 увеличит ее на ступень. Внешний светодиод имеет 11 уровней яркости, увеличивающихся с шагом в 10%, поэтому яркость будет увеличиваться от 0% до 100%.
Это контакты ввода/вывода, которые мы будем использовать для подключения кнопок и внешнего светодиода: