#include "stm32c0xx.h"
// === Макросы для пинов ===
#define LED_PIN GPIO_PIN_1
#define TEMP_SENSOR_PIN GPIO_PIN_0
// === Глобальные переменные ===
volatile uint8_t system_armed = 0; // Состояние: на охране / не на охране
volatile uint8_t fire_detected = 0; // Обнаружен ли пожар
volatile char rx_buffer[64];
volatile uint8_t rx_index = 0;
// === Прототипы функций ===
void init_uart(void);
void init_adc(void);
void init_timer(void);
void SysTick_Delay(uint32_t ms);
uint16_t read_temperature_sensor(void);
// === Прерывание от USART2 (UART RX) ===
void USART2_IRQHandler(void) {
if ((USART2->ISR & USART_ISR_RXNE_RXFNE) != 0) { // Обновлённое имя RXNE
char ch = USART2->RDR;
if (ch == '\n' || ch == '\r') {
rx_buffer[rx_index] = '\0';
rx_index = 0;
if (strcmp((char*)rx_buffer, "set") == 0) {
if (!fire_detected) {
system_armed = 1;
GPIOA->BSRR = LED_PIN;
USART2->TDR = 'O'; while (!(USART2->ISR & USART_ISR_TXE_TXFNF)); // TXE обновлён
USART2->TDR = 'K'; while (!(USART2->ISR & USART_ISR_TXE_TXFNF));
USART2->TDR = '\r'; while (!(USART2->ISR & USART_ISR_TXE_TXFNF));
} else {
const char *msg = "Ошибка взятия\r\n";
for (int i = 0; msg[i]; i++) {
USART2->TDR = msg[i];
while (!(USART2->ISR & USART_ISR_TXE_TXFNF));
}
}
} else if (strcmp((char*)rx_buffer, "reset") == 0) {
system_armed = 0;
fire_detected = 0;
GPIOA->BRR = LED_PIN;
const char *msg = "Снято с охраны\r\n";
for (int i = 0; msg[i]; i++) {
USART2->TDR = msg[i];
while (!(USART2->ISR & USART_ISR_TXE_TXFNF));
}
}
} else {
rx_buffer[rx_index++] = ch;
}
}
}
// === Прерывание от TIM1 (мигание светодиода при пожаре) ===
void TIM1_BRK_UP_TRG_COM_IRQHandler(void) {
static uint8_t led_state = 0;
if ((TIM1->SR & TIM_SR_UIF) != 0) {
TIM1->SR &= ~TIM_SR_UIF;
if (fire_detected) {
if (led_state) {
GPIOA->BRR = LED_PIN;
} else {
GPIOA->BSRR = LED_PIN;
}
led_state ^= 1;
}
}
}
// === Инициализация UART (USART2) ===
void init_uart() {
RCC->IOPENR |= RCC_IOPENR_GPIOAEN;
RCC->APBENR1 |= RCC_APBENR1_USART2EN;
// PA2 — TX, PA3 — RX
GPIOA->MODER &= ~(GPIO_MODER_MODE2 | GPIO_MODER_MODE3);
GPIOA->MODER |= (GPIO_MODER_MODE2_1 | GPIO_MODER_MODE3_1); // Alternate function
GPIOA->AFR[0] |= (1 << (2 * 4)) | (1 << (3 * 4)); // AF1
USART2->CR1 = 0;
USART2->BRR = SystemCoreClock / 19200;
USART2->CR1 |= USART_CR1_RE | USART_CR1_TE | USART_CR1_RXNEIE_RXFNEIE; // Исправлено
USART2->CR1 |= USART_CR1_UE;
NVIC_EnableIRQ(USART2_IRQn);
}
// === Инициализация ADC для датчика температуры ===
void init_adc() {
RCC->APBENR2 |= RCC_APBENR2_ADCEN;
RCC->IOPENR |= RCC_IOPENR_GPIOAEN;
// PA0 — аналоговый вход
GPIOA->MODER &= ~GPIO_MODER_MODE0;
GPIOA->MODER |= GPIO_MODER_MODE0_0; // Аналоговый режим
ADC1->CFGR1 &= ~ADC_CFGR1_CONT;
ADC1->CHSELR = ADC_CHSELR_CHSEL0;
ADC1->CR |= ADC_CR_ADEN;
while (!(ADC1->ISR & ADC_ISR_ADRDY));
}
// === Чтение значения с датчика температуры ===
uint16_t read_temperature_sensor() {
ADC1->CR |= ADC_CR_ADSTART;
while (!(ADC1->ISR & ADC_ISR_EOC));
return ADC1->DR;
}
// === Инициализация SysTick для задержки ===
void SysTick_Init(void) {
SysTick->CTRL = 0;
SysTick->LOAD = 0xFFFFFF;
SysTick->VAL = 0;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
}
// === Функция задержки в миллисекундах ===
void SysTick_Delay(uint32_t ms) {
SysTick->LOAD = (SystemCoreClock / 1000) * ms - 1;
SysTick->VAL = 0;
while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);
}
// === Инициализация таймера TIM1 (для мигания) ===
void init_timer() {
RCC->APBENR2 |= RCC_APBENR2_TIM1EN;
TIM1->PSC = SystemCoreClock / 1000 - 1; // 1 мс
TIM1->ARR = 500; // 500 мс
TIM1->DIER |= TIM_DIER_UIE;
TIM1->CR1 |= TIM_CR1_CEN;
NVIC_EnableIRQ(TIM1_BRK_UP_TRG_COM_IRQn);
}
// === Основной цикл программы ===
int main(void) {
SystemInit();
SysTick_Init();
// Инициализация периферии
init_uart();
init_adc();
init_timer();
// Настройка светодиода
RCC->IOPENR |= RCC_IOPENR_GPIOAEN;
GPIOA->MODER &= ~GPIO_MODER_MODE1;
GPIOA->MODER |= GPIO_MODER_MODE1_0; // Выход
while (1) {
uint16_t temp_value = read_temperature_sensor();
if (temp_value > 3000) { // Пороговое значение
fire_detected = 1;
if (system_armed) {
const char *msg = "Пожар\r\n";
for (int i = 0; msg[i]; i++) {
USART2->TDR = msg[i];
while (!(USART2->ISR & USART_ISR_TXE_TXFNF));
}
}
} else {
fire_detected = 0;
}
if (!system_armed) {
GPIOA->BRR = LED_PIN;
} else if (system_armed && !fire_detected) {
GPIOA->BSRR = LED_PIN;
}
SysTick_Delay(100); // Задержка 100 мс
}
}