Selasa, 30 April 2019

TP 2 M2 Praktikum Mikroprosesor Mikrokontroler 2025

 




1. Prosedur
[Kembali]

- Rangkaian


    Rangkaian ini merupakan sistem otomatis berbasis mikrokontroler STM32F103C8T6 yang menggunakan sensor cahaya LDR untuk mengendalikan buzzer dan motor DC. LDR dan resistor 10kΩ membentuk pembagi tegangan yang terhubung ke pin ADC mikrokontroler (PA1) untuk mendeteksi intensitas cahaya di lingkungan. Jika cahaya terdeteksi redup atau gelap, mikrokontroler akan mengaktifkan buzzer melalui pin PA5 dan mengaktifkan motor DC dengan memberi sinyal ke basis transistor BD139 melalui pin PA6. Transistor ini berfungsi sebagai saklar elektronik untuk mengalirkan arus ke motor dari sumber 5V. Sebuah dioda disematkan sejajar dengan motor untuk melindungi rangkaian dari lonjakan tegangan balik yang ditimbulkan oleh induktansi motor saat dimatikan. Rangkaian ini menunjukkan aplikasi kontrol otomatis berbasis cahaya dengan output suara dan gerak mekanik.

    Rangkaian ini juga merupakan penerapan dari  interrupt eksternal agar mikrokontroler  dimana bisa merespons perubahan kondisi cahaya atau masukan tombol secara efisien tanpa harus terus memantau input. Penggunaan EXTI pada pin seperti PA0 (untuk tombol) memungkinkan sistem segera melakukan aksi saat pemicu tertentu terjadi, lalu memproses pembacaan ADC untuk menentukan apakah buzzer dan motor perlu diaktifkan.

2. Hardware dan Diagram Blok [Kembali]

STM32F103C8T6 (U1) sebagai Mikrokontroler utama yang mengontrol seluruh sistem, termasuk pembacaan sensor dan pengaktifan aktuator seperti buzzer dan motor.


- Buzzer berfungsi sebagai output suara. Saat kondisi tertentu terpenuhi (misalnya cahaya terlalu redup atau terlalu terang), buzzer akan aktif dan mengeluarkan bunyi sebagai peringatan atau notifikasi.





 
- LED merah digunakan sebagai indikator visual yang menyala ketika menerima sinyal dari mikrokontroler. 


- Resistor dipasang seri dengan LED untuk membatasi arus dan mencegah kerusakan. Koneksi daya menggunakan pin VCC (3.3V)


Push Button berfungsi sebagai Saklar manual untuk memberikan input digital ke mikrokontroler, biasanya digunakan sebagai pemicu melalui interrupt eksternal.


 - Motor DC sebagai Aktuator mekanik yang dikendalikan oleh transistor untuk bergerak saat kondisi tertentu terpenuhi.



Q1 (BD139) Transistor NPN yang berfungsi sebagai saklar elektronik untuk mengendalikan arus ke motor.


D1 (Dioda Flyback) Dioda pelindung dari tegangan balik motor DC agar tidak merusak transistor saat motor dimatikan.



3. Rangkaian Simulasi dan Prinsip Kerja [Kembali]

- Rangkaian 



- Prinsip kerja

    Rangkaian ini merupakan sistem kendali berbasis mikrokontroler STM32F103C8T6 yang memanfaatkan sensor LDR untuk mendeteksi intensitas cahaya dan menghasilkan sinyal analog yang dibaca melalui ADC. Nilai tersebut dijadikan acuan dalam bentuk persentase (threshold) untuk mengatur kecepatan motor DC menggunakan PWM serta mengaktifkan buzzer dalam kondisi tertentu. Berdasarkan flowchart, sistem akan mulai dengan inisialisasi semua pin yang terhubung ke LDR, buzzer, tombol, dan motor. Setelah membaca nilai sensor, sistem menentukan zona terang (kurang dari 33%, antara 33–66%, dan lebih dari 66%) dan memberikan respon berupa pengaturan kecepatan motor melalui PWM serta status buzzer. Jika intensitas cahaya tinggi (threshold > 66%), maka kondisi tombol akan diperiksa melalui interrupt eksternal. Bila tombol ditekan, buzzer diaktifkan dan motor tetap berjalan pada kecepatan maksimum, namun jika tidak, hanya motor yang aktif. Sistem terus bekerja dalam loop untuk merespons perubahan cahaya dan input tombol secara dinamis.

4. Flowchart dan Listing Program [Kembali]

Flowchart : 



Listing Program :

#include "main.h"

 

ADC_HandleTypeDef hadc1;

TIM_HandleTypeDef htim1;

TIM_HandleTypeDef htim2;

 

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_ADC1_Init(void);

static void MX_TIM1_Init(void);

static void MX_TIM2_Init(void);

 

int main(void)

{

  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();

  MX_ADC1_Init();

  MX_TIM1_Init();

  MX_TIM2_Init();

 

  HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); // Motor PWM

  HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3); // Buzzer PWM

  HAL_ADC_Start(&hadc1);

 

  uint8_t buzzer_enabled = 1;

  uint32_t last_buzzer_change = 0;

  uint8_t buzzer_freq_index = 0;

 

  const uint32_t buzzer_periods[] = {143999, 71999, 47999}; // Frekuensi berbeda

 

  // Threshold (dari rendah → sedang → tinggi)

  const uint16_t THRESH_LOW = 1500;

  const uint16_t THRESH_MID = 3000;

while (1)

{

HAL_ADC_Start(&hadc1);

HAL_ADC_PollForConversion(&hadc1, 10);

uint32_t adc_val = HAL_ADC_GetValue(&hadc1);

// --- Motor Control ---

if (adc_val < THRESH_LOW)

{

__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 200); // Lambat

}

else if (adc_val < THRESH_MID)

{

__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 600); // Sedang

}

else

{

__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 1000); // Cepat

}

// --- Buzzer Logic ---

if (adc_val < THRESH_LOW && buzzer_enabled)

{

// Ubah frekuensi buzzer setiap 500ms

if (HAL_GetTick() - last_buzzer_change >= 500)

{

last_buzzer_change = HAL_GetTick();

buzzer_freq_index = (buzzer_freq_index + 1) % 3;

uint32_t period = buzzer_periods[buzzer_freq_index];

__HAL_TIM_SET_AUTORELOAD(&htim2, period);

__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, period / 2); // 50% duty

}

}

else

{

}

__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, 0); // Matikan buzzer

// --- Button Logic (PB0 ditekan = nonaktifkan buzzer) ---

if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_SET)

{

buzzer_enabled = 0;

__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, 0); // Paksa matikan

buzzer

}

HAL_Delay(10);

}

}

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();

}

}

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;

sConfig.Rank = ADC_REGULAR_RANK_1;

sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;

if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

{

Error_Handler();

}

}

static void MX_TIM1_Init(void)

{

TIM_MasterConfigTypeDef sMasterConfig = {0};

TIM_OC_InitTypeDef sConfigOC = {0};

TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

htim1.Instance = TIM1;

htim1.Init.Prescaler = 0;

htim1.Init.CounterMode = TIM_COUNTERMODE_UP;

htim1.Init.Period = 65535;

htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

htim1.Init.RepetitionCounter = 0;

htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)

{

Error_Handler();

}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) !=

HAL_OK)

{

Error_Handler();

}

sConfigOC.OCMode = TIM_OCMODE_PWM1;

sConfigOC.Pulse = 0;

sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;

sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;

sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;

if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) !=

HAL_OK)

{

Error_Handler();

}

sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;

sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;

sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;

sBreakDeadTimeConfig.DeadTime = 0;

sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;

sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;

sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;

if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) !=

HAL_OK)

{

Error_Handler();

}

HAL_TIM_MspPostInit(&htim1);

}

static void MX_TIM2_Init(void)

{

TIM_MasterConfigTypeDef sMasterConfig = {0};

TIM_OC_InitTypeDef sConfigOC = {0};

htim2.Instance = TIM2;

htim2.Init.Prescaler = 0;

htim2.Init.CounterMode = TIM_COUNTERMODE_UP;

htim2.Init.Period = 65535;

htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)

{

Error_Handler();

}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) !=

HAL_OK)

{

Error_Handler();

}

sConfigOC.OCMode = TIM_OCMODE_PWM1;

sConfigOC.Pulse = 0;

sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) !=

HAL_OK)

{

Error_Handler();

}

HAL_TIM_MspPostInit(&htim2);

}

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();

/*Configure GPIO pin : PB0 */

GPIO_InitStruct.Pin = GPIO_PIN_0;

GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

GPIO_InitStruct.Pull = GPIO_PULLUP;

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 /* USE_FULL_ASSERT */


5. Video Demo [Kembali]




6. Kondisi [Kembali]

Kondisi 5
Buatlah rangkaian seperti gambar  pada percobaan 3, jika nilai potensiometer dibawah threshold 1500 maka motor DC berputar dengan duty cycle 20%  dan buzzer berbunyi dengan frekuensi sedang; jika nilai diatas threshold 3000 maka motor DC berputar dengan duty cycle 100% dan buzzer berbunyi dengan frekuensi rendah. 


7. Video Simulasi [Kembali]




8. Download File[Kembali]

File HTML [disini]
Rangkaian [disini]
Listing Program [disini]
Video [disini]
Datasheet STM32F103C8 [disini]

Datasheet  LDR [disini]

Datasheet Transistor BD139 [disini]

0 comments:

Posting Komentar