LAPORAN AKHIR PERCOBAAN 2
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.
1. Mikrokontroler STM32F103C8

2. Touch Sensor

3. Power Supply
4. Motor DC (Dinamo DC)
5. Motor Stepper
6. ULN2003A
7. Potensiometer
Diagram Blok:
#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 LED_RED_PIN GPIO_PIN_12
#define LED_GREEN_PIN GPIO_PIN_13
#define LED_BLUE_PIN GPIO_PIN_14
#define LED_PORT GPIOB
// Mode Stepper
const uint16_t STEP_SEQ_CW[4] = {0x0100, 0x0200, 0x0400, 0x0800}; // Clockwise
const uint16_t STEP_SEQ_CCW[4] = {0x0800, 0x0400, 0x0200, 0x0100}; // Counter-Clockwise
ADC_HandleTypeDef hadc1;
uint8_t current_mode = 0; // 0=CW, 1=CCW, 2=Oscillate
uint8_t direction = 0; // Untuk mode oscillate
void SystemClock_Config(void);
void MX_GPIO_Init(void);
void MX_ADC1_Init(void);
void RunStepper(const uint16_t *sequence, uint8_t speed);
void Error_Handler(void);
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC1_Init();
while (1) {
// Baca potensiometer untuk pilih mode
HAL_ADC_Start(&hadc1);
if (HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK) {
uint16_t adc_val = HAL_ADC_GetValue(&hadc1);
// Tentukan mode
if (adc_val < 1365) { // Mode 1: CW
current_mode = 0;
HAL_GPIO_WritePin(LED_PORT, LED_RED_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(LED_PORT, LED_GREEN_PIN|LED_BLUE_PIN, GPIO_PIN_RESET);
}
else if (adc_val < 2730) { // Mode 2: CCW
current_mode = 1;
HAL_GPIO_WritePin(LED_PORT, LED_GREEN_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(LED_PORT, LED_RED_PIN|LED_BLUE_PIN, GPIO_PIN_RESET);
}
else { // Mode 3: Oscillate
current_mode = 2;
HAL_GPIO_WritePin(LED_PORT, LED_BLUE_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(LED_PORT, LED_RED_PIN|LED_GREEN_PIN, GPIO_PIN_RESET);
}
}
// Eksekusi mode
switch(current_mode) {
case 0: // CW
RunStepper(STEP_SEQ_CW, 10);
break;
case 1: // CCW
RunStepper(STEP_SEQ_CCW, 10);
break;
case 2: // Oscillate
if(direction == 0) {
RunStepper(STEP_SEQ_CW, 5);
if(STEPPER_PORT->ODR == (STEPPER_PORT->ODR & 0x00FF) | STEP_SEQ_CW[3])
direction = 1;
} else {
RunStepper(STEP_SEQ_CCW, 5);
if(STEPPER_PORT->ODR == (STEPPER_PORT->ODR & 0x00FF) | STEP_SEQ_CCW[3])
direction = 0;
}
break;
}
}
}
void RunStepper(const uint16_t *sequence, uint8_t speed) {
static uint8_t step = 0;
STEPPER_PORT->ODR = (STEPPER_PORT->ODR & 0x00FF) | sequence[step];
step = (step + 1) % 4;
HAL_Delay(speed);
}
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 MX_GPIO_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOB_CLK_ENABLE();
// Konfigurasi LED
GPIO_InitStruct.Pin = LED_RED_PIN | LED_GREEN_PIN | LED_BLUE_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN; // Tambahkan pull-down
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; // High speed untuk stabil
HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct);
// Konfigurasi Stepper
GPIO_InitStruct.Pin = IN1_PIN | IN2_PIN | IN3_PIN | IN4_PIN;
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 Error_Handler(void) {
while(1) {}
}
1.
Analisa bagaimana perbedaan implementasi PWM antara STM32 dan Raspberry Pi Pico
serta dampaknya terhadap kontrol motor dan LED
PWM
pada STM32 diimplementasikan menggunakan timer hardware (seperti TIM1–TIM4)
yang mendukung pengaturan frekuensi dan duty cycle secara presisi. STM32 mampu
menghasilkan sinyal PWM stabil dengan fitur lanjutan seperti complementary
output dan dead time, sehingga kontrol motor menjadi lebih halus dan LED dapat
dikendalikan secara bertingkat. Sebaliknya, Raspberry Pi Pico menggunakan PWM
slice bawaan dengan pengaturan sederhana lewat PWM(freq, duty_u16). Pico cukup
untuk kontrol dasar motor dan LED, tetapi kurang akurat untuk kebutuhan presisi
tinggi. Dampaknya, STM32 lebih ideal untuk aplikasi kontrol motor dan
pencahayaan yang memerlukan kestabilan dan respon cepat.
2.
Analisa bagaimana cara pembacaan nilai sensor analog menggunakan ADC pada STM32
dan Raspberry Pi Pico
STM32
menggunakan ADC 12-bit dengan fitur seperti scan mode, DMA, dan trigger
eksternal. Pembacaan nilai sensor dapat dilakukan secara polling, interrupt,
maupun DMA, sehingga efisien untuk banyak channel. Pada Raspberry Pi Pico,
pembacaan ADC dilakukan melalui fungsi adc.read_u16() dengan resolusi 12-bit
yang di-upscale ke 16-bit. Namun, Pico tidak mendukung DMA atau trigger
eksternal secara default. Maka, pembacaan sensor analog di STM32 lebih
fleksibel dan cocok untuk aplikasi yang membutuhkan sampling cepat dan
simultan.
3.
Analisa bagaimana penggunaan interrupt eksternal dalam mendeteksi input dari
sensor atau tombol pada STM32 dan Raspberry Pi Pico
STM32
menggunakan EXTI (External Interrupt) yang mendukung konfigurasi tepi sinyal
(rising/falling), prioritas interrupt, dan integrasi dengan sistem NVIC.
Deteksi input dari sensor atau tombol menjadi cepat dan akurat. Sementara itu,
Raspberry Pi Pico menggunakan metode irq() pada objek machine.Pin untuk
mendeteksi tepi naik atau turun, namun tidak mendukung prioritas atau sistem
interrupt kompleks. Hasilnya, STM32 lebih unggul untuk aplikasi real-time dan
multi-interrupt, sedangkan Pico cocok untuk deteksi sederhana.
4.
Analisa bagaimana cara kerja fungsi HAL_GetTick() pada STM32 dan
utime.ticks_ms() pada Raspberry Pi Pico dalam menghitung waktu sejak sistem
dinyalakan
Fungsi
HAL_GetTick() pada STM32 menghitung waktu dalam milidetik sejak sistem menyala
menggunakan interrupt dari timer SysTick yang aktif setiap 1 ms. Sedangkan
utime.ticks_ms() pada Raspberry Pi Pico membaca nilai waktu dari counter
internal sejak booting. Keduanya memberikan waktu dalam satuan ms, namun STM32
memungkinkan pengaturan presisi lebih tinggi melalui pengaturan SysTick dan
juga mendukung interrupt. Pico cukup akurat untuk aplikasi sederhana, tapi
STM32 lebih fleksibel untuk sistem waktu presisi tinggi.
5.
Analisa bagaimana perbedaan konfigurasi dan kontrol pin PWM serta pemanfaatan
timer internal pada STM32 dan Raspberry Pi Pico dalam menghasilkan sinyal
gelombang persegi
Komentar
Posting Komentar