/*
Домашнее задание №2. (Светофор на STM32)
Использована версия C031C6, т.к. F103, рекомендуемая преподователем
недоступна на WOKWI*
Другие симуляторы закрыты из-за санкций на текущий момент.
Задание:
Сделать “светофор” на трех светодиодах: красный, желтый, зеленый
-Светофор работает в строгой последовательности цветов сигналов
1. Зеленый сигнал — разрешает движение в данном направлении.
2. Зеленый мигающий сигнал 3 раза — разрешает движение и предупреждает,
что будет смена сигнала.
3. Желтый сигнал — запрещает движение и предупреждает,
что будет красный сигнал.
4. Красный сигнал — запрещает движение в данном направлении
-Добавить кнопку перехода пешехода в светофор
Алгоритм работы:
1. Пешеход нажимает кнопку.
2. Через определенное программно время (например, 5 сек) светофор
для машин переходит в режим мигающий зеленый 3 раза.
3. Красный для перехода пешеходов горит строго определенное время,
сколько бы раз кнопку не нажимали
4. После "зеленого" с установленным временем задержки (5 сек)
происходит разрешение нажатия кнопки (до этого кнопка не реагирует).
*Светофор готов к новому циклу. *
{}Включение светодиода по команде с консоли{*}
-Из заданий 2 и 4, рассмотренных на семинаре, синтезируем код,с помощью которого можно будет управлять состоянием светодиода.
Необходимые компоненты: STM32, резистор, светодиод, макетная плата.
-Соберите цепи из указанных компонентов и напишите данный код.
Запустите serial monitor.
Введите с клавиатуры «1», светодиод загорится зеленый.
При вводе «0» зеленый светодиод потухнет.
Можно сделать для разных светодиодов.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <stm32c0xx_hal.h>
// Конфигурация портов светодиодов
#define LED_RED GPIO_PIN_5
#define LED_YELLOW GPIO_PIN_6
#define LED_GREEN GPIO_PIN_7
#define BUTTON GPIO_PIN_13
// Тайм-ауты для светодиодов
#define TIMEOUT_RED 3000
#define TIMEOUT_YEL 1690
#define TIMEOUT_GREEN 2000
#define TIMEOUT_FLASH_GREEN 500
// Глобальные переменные
static GPIO_TypeDef *ledPorts[3] = {GPIOB, GPIOB, GPIOB};
static uint16_t ledPins[3] = {LED_RED, LED_YELLOW, LED_GREEN};
volatile static bool buttonPressed = false;
void systickDelayMS(uint32_t ms)
{
uint32_t start = HAL_GetTick();
while (HAL_GetTick() - start < ms);
}
void setup()
{
GPIO_InitTypeDef gpioInitStruct;
// Инициализация тайм-аутов
systickDelayMS(2000);
// Инициализация портов GPIO
for (uint8_t i = 0; i < 3; i++)
{
gpioInitStruct.Pin = ledPins[i];
gpioInitStruct.Mode = GPIO_MODE_OUTPUT_PP;
gpioInitStruct.Pull = GPIO_NOPULL;
gpioInitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(ledPorts[i], &gpioInitStruct);
}
// Инициализация всех светодиодов отключенными
HAL_GPIO_WritePin(ledPorts[0], ledPins[0], GPIO_PIN_RESET);
HAL_GPIO_WritePin(ledPorts[1], ledPins[1], GPIO_PIN_RESET);
HAL_GPIO_WritePin(ledPorts[2], ledPins[2], GPIO_PIN_RESET);
// Инициализация кнопки
gpioInitStruct.Pin = BUTTON;
gpioInitStruct.Mode = GPIO_MODE_IT_RISING;
gpioInitStruct.Pull = GPIO_PULLDOWN;
gpioInitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &gpioInitStruct);
// Установка прерывания кнопки
HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(SPI1_IRQn);
}
void GPIOC_IRQHandler(void)
{
if (__HAL_GPIO_EXTI_GET_FLAG(BUTTON) != RESET)
{
__HAL_GPIO_EXTI_CLEAR_FLAG(BUTTON);
buttonPressed = true;
}
}
void loop()
{
// Включить зеленый светодиод
HAL_GPIO_WritePin(ledPorts[2], ledPins[2], GPIO_PIN_SET);
systickDelayMS(TIMEOUT_GREEN);
if(buttonPressed)
{
// Мигать зеленым светодиодом 3 раза
for (int i = 0; i < 3; i++)
{
HAL_GPIO_WritePin(ledPorts[2], ledPins[2], GPIO_PIN_RESET);
systickDelayMS(TIMEOUT_FLASH_GREEN);
HAL_GPIO_WritePin(ledPorts[2], ledPins[2], GPIO_PIN_SET);
systickDelayMS(TIMEOUT_FLASH_GREEN);
buttonPressed = false;
}
}
// Включить желтый светодиод
HAL_GPIO_WritePin(ledPorts[1], ledPins[1], GPIO_PIN_SET);
systickDelayMS(TIMEOUT_YEL);
// Отключить желтый светодиод
HAL_GPIO_WritePin(ledPorts[1], ledPins[1], GPIO_PIN_RESET);
// Включить красный светодиод
HAL_GPIO_WritePin(ledPorts[0], ledPins[0], GPIO_PIN_SET);
systickDelayMS(TIMEOUT_RED);
// Включить желтый светодиод
HAL_GPIO_WritePin(ledPorts[1], ledPins[1], GPIO_PIN_SET);
systickDelayMS(TIMEOUT_YEL);
// Отключить желтый и красный светодиоды
HAL_GPIO_WritePin(ledPorts[1], ledPins[1], GPIO_PIN_RESET);
HAL_GPIO_WritePin(ledPorts[0], ledPins[0], GPIO_PIN_RESET);
}
int main(void)
{
HAL_Init();
SystemCoreClockUpdate();
setup();
while (1)
{
loop();
}
return 0;
}