#include <Arduino.h>
// Параметры ШИМ
#define PWM_FREQUENCY 1000 // Частота ШИМ 1 кГц
#define PWM_MAX_VALUE 1000 // Максимальное значение ШИМ (100%)
#define PWM_RESOLUTION 10 // Разрешение ШИМ (10 бит = 0-1023)
// Пины для ШИМ (используем пины с поддержкой ШИМ на STM32)
const int pwmPins[] = {PA0, PA1, PA2, PA3}; // 4 канала ШИМ
const int ledPins[] = {PB0, PB1, PB2, PB3}; // Светодиоды для визуализации
int pwmValues[4] = {0, 0, 0, 0}; // Текущие значения ШИМ
int direction[4] = {1, 1, 1, 1}; // Направление изменения яркости
// Функция для настройки ШИМ
void setupPWM() {
// Настройка пинов ШИМ как выходов
for (int i = 0; i < 4; i++) {
pinMode(pwmPins[i], OUTPUT);
analogWriteResolution(PWM_RESOLUTION);
analogWriteFrequency(PWM_FREQUENCY);
analogWrite(pwmPins[i], 0); // Начальное значение 0%
}
// Настройка светодиодов как выходов
for (int i = 0; i < 4; i++) {
pinMode(ledPins[i], OUTPUT);
digitalWrite(ledPins[i], LOW);
}
// Настройка встроенного светодиода
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
}
// Функция для демонстрации различных режимов ШИМ
void demoPWM() {
static unsigned long lastUpdate = 0;
static int demoPhase = 0;
unsigned long currentTime = millis();
if (currentTime - lastUpdate >= 50) { // Обновление каждые 50 мс
lastUpdate = currentTime;
switch(demoPhase) {
case 0: // Плавное увеличение яркости всех светодиодов
for (int i = 0; i < 4; i++) {
pwmValues[i] += 10;
if (pwmValues[i] > PWM_MAX_VALUE) {
pwmValues[i] = PWM_MAX_VALUE;
demoPhase = 1;
}
analogWrite(pwmPins[i], pwmValues[i]);
digitalWrite(ledPins[i], pwmValues[i] > 0 ? HIGH : LOW);
}
break;
case 1: // Плавное уменьшение яркости
for (int i = 0; i < 4; i++) {
pwmValues[i] -= 10;
if (pwmValues[i] < 0) {
pwmValues[i] = 0;
demoPhase = 2;
}
analogWrite(pwmPins[i], pwmValues[i]);
digitalWrite(ledPins[i], pwmValues[i] > 0 ? HIGH : LOW);
}
break;
case 2: // Бегущий огонь с ШИМ
static int runningLED = 0;
for (int i = 0; i < 4; i++) {
if (i == runningLED) {
pwmValues[i] = PWM_MAX_VALUE;
} else {
pwmValues[i] = pwmValues[i] > 0 ? pwmValues[i] - 100 : 0;
}
analogWrite(pwmPins[i], pwmValues[i]);
digitalWrite(ledPins[i], pwmValues[i] > 0 ? HIGH : LOW);
}
runningLED = (runningLED + 1) % 4;
demoPhase = 3;
break;
case 3: // Разные уровни яркости
analogWrite(pwmPins[0], PWM_MAX_VALUE * 0.25); // 25%
analogWrite(pwmPins[1], PWM_MAX_VALUE * 0.50); // 50%
analogWrite(pwmPins[2], PWM_MAX_VALUE * 0.75); // 75%
analogWrite(pwmPins[3], PWM_MAX_VALUE); // 100%
for (int i = 0; i < 4; i++) {
digitalWrite(ledPins[i], analogRead(pwmPins[i]) > 0 ? HIGH : LOW);
}
demoPhase = 4;
break;
case 4: // Мигание с разной скважностью
static bool pulseState = false;
for (int i = 0; i < 4; i++) {
if (pulseState) {
analogWrite(pwmPins[i], PWM_MAX_VALUE / (i + 1));
} else {
analogWrite(pwmPins[i], 0);
}
digitalWrite(ledPins[i], analogRead(pwmPins[i]) > 0 ? HIGH : LOW);
}
pulseState = !pulseState;
demoPhase = 0;
break;
}
}
}
void setup() {
Serial.begin(115200);
Serial.println("Лабораторная работа №3: Генерация ШИМ");
Serial.println("Демонстрация различных режимов ШИМ");
setupPWM();
Serial.println("Параметры ШИМ:");
Serial.print("Частота: "); Serial.print(PWM_FREQUENCY); Serial.println(" Гц");
Serial.print("Разрешение: "); Serial.print(PWM_RESOLUTION); Serial.println(" бит");
Serial.print("Максимальное значение: "); Serial.println(PWM_MAX_VALUE);
}
void loop() {
demoPWM();
// Дополнительно: управление через Serial Monitor
if (Serial.available()) {
char command = Serial.read();
switch(command) {
case '0': analogWrite(pwmPins[0], 0); break;
case '1': analogWrite(pwmPins[0], PWM_MAX_VALUE/4); break;
case '2': analogWrite(pwmPins[0], PWM_MAX_VALUE/2); break;
case '3': analogWrite(pwmPins[0], PWM_MAX_VALUE); break;
case 'r': setupPWM(); break; // Сброс
}
}
}