#include "main.h"
/* ============================================================
* KONSTANTA
* ============================================================ */
#define EMERGENCY_THRESHOLD_MS 500 /* Batas waktu transisi darurat (ms) */
#define BLINK_INTERVAL_MS 100 /* Interval kedip LED mode darurat (ms) */
/* ============================================================
* VARIABEL GLOBAL
* ============================================================ */
/* --- Deteksi transisi IR --- */
uint8_t ir_last = 1; /* State IR sebelumnya (1 = tidak mendeteksi) */
uint32_t ir_not_detect_time = 0; /* Timestamp saat IR mulai tidak mendeteksi */
/* --- Mode darurat --- */
uint8_t emergency_mode = 0; /* Flag mode darurat */
uint32_t blink_last_time = 0; /* Timestamp kedip terakhir */
uint8_t blink_state = 0; /* State kedip saat ini (0/1) */
/* --- Debounce switch --- */
uint8_t switch_last = 0; /* State switch sebelumnya */
/* ============================================================
* DEKLARASI FUNGSI
* ============================================================ */
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void all_outputs_off(void);
static void handle_emergency(void);
static void handle_normal(uint8_t ir_now);
/* ============================================================
* MAIN
* ============================================================ */
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
while (1)
{
uint8_t switch_now = HAL_GPIO_ReadPin(BUTTON_REVERSE_GPIO_Port,
BUTTON_REVERSE_Pin);
uint8_t ir_now = HAL_GPIO_ReadPin(IR_SENSOR_GPIO_Port,
IR_SENSOR_Pin);
/* --------------------------------------------------
* RESET MODE DARURAT via Switch
* Tekan switch (rising edge) untuk keluar dari darurat
* -------------------------------------------------- */
if (switch_now == GPIO_PIN_SET && switch_last == GPIO_PIN_RESET)
{
if (emergency_mode)
{
emergency_mode = 0;
all_outputs_off();
}
}
switch_last = switch_now;
/* --------------------------------------------------
* DETEKSI TRANSISI IR: tidak mendeteksi → mendeteksi
* ir_last == 1 (SET) = sebelumnya tidak mendeteksi
* ir_now == 0 (RESET) = sekarang mendeteksi
* -------------------------------------------------- */
if (ir_last == GPIO_PIN_SET && ir_now == GPIO_PIN_RESET)
{
uint32_t elapsed = HAL_GetTick() - ir_not_detect_time;
if (elapsed < EMERGENCY_THRESHOLD_MS)
{
/* Transisi terjadi < 500ms → aktifkan mode darurat */
emergency_mode = 0; /* reset dulu agar blink_state fresh */
blink_state = 0;
blink_last_time = HAL_GetTick();
emergency_mode = 1;
}
}
/* --------------------------------------------------
* DETEKSI TRANSISI IR: mendeteksi → tidak mendeteksi
* Catat timestamp awal kondisi "tidak mendeteksi"
* -------------------------------------------------- */
if (ir_last == GPIO_PIN_RESET && ir_now == GPIO_PIN_SET)
{
ir_not_detect_time = HAL_GetTick();
}
ir_last = ir_now;
/* --------------------------------------------------
* EKSEKUSI OUTPUT berdasarkan mode
* -------------------------------------------------- */
if (emergency_mode)
{
handle_emergency();
}
else
{
handle_normal(switch_now);
}
HAL_Delay(10); /* Loop setiap 10ms, cukup responsif */
}
}
/* ============================================================
* FUNGSI: Matikan semua output
* ============================================================ */
static void all_outputs_off(void)
{
HAL_GPIO_WritePin(GPIOB,
LED_GREEN_Pin | LED_RED_Pin |
LED_BLUE_Pin | BUZZER_Pin,
GPIO_PIN_RESET);
}
/* ============================================================
* FUNGSI: Handle mode darurat
* LED Merah & Biru berkedip bergantian, Buzzer terus menyala
* ============================================================ */
static void handle_emergency(void)
{
uint32_t now = HAL_GetTick();
if (now - blink_last_time >= BLINK_INTERVAL_MS)
{
blink_last_time = now;
blink_state = !blink_state;
if (blink_state)
{
/* Fase 1: LED Merah ON, LED Biru OFF */
HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(LED_BLUE_GPIO_Port, LED_BLUE_Pin, GPIO_PIN_RESET);
}
else
{
/* Fase 2: LED Merah OFF, LED Biru ON */
HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED_BLUE_GPIO_Port, LED_BLUE_Pin, GPIO_PIN_SET);
}
/* Buzzer selalu ON (nada tinggi terus-menerus) */
HAL_GPIO_WritePin(BUZZER_GPIO_Port, BUZZER_Pin, GPIO_PIN_SET);
/* Pastikan LED Hijau mati */
HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_RESET);
}
}
/* ============================================================
* FUNGSI: Handle mode normal (logika parkir mundur biasa)
* ============================================================ */
static void handle_normal(uint8_t switch_state)
{
if (switch_state == GPIO_PIN_RESET)
{
/* Switch tidak aktif → semua output mati */
all_outputs_off();
}
else
{
/* Switch aktif → baca kondisi IR */
uint8_t ir_now = HAL_GPIO_ReadPin(IR_SENSOR_GPIO_Port, IR_SENSOR_Pin);
if (ir_now == GPIO_PIN_RESET)
{
/* IR mendeteksi objek → LED Merah + Buzzer ON */
HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(BUZZER_GPIO_Port, BUZZER_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED_BLUE_GPIO_Port, LED_BLUE_Pin, GPIO_PIN_RESET);
}
else
{
/* IR tidak mendeteksi → aman, LED Hijau ON */
HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(BUZZER_GPIO_Port, BUZZER_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED_BLUE_GPIO_Port, LED_BLUE_Pin, GPIO_PIN_RESET);
}
}
}
/* ============================================================
* KONFIGURASI CLOCK
* ============================================================ */
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK |
RCC_CLOCKTYPE_SYSCLK |
RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
/* ============================================================
* INISIALISASI GPIO
* ============================================================ */
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/* --- INPUT: PA0 (Switch), PA1 (IR Sensor) --- */
GPIO_InitStruct.Pin = BUTTON_REVERSE_Pin | IR_SENSOR_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* --- OUTPUT: PB0 (LED Green), PB1 (LED Red),
PB2 (Buzzer), PB3 (LED Blue) --- */
GPIO_InitStruct.Pin = LED_GREEN_Pin | LED_RED_Pin |
BUZZER_Pin | LED_BLUE_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Pastikan semua output mati di awal */
HAL_GPIO_WritePin(GPIOB,
LED_GREEN_Pin | LED_RED_Pin |
BUZZER_Pin | LED_BLUE_Pin,
GPIO_PIN_RESET);
}
/* ============================================================
* ERROR HANDLER
* ============================================================ */
void Error_Handler(void)
{
__disable_irq();
while (1) {}
}
b. main.h
#ifndef __MAIN_H
#define __MAIN_H
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32c0xx_hal.h"
void Error_Handler(void);
/* ====== PIN INPUT ====== */
#define BUTTON_REVERSE_Pin GPIO_PIN_0
#define BUTTON_REVERSE_GPIO_Port GPIOA
#define IR_SENSOR_Pin GPIO_PIN_1
#define IR_SENSOR_GPIO_Port GPIOA
/* ====== PIN OUTPUT ====== */
#define LED_GREEN_Pin GPIO_PIN_0
#define LED_GREEN_GPIO_Port GPIOB
#define LED_RED_Pin GPIO_PIN_1
#define LED_RED_GPIO_Port GPIOB
#define BUZZER_Pin GPIO_PIN_2
#define BUZZER_GPIO_Port GPIOB
#define LED_BLUE_Pin GPIO_PIN_3
#define LED_BLUE_GPIO_Port GPIOB
#ifdef __cplusplus
}
#endif
#endif /* __MAIN_H */
Tidak ada komentar:
Posting Komentar