- Prosedur
-
Inisialisasi Sistem:
-
STM32F103C8T6 melakukan inisialisasi semua pin GPIO yang terhubung ke stepper motor, motor DC, potensiometer (via ADC), dan touch sensor.
-
Clock sistem dikonfigurasi menggunakan internal oscillator HSI.
-
-
Konfigurasi ADC:
-
ADC1 dikonfigurasi untuk membaca nilai analog dari potensiometer.
-
Channel ADC yang digunakan adalah
ADC_CHANNEL_0
.
-
-
Konfigurasi Interrupt:
-
Touch sensor dikonfigurasi pada pin
PB0
sebagai input dengan interrupt eksternal (EXTI0
) yang aktif pada perubahan naik dan turun (rising & falling). -
Handler
EXTI0_IRQHandler
akan memanggil fungsi callbackHAL_GPIO_EXTI_Callback()
saat interrupt terjadi.
-
-
Loop Utama Program:
-
Program utama berjalan dalam loop tak hingga (
while(1)
). -
Jika touch sensor tidak aktif (tidak disentuh), sistem akan membaca nilai potensiometer menggunakan ADC.
-
-
Pengaturan Arah Motor Stepper:
-
Jika nilai ADC < 2048 → motor stepper berputar searah jarum jam (CW).
-
Jika nilai ADC ≥ 2048 → motor stepper berputar berlawanan arah jarum jam (CCW).
-
Motor stepper dijalankan menggunakan fungsi
RunStepper()
dengan kecepatan tertentu.
-
-
Respon terhadap Sentuhan (Interrupt):
-
Saat touch sensor disentuh:
-
Interrupt aktif dan masuk ke callback
HAL_GPIO_EXTI_Callback()
. -
Motor DC (pada pin
PB7
) dinyalakan (GPIO_PIN_SET
). -
Semua output stepper motor dimatikan untuk menghentikan pergerakannya.
-
-
Saat touch sensor dilepas:
-
Motor DC dimatikan (
GPIO_PIN_RESET
).
-
-
-
Fungsi
RunStepper()
:-
Fungsi ini mengatur logika langkah (step) pada stepper motor sesuai urutan CW atau CCW.
-
Mengatur sinyal pada pin
PB8–PB11
(IN1–IN4) dan memberikan delay sesuai kecepatan yang ditentukan.
-
-
Error Handler:
-
Jika terjadi kesalahan saat inisialisasi periferal (ADC, GPIO, dll.), program masuk ke loop
while(1)
dalamError_Handler()
.
-
Dengan prosedur ini, sistem mampu bekerja secara otomatis mengendalikan motor stepper berdasarkan nilai potensiometer, dan memprioritaskan kontrol ke motor DC saat sensor disentuh, dengan mekanisme interrupt yang efisien.
Rangkaian ini bekerja dengan prinsip utama pemilihan dan pengendalian dua jenis motor—motor DC dan motor stepper—berdasarkan masukan dari sensor sentuh dan potensiometer. Saat sistem pertama kali dijalankan, mikrokontroler STM32 akan melakukan inisialisasi terhadap berbagai periferal seperti HAL, clock sistem, GPIO, dan ADC. Setelah inisialisasi selesai, program masuk ke dalam loop utama yang akan terus berjalan selama sistem aktif.
Di dalam loop utama, sistem akan mengecek kondisi dari touch sensor. Jika sensor disentuh, maka terjadi interupsi yang mengaktifkan motor DC dan secara bersamaan mematikan motor stepper untuk mencegah keduanya berjalan secara bersamaan. Hal ini bertujuan agar hanya satu motor yang aktif pada satu waktu berdasarkan input yang diterima.
Namun, jika sensor tidak disentuh, maka sistem akan membaca nilai analog dari potensiometer menggunakan ADC (Analog to Digital Converter). Nilai ini kemudian digunakan untuk menentukan arah putaran motor stepper. Jika nilai ADC kurang dari 2048, maka motor stepper akan berputar searah jarum jam. Sebaliknya, jika nilai ADC lebih besar atau sama dengan 2048, motor stepper akan berputar berlawanan arah jarum jam. Setiap langkah putaran motor diberikan delay selama 1ms untuk mengatur kecepatan rotasi dan menjaga kestabilan.
#include "stm32f1xx_hal.h"
// Konfigurasi Hardware
#define STEPPER_PORT GPIOB
#define IN1_PIN GPIO_PIN_8
#define IN2_PIN GPIO_PIN_9
#define IN3_PIN GPIO_PIN_10
#define IN4_PIN GPIO_PIN_11
#define TOUCH_SENSOR_PORT GPIOB
#define TOUCH_SENSOR_PIN GPIO_PIN_0
#define MOTOR_DC_PORT GPIOB
#define MOTOR_DC_PIN GPIO_PIN_7
// Mode Stepper
const uint8_t STEP_SEQ_CW[4] = {
(1<<0), // IN1
(1<<1), // IN2
(1<<2), // IN3
(1<<3) // IN4
};
const uint8_t STEP_SEQ_CCW[4] = {
(1<<3), // IN4
(1<<2), // IN3
(1<<1), // IN2
(1<<0) // IN1
};
ADC_HandleTypeDef hadc1;
uint8_t current_mode = 0; // 0=CW, 1=CCW
volatile uint8_t touch_state = 0;
void SystemClock_Config(void);
void MX_GPIO_Init(void);
void MX_ADC1_Init(void);
void RunStepper(const uint8_t *sequence, uint8_t speed);
void Error_Handler(void);
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC1_Init();
while (1) {
// Saat tidak disentuh, jalankan stepper seperti biasa
if (HAL_GPIO_ReadPin(TOUCH_SENSOR_PORT, TOUCH_SENSOR_PIN) ==
GPIO_PIN_RESET) {
HAL_ADC_Start(&hadc1);
if (HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK) {
uint16_t adc_val = HAL_ADC_GetValue(&hadc1);
current_mode = (adc_val < 2048) ? 0 : 1; // 0 = CW, 1 =
CCW
}
if (current_mode == 0) {
RunStepper(STEP_SEQ_CW, 5);
} else {
RunStepper(STEP_SEQ_CCW, 5);
}
}
HAL_Delay(1);
}
}
void RunStepper(const uint8_t *sequence, uint8_t speed) {
static uint8_t step = 0;
HAL_GPIO_WritePin(STEPPER_PORT, IN1_PIN, (sequence[step]
& (1<<0)) ?
GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(STEPPER_PORT, IN2_PIN, (sequence[step]
& (1<<1)) ?
GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(STEPPER_PORT, IN3_PIN, (sequence[step]
& (1<<2)) ?
GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(STEPPER_PORT, IN4_PIN, (sequence[step]
& (1<<3)) ?
GPIO_PIN_SET : GPIO_PIN_RESET);
step = (step + 1) % 4;
HAL_Delay(speed);
}
void MX_GPIO_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_AFIO_REMAP_SWJ_NOJTAG(); // Optional: disable JTAG to
free PB3-PB4 if
needed
// Konfigurasi Touch Sensor sebagai input dengan EXTI
(interrupt)
GPIO_InitStruct.Pin = TOUCH_SENSOR_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(TOUCH_SENSOR_PORT, &GPIO_InitStruct);
// Aktifkan NVIC untuk EXTI0
HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI0_IRQn);
// Konfigurasi Motor DC (PB7)
GPIO_InitStruct.Pin = MOTOR_DC_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(MOTOR_DC_PORT, &GPIO_InitStruct);
// Konfigurasi Stepper Motor (PB8-PB11)
GPIO_InitStruct.Pin = IN1_PIN | IN2_PIN | IN3_PIN | IN4_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(STEPPER_PORT, &GPIO_InitStruct);
}
void MX_ADC1_Init(void) {
ADC_ChannelConfTypeDef sConfig = {0};
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
if (HAL_ADC_Init(&hadc1) != HAL_OK) {
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) !=
HAL_OK) {
Error_Handler();
}
}
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_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();
}
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
if (GPIO_Pin == TOUCH_SENSOR_PIN) {
GPIO_PinState pinState = HAL_GPIO_ReadPin(TOUCH_SENSOR_PORT,
TOUCH_SENSOR_PIN);
if (pinState == GPIO_PIN_SET) {
// Touch sensor ditekan - nyalakan motor DC, matikan stepper
HAL_GPIO_WritePin(MOTOR_DC_PORT, MOTOR_DC_PIN,
GPIO_PIN_SET);
HAL_GPIO_WritePin(STEPPER_PORT,
IN1_PIN|IN2_PIN|IN3_PIN|IN4_PIN,
GPIO_PIN_RESET);
} else {
// Touch sensor dilepas - matikan motor DC
HAL_GPIO_WritePin(MOTOR_DC_PORT, MOTOR_DC_PIN,
GPIO_PIN_RESET);
}
}
}
// IRQ Handler untuk EXTI0
void EXTI0_IRQHandler(void) {
HAL_GPIO_EXTI_IRQHandler(TOUCH_SENSOR_PIN);
}
void Error_Handler(void) {
while(1) {}
}
File HTML [disini]
Listing Program [disini]
Video [disini]
Datasheet STM32F103C8 [disini]
Datasheet Touch Sensor [disini]
Datasheet ULN2003A [disini]
0 comments:
Posting Komentar