TP 2 M2 PRAK UP UC
1. Rangkai rangkaian di proteus sesuai dengan kondisi percobaan.
2. Buat program untuk mikrokontroler STM32F103C8 di software STM32 CubeIDE.
3. Compile program dalam format hex, lalu upload ke dalam mikrokontroler.
4. Jalankan simulasi rangkaian pada proteus.
5. Selesai.
Dalam rangkaian ini, mikrokontroler STM32F103C8 berperan sebagai unit kendali utama yang menerima input dari sensor sentuh dan potensiometer, serta mengatur keluaran untuk motor DC dan motor stepper melalui driver ULN2003A.
Ketika sensor sentuh mendeteksi adanya sentuhan, mikrokontroler akan mengaktifkan motor DC sehingga motor tersebut mulai berputar, sementara motor stepper tetap diam karena seluruh sinyal keluarannya disetel ke level LOW. Sebaliknya, jika tidak ada sentuhan yang terdeteksi, motor DC akan dimatikan dan sistem akan mengalihkan kendali ke motor stepper berdasarkan input dari potensiometer. Mikrokontroler membaca nilai analog dari potensiometer melalui pin ADC (PA0) dan menentukan arah rotasi motor stepper. Jika nilai potensiometer berada pada angka tinggi (≥ 2048), maka motor stepper akan bergerak searah jarum jam. Jika nilainya rendah (< 2048), motor akan berputar berlawanan arah jarum jam.
Motor stepper dikendalikan melalui urutan langkah (step sequence) yang telah diprogram untuk masing-masing arah putaran. Seluruh sistem beroperasi secara real-time dengan membaca input dan mengatur motor secara terus-menerus dalam loop utama program. Dengan cara ini, sistem menjamin bahwa motor DC dan motor stepper tidak akan aktif secara bersamaan, serta mampu merespons perubahan input dengan cepat dan stabil.
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
// 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
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
/* USER CODE BEGIN PV */
// 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<<0), // IN1
(1<<3), // IN4
(1<<2), // IN3
(1<<1) // IN2
};
uint8_t step_index = 0;
uint32_t last_step_time = 0;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
void RunStepperSmooth(const uint8_t *sequence, uint8_t speed);
void Error_Handler(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* MCU Configuration--------------------------------------------------------*/
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC1_Init();
/* Infinite loop */
while (1)
{
GPIO_PinState touchState = HAL_GPIO_ReadPin(TOUCH_SENSOR_PORT, TOUCH_SENSOR_PIN);
if (touchState == GPIO_PIN_SET)
{
// Sensor disentuh
HAL_GPIO_WritePin(MOTOR_DC_PORT, MOTOR_DC_PIN, GPIO_PIN_SET); // Motor DC ON
HAL_GPIO_WritePin(STEPPER_PORT, IN1_PIN | IN2_PIN | IN3_PIN | IN4_PIN, GPIO_PIN_RESET); // Stepper OFF
}
else
{
// Sensor tidak disentuh
HAL_GPIO_WritePin(MOTOR_DC_PORT, MOTOR_DC_PIN, GPIO_PIN_RESET); // Motor DC OFF
// Baca ADC
HAL_ADC_Start(&hadc1);
if (HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK)
{
uint16_t adc_val = HAL_ADC_GetValue(&hadc1);
if (adc_val >= 2048)
{
RunStepperSmooth(STEP_SEQ_CW, 5); // Searah jarum jam
}
else
{
RunStepperSmooth(STEP_SEQ_CCW, 5); // Berlawanan jarum jam
}
}
HAL_ADC_Stop(&hadc1);
}
HAL_Delay(1); // Delay kecil supaya stabil
}
}
/**
* @brief Stepper motor control
*/
void RunStepperSmooth(const uint8_t *sequence, uint8_t speed)
{
if (HAL_GetTick() - last_step_time >= speed)
{
HAL_GPIO_WritePin(STEPPER_PORT, IN1_PIN, (sequence[step_index] & (1<<0)) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(STEPPER_PORT, IN2_PIN, (sequence[step_index] & (1<<1)) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(STEPPER_PORT, IN3_PIN, (sequence[step_index] & (1<<2)) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(STEPPER_PORT, IN4_PIN, (sequence[step_index] & (1<<3)) ? GPIO_PIN_SET : GPIO_PIN_RESET);
step_index = (step_index + 1) % 4;
last_step_time = HAL_GetTick();
}
}
/**
* @brief System Clock Configuration
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {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();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV2;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief ADC1 Initialization Function
*/
static void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_0; // PA0
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief GPIO Initialization Function
*/
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();
/* Touch Sensor Input */
GPIO_InitStruct.Pin = TOUCH_SENSOR_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(TOUCH_SENSOR_PORT, &GPIO_InitStruct);
/* DC Motor Output */
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);
/* Stepper Motor Output */
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);
}
/**
* @brief Error Handler
*/
void Error_Handler(void)
{
__disable_irq();
while (1)
{
}
}
Komentar
Posting Komentar