FPGA. Модуль PWM
Поуправляв включением и выключением светодиодов по UART, я решил поуправлять изменением яркости свечения светодиодов с помощью широтно-импульсной модуляции (ШИМ) или по-английски PWM (Pulse Width Modulation). Для этого я написал на Verilog модуль 8-битного ШИМ, который добавил в схему slave-модуля интерфейса SPI.
Модуль широтно-импульсной модуляции (ШИМ)
Модуль широтно-импульсной модуляции тактируется импульсами, с некоторой частотой подаваемыми на вход clkIN. Счётчик импульсов counter с каждым импульсом увеличивает своё значение по переднему фронту импульса. Значение счётчика сравнивается со значением value. Если значение счётчика меньше или равно value, вывод pwmOUT устанавливается в логическую 1, и наоборот.
Поскольку разрядность счётчика в модуле равна 8 бит, то максимальное значение (МАХ) равно 255. При значениях value = 0 или value = MAX, вывод pwmOUT всегда либо равен 0, либо 1.
Исходный текст модуля (скачать):
module PWM(
input wire nResetIN,
input wire clkIN,
input wire [7:0] valueIN,
output reg pwmOUT
);
reg [7:0] counter = 8'h00;
always @ (posedge clkIN)
if (~nResetIN) begin
counter <= 8'h00;
pwmOUT <= 1'b0;
end
else begin
counter <= counter + 1'b1;
pwmOUT <= (counter > valueIN) ? 1'b0 : 1'b1;
end
endmodule
Блок-схема для приёма данных от микроконтроллера по интерфейсу SPI получилась следующей (скачать BDF):
Подключение к Olimexino-STM32
Для того, чтобы управлять яркость свечения светодиода с помощью потенциометра, я подключил к FPGA по интерфейсу SPI плату Olimexino-STM32, к выводу D0 которой подключил потенциометр 10K. Схема подключения:
Микроконтроллер Olimexino-STM32 я запрограммировал нижеприведённым скетчем (скачать):
/**
* Тестовый скетч подключения к Olimexino-STM32 FPGA по интерфейсу SPI.
* Изменение яркости свечения светодиода с помощью потенциометра,
* подключенного к выводу D0
*
*/
HardwareSPI spi(1);
#define NSS1 10
const int analogInputPin = 0;
void setup()
{
// Declare analogInputPin as INPUT_ANALOG:
pinMode(analogInputPin, INPUT_ANALOG);
spi.begin(SPI_18MHZ, MSBFIRST, SPI_MODE_0);
pinMode(NSS1, OUTPUT);
digitalWrite(NSS1, LOW);
}
void loop()
{
int value = analogRead(analogInputPin);
byte pwm = map(value, 0, 4095, 0, 255);
spi.transfer(pwm);
delay(5);
}
Автор: Андрей Шаройко <vanyamboe@gmail.com>