Mikrokontroler STM32 diprogram menggunakan software STM32CubeIDE. Langkah awal dimulai dengan membuat project baru sesuai tipe STM32 yang digunakan pada rangkaian. Setelah itu, dilakukan pengaturan pin pada menu Pinout, di mana pin yang terhubung ke sensor LM35 diset sebagai input analog (ADC), sedangkan pin yang terhubung ke driver motor (L298) untuk kipas diset sebagai output PWM.
Ketika sensor LM35 mendeteksi suhu di bawah 30°C, STM32 memberikan sinyal PWM dengan duty cycle rendah ke driver motor, sehingga kipas berputar dengan kecepatan rendah. Kondisi ini menunjukkan bahwa ruangan masih cukup sejuk sehingga kipas hanya bekerja secara ringan.
Seiring meningkatnya suhu di atas 30°C, STM32 akan menaikkan nilai duty cycle PWM secara bertahap. Hal ini menyebabkan kecepatan kipas meningkat secara linear mengikuti kenaikan suhu. Dengan cara ini, sistem tidak langsung mengubah kecepatan secara drastis, tetapi menyesuaikan secara halus sesuai kondisi suhu ruangan.
Namun, ketika suhu mencapai 40°C, sistem akan mematikan kipas sepenuhnya. STM32 menghentikan sinyal PWM yang diberikan ke driver motor, sehingga kipas berhenti berputar. Kondisi ini merupakan bagian dari logika kontrol yang telah dirancang dalam program.
Dengan cara ini, STM32CubeIDE digunakan untuk merancang dan menulis program pengendalian suhu, sedangkan Proteus digunakan untuk mensimulasikan dan mengamati kinerja rangkaian secara keseluruhan.
#include "main.h"
/* ================= DEFINE ================= */
#define TEMP_START 30.0f
#define TEMP_OFF 40.0f
#define PWM_MAX 65535U
#define PWM_LOW 13107U // 20%
/* ================= HANDLE ================= */
ADC_HandleTypeDef hadc1;
TIM_HandleTypeDef htim1;
/* ================= VAR ================= */
uint32_t adcValue = 0;
float voltage = 0.0f;
float temperature = 0.0f;
uint8_t system_on = 1;
/* ================= PROTOTYPE ================= */
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
static void MX_TIM1_Init(void);
/* ================= MAIN ================= */
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC1_Init();
MX_TIM1_Init();
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2 | GPIO_PIN_3, GPIO_PIN_RESET);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 0);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
while (1)
{
/* ===== BACA ADC ===== */
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
adcValue = HAL_ADC_GetValue(&hadc1);
/* ===== KONVERSI SUHU ===== */
voltage = (adcValue / 4095.0f) * 3.3f;
temperature = voltage * 100.0f;
/* ===== LIMIT SUHU (ANTI ERROR) ===== */
if (temperature < 0) temperature = 0;
if (temperature > 100) temperature = 100;
/* ===== LOGIKA KIPAS ===== */
if (system_on)
{
/* >= 40°C → MATI */
if (temperature >= TEMP_OFF)
{
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 0);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
}
/* 30–40°C → NAIK LINEAR */
else if (temperature >= TEMP_START)
{
float duty = (temperature - TEMP_START) / (TEMP_OFF - TEMP_START);
/* PWM DIBALIK */
float pwm_val = PWM_MAX - (PWM_LOW + duty * (PWM_MAX - PWM_LOW));
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, (uint32_t)pwm_val);
}
/* < 30°C → PELAN */
else
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
/* PWM DIBALIK */
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, PWM_MAX - PWM_LOW);
}
}
else
{
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 0);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
}
HAL_Delay(200);
}
}
/* ================= CLOCK ================= */
void SystemClock_Config(void)
{
RCC_OscInitTypeDef osc = {0};
RCC_ClkInitTypeDef clk = {0};
osc.OscillatorType = RCC_OSCILLATORTYPE_HSI;
osc.HSIState = RCC_HSI_ON;
osc.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
osc.PLL.PLLState = RCC_PLL_NONE;
HAL_RCC_OscConfig(&osc);
clk.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK;
clk.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
clk.AHBCLKDivider = RCC_SYSCLK_DIV1;
clk.APB1CLKDivider = RCC_HCLK_DIV1;
clk.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&clk, FLASH_LATENCY_0);
}
/* ================= ADC ================= */
static void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
__HAL_RCC_ADC1_CLK_ENABLE();
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
HAL_ADC_Init(&hadc1);
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}
/* ================= PWM ================= */
static void MX_TIM1_Init(void)
{
TIM_OC_InitTypeDef sConfigOC = {0};
__HAL_RCC_TIM1_CLK_ENABLE();
htim1.Instance = TIM1;
htim1.Init.Prescaler = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 65535;
HAL_TIM_PWM_Init(&htim1);
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);
}
/* ================= GPIO ================= */
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
/* IN1 & IN2 */
GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* PWM PA8 */
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
/* ================= ERROR ================= */
void Error_Handler(void)
{
while (1);
}
Komentar
Posting Komentar