MODUL 1
GENERAL INPUT DAN OUTPUT
Development Board STM32: 1 buah (Bisa menggunakan STM32F103C8T6 "Blue Pill" atau Nucleo-G474RE sesuai spesifikasi lab).
ST-Link V2 / Programmer: 1 buah (Jika menggunakan Blue Pill. Untuk board Nucleo, ST-Link sudah terintegrasi).

Kabel Jumper (Male-to-Male, Male-to-Female): Secukupnya.
Breadboard / Project Board: 1 buah.
LED RGB (Common Cathode/Anode): 1 buah (Bisa diganti dengan 3 LED terpisah: Merah, Hijau, Biru).
Resistor: 3 buah
Push Button / Toggle Switch: 1 buah.
Active Buzzer (3.3V - 5V): 1 buah.
Modul Sensor Infrared (IR) Obstacle: 1 buah.
Modul Sensor Sentuh (Touch Sensor TTP223): 1 buah.
1 Mikrokontroler STM32 dan STM32CubeIDE
STM32 adalah keluarga mikrokontroler 32-bit buatan STMicroelectronics. Mikrokontroler ini dilengkapi dengan berbagai periferal internal seperti antarmuka komunikasi (UART, SPI, I2C), konverter analog-ke-digital (ADC), dan pengatur waktu (timer). Untuk memprogram STM32, digunakan Integrated Development Environment (IDE) bernama STM32CubeIDE. Platform ini memiliki fitur Device Configuration Tool yang memudahkan inisialisasi pin dan periferal secara grafis, lalu secara otomatis menghasilkan kerangka kode bahasa C berbasis Hardware Abstraction Layer (HAL) library.
2 General Purpose Input/Output (GPIO)
GPIO adalah pin antarmuka generik pada mikrokontroler yang perilakunya (sebagai input atau output) dapat dikontrol melalui perangkat lunak.
Mode Output: Pin dikonfigurasi untuk mengeluarkan tegangan. Pada STM32, mode Push-Pull secara aktif mendorong pin ke kondisi High (3.3V) atau menariknya ke kondisi Low (0V). Digunakan untuk menyalakan LED atau menggerakkan buzzer.
Mode Input: Pin dikonfigurasi untuk membaca status tegangan dari luar. Pin input rentan terhadap noise (mengambang/ floating), sehingga sering dikonfigurasi dengan resistor internal Pull-Up (menjaga status default selalu High) atau Pull-Down (menjaga status default selalu Low).
3 Active High dan Active Low Dalam sistem digital, logika aktuasi terbagi menjadi dua:
Active High: Perangkat akan aktif (menyala/mendeteksi) ketika diberikan logika 1 (Tegangan High). Contoh: Modul Touch Sensor TTP223 sering kali berlogika Active High (mengirimkan logika 1 saat disentuh).
Active Low: Perangkat akan aktif ketika ditarik ke logika 0 (Tegangan Low / Ground). Contoh: Modul sensor Infrared (IR) Obstacle umumnya mengirimkan logika 0 saat mendeteksi rintangan.
4 Bouncing pada Saklar Mekanis
Ketika saklar mekanis (seperti push button atau toggle switch) ditekan atau dilepas, kontak logam di dalamnya tidak menempel secara instan. Kontak tersebut akan memantul (bounce) selama beberapa milidetik, menghasilkan lonjakan sinyal 1 dan 0 yang tidak stabil. Mikrokontroler yang sangat cepat dapat membaca pantulan ini sebagai tekanan tombol berkali-kali. Oleh karena itu, diperlukan teknik debouncing (baik melalui delay pada perangkat lunak maupun penambahan kapasitor pada perangkat keras) agar pembacaan menjadi stabil.
#include "main.h"
uint8_t system_enable = 1; uint8_t touch_last = 0;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
int main(void)
{
HAL_Init(); SystemClock_Config(); MX_GPIO_Init();
while (1)
{
uint8_t touch_now = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1);
if (touch_now == GPIO_PIN_SET && touch_last == GPIO_PIN_RESET)
{
system_enable = !system_enable; HAL_Delay(200);
}
touch_last = touch_now;
if (system_enable)
{
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_SET)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
}
}
else
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
}
}
}
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; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
HAL_RCC_GPIOD_CLK_ENABLE();
HAL_RCC_GPIOA_CLK_ENABLE();
HAL_RCC_GPIOB_CLK_ENABLE();
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0 | GPIO_PIN_1, GPIO_PIN_RESET);
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLDOWN; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1; 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);
}
void Error_Handler(void)
{
disable_irq(); while (1)
{
}
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{
}
#include "main.h"
void SystemClock_Config(void); static void MX_GPIO_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config(); MX_GPIO_Init();
while (1)
{
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);
}
else
{
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);
}
else
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
}
}
HAL_Delay(50);
}
}
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();
}
}
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
HAL_RCC_GPIOA_CLK_ENABLE();
HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLDOWN; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2; 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);
}
void Error_Handler(void)
{
disable_irq(); while (1)
{
}
}
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
HAL_RCC_GPIOA_CLK_ENABLE();
HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLDOWN; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2; 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);
}
void Error_Handler(void)
{
disable_irq(); while (1)
{
}
}
#ifndef MAIN_H #define MAIN_H
#ifdef cplusplus extern "C" { #endif
#include "stm32c0xx_hal.h" void Error_Handler(void); #define BUTTON_REVERSE_Pin
#define BUTTON_REVERSE_GPIO_Port GPIOA
#define IR_SENSOR_Pin #define IR_SENSOR_GPIO_Port
#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
#ifdef cplusplus
}
#endif
#endif
C. Alarm Perimeter Pintu
Rangkaian
#include "main.h"
uint8_t system_enable = 1; uint8_t touch_last = 0;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
int main(void)
{
HAL_Init(); SystemClock_Config(); MX_GPIO_Init();
while (1)
{
uint8_t touch_now = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1);
if (touch_now == GPIO_PIN_SET && touch_last == GPIO_PIN_RESET)
{
system_enable = !system_enable; HAL_Delay(200);
}
touch_last = touch_now;
if (system_enable)
{
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_SET)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
}
}
else
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
}
}
}
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; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
HAL_RCC_GPIOD_CLK_ENABLE();
HAL_RCC_GPIOA_CLK_ENABLE();
HAL_RCC_GPIOB_CLK_ENABLE();
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0 | GPIO_PIN_1, GPIO_PIN_RESET);
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLDOWN; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1; 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);
}
void Error_Handler(void)
{
disable_irq(); while (1)
{
}
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{
}
#endif
D. Sistem Kontrol Otomatis Tangki Minyak
Rangkaian
Flowchart
#include "main.h"
void SystemClock_Config(void); static void MX_GPIO_Init(void);
int main(void)
{
HAL_Init(); SystemClock_Config(); MX_GPIO_Init();
while (1)
{
GPIO_PinState flame_state; GPIO_PinState float_state;
flame_state = HAL_GPIO_ReadPin(FLAME_PORT, FLAME_PIN); float_state = HAL_GPIO_ReadPin(FLOAT_PORT, FLOAT_PIN);
/* ===== FLAME SENSOR ===== */
if (flame_state == GPIO_PIN_SET)
{
/* Api terdeteksi */
HAL_GPIO_WritePin(LED_PORT, LED_PIN, GPIO_PIN_SET); HAL_GPIO_WritePin(BUZZER_PORT, BUZZER_PIN, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(LED_PORT, LED_PIN, GPIO_PIN_RESET); HAL_GPIO_WritePin(BUZZER_PORT, BUZZER_PIN, GPIO_PIN_RESET);
}
/* ===== RELAY / POMPA ===== */
if ((flame_state == GPIO_PIN_SET) || (float_state == GPIO_PIN_SET))
{
/* Api ATAU tangki penuh → pompa MATI */ HAL_GPIO_WritePin(RELAY_PORT, RELAY_PIN, GPIO_PIN_RESET);
}
else
{
/* Aman & tangki belum penuh → pompa HIDUP */ HAL_GPIO_WritePin(RELAY_PORT, RELAY_PIN, GPIO_PIN_SET);
}
HAL_Delay(100);
}
}
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
HAL_RCC_GPIOA_CLK_ENABLE();
/* INPUT */
GPIO_InitStruct.Pin = FLAME_PIN | FLOAT_PIN; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLDOWN; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* OUTPUT */
GPIO_InitStruct.Pin = LED_PIN | BUZZER_PIN | RELAY_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Relay default ON */
HAL_GPIO_WritePin(RELAY_PORT, RELAY_PIN, GPIO_PIN_SET);
}
void SystemClock_Config(void)
{
/* Clock default CubeIDE */
}
void Error_Handler(void)
{
while (1) {}
}
Tidak ada komentar:
Posting Komentar