TUGAS PENDAHULUAN DAN LA



1. Prosedur [kembali]

    1. Menyiapkan alat dan bahan yang digunakan pada praktikum, seperti STM32 Nucleo G474RE, STM32F103C8T6 (Bluepill), sensor, LED, OLED, breadboard, jumper, dan komponen pendukung lainnya sesuai percobaan.
    2. Membuat project baru pada STM32CubeIDE untuk masing-masing board mikrokontroler yang digunakan sebagai master maupun slave/receiver.
    3. Melakukan konfigurasi peripheral komunikasi pada STM32CubeMX sesuai protokol yang digunakan, yaitu UART, SPI, atau I2C. Konfigurasi meliputi baudrate, mode komunikasi, clock, pin TX/RX, SCK, MISO, MOSI, SDA, dan SCL.
    4. Menghubungkan pin komunikasi antar board sesuai jenis protokol yang digunakan. Pada UART menghubungkan TX dan RX secara silang, pada SPI menghubungkan pin SCK, MOSI, MISO, dan NSS/CS, sedangkan pada I2C menghubungkan jalur SDA dan SCL. Ground kedua board juga disatukan agar komunikasi dapat berjalan dengan baik.
    5. Melakukan generate code dari STM32CubeMX kemudian menambahkan program komunikasi menggunakan library HAL pada file utama (main.c). Program dibuat agar board master dapat mengirim data dan board slave dapat menerima maupun merespon data.
    6. Menghubungkan sensor atau aktuator sesuai rangkaian percobaan, seperti sensor PIR, LDR, LED, OLED, fan, ataupun motor servo untuk menguji komunikasi data antar perangkat.
    7. Meng-compile program dan mengunggah kode ke masing-masing board STM32 menggunakan ST-LINK atau downloader yang sesuai.
    8. Menjalankan sistem dan mengamati proses komunikasi data antar mikrokontroler, kemudian mencatat hasil pengujian apakah data berhasil dikirim dan diterima sesuai fungsi program yang dibuat.

2. Hardware dan Diagram Blok [kembali]

1. STM32F103C8

Microcontroller

ARM Cortex-M3

Operating Voltage

3.3 V

Input Voltage (recommended)

5 V 

Input Voltage (limit)

2 – 3.6 V

Digital I/O Pins

32

PWM Digital I/O Pins

15

Analog Input Pins

10 (dengan resolusi 12-bit ADC)

DC Current per I/O Pin

25 mA

DC Current for 3.3V Pin

150 mA

Flash Memory

64 KB

SRAM

20 KB

EEPROM

Emulasi dalam Flash

 

Clock Speed

72 MHz

 

TM32F103C8 adalah mikrokontroler berbasis ARM Cortex-M3 yang dikembangkan oleh STMicroelectronics. Mikrokontroler ini sering digunakan dalam pengembangan sistem tertanam karena kinerjanya yang baik, konsumsi daya yang rendah, dan kompatibilitas dengan berbagai protokol komunikasi. Pada praktikum ini, kita menggunakan STM32F103C8 yang dapat diprogram menggunakan berbagai metode, termasuk komunikasi serial (USART), SWD (Serial Wire Debug), atau JTAG untuk berhubungan dengan komputer maupun perangkat lain.


2. Mikrokontroler STM32 Nucleo G474RE

 

Microcontroller

STM32G474RE (ARM Cortex-M4F)

Operating Voltage

3.3 V

Input Voltage (recommended)

5 V via USB (ST-LINK) atau 7–12 V via VIN

Input Voltage (limit)

4.5 – 15 V (VIN board Nucleo)

Digital I/O Pins

±51 GPIO pins (tergantung konfigurasi fungsi)

PWM Digital I/O Pins

Hingga 24 channel PWM (advanced, general-purpose, dan high-resolution timers)

Analog Input Pins

Hingga 24 channel ADC (12-bit / 16-bit dengan oversampling)

DC Current per I/O Pin

Maks. 20 mA per pin (disarankan ≤ 8 mA)

DC Current for 3.3V Pin

Hingga ±500 mA (tergantung regulator & sumber daya)

Flash Memory

512 KB internal Flash

SRAM

128 KB SRAM (termasuk CCM RAM)

Clock Speed

Hingga 170 MHz

 

3. PIR Sensor

PIR (Passive Infrared) Sensor digunakan untuk mendeteksi keberadaan atau pergerakan manusia berdasarkan pancaran inframerah dari tubuh. Pada praktikum smart entry indicator, sensor PIR digunakan sebagai input untuk mendeteksi gerakan kemudian mengirimkan data ke mikrokontroler melalui komunikasi UART.

4. Sensor LDR

LDR (Light Dependent Resistor) merupakan sensor cahaya yang nilai resistansinya berubah sesuai intensitas cahaya yang diterima. Sensor ini digunakan pada sistem kontrol greenhouse untuk mendeteksi kondisi terang atau gelap sehingga mikrokontroler dapat mengontrol output tertentu seperti LED atau fan.

5. OLED Display

OLED (Organic Light Emitting Diode) digunakan sebagai media output tampilan visual. Pada praktikum game geometry jump, OLED digunakan untuk menampilkan objek permainan, skor, dan status game. Display ini berkomunikasi menggunakan protokol I2C sehingga hanya membutuhkan dua jalur komunikasi.

6. Push Button

Push button merupakan saklar sederhana yang digunakan sebagai perangkat input digital. Tombol ini digunakan untuk memberikan perintah tertentu pada sistem, seperti menjalankan aksi lompat pada game atau memberikan trigger pada sistem komunikasi.

7. LED

LED (Light Emitting Diode) digunakan sebagai indikator visual output sistem. LED akan menyala atau mati sesuai data yang diterima mikrokontroler sehingga dapat digunakan untuk mengetahui kondisi komunikasi atau status sistem secara langsung.

8. Fan

Fan atau kipas DC digunakan sebagai aktuator output pada sistem greenhouse. Fan akan aktif ketika kondisi tertentu terpenuhi, misalnya saat sensor mendeteksi intensitas cahaya rendah atau kondisi lingkungan tertentu.

9. Sensor IR

Sensor IR (Infrared Sensor) digunakan untuk mendeteksi objek atau kendaraan melalui pantulan cahaya inframerah. Pada sistem parkir otomatis, sensor ini digunakan untuk mendeteksi kendaraan yang masuk atau keluar area parkir.

10. Motor Servo

Motor servo digunakan sebagai aktuator penggerak portal parkir otomatis. Servo dapat bergerak pada sudut tertentu berdasarkan sinyal PWM dari mikrokontroler sehingga cocok digunakan untuk membuka dan menutup palang parkir.

11. Breadboard

Breadboard digunakan sebagai media perakitan rangkaian elektronik tanpa proses solder. Komponen dapat dipasang dan dilepas dengan mudah sehingga memudahkan proses praktikum dan pengujian rangkaian.

12. Kabel Jumper

Kabel jumper digunakan untuk menghubungkan antar komponen pada breadboard maupun antara sensor dengan mikrokontroler. Kabel ini menjadi media penghantar sinyal dan daya pada rangkaian praktikum.

3. Rangkaian Simulasi dan Prinsip Kerja [kembali]

4. Flowchart dan Listing Program [kembali]

Flowchart game



MASTER

Flowchart



main.c

#include "main.h"

#include "stm32g4xx_hal_i2c.h"

/* Private variables ---------------------------------------------------------*/

I2C_HandleTypeDef hi2c1;

#define SSD1306_I2C_PORT hi2c1

/* Variabel Game */

int dinoY = GROUND_Y;

int velocityY = 0;

const int gravity = 2;

uint8_t isJumping = 0;

int cactusX = 128;

uint32_t score = 0;

char scoreBuf[10];

uint8_t gameOver = 0;

uint32_t highScore = 0;


/* Private function prototypes -----------------------------------------------*/

void ResetGame(void);


int main(void)

{

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

  HAL_Init();

  SystemClock_Config();


  /* Initialize all configured peripherals */

  MX_GPIO_Init();

  MX_I2C1_Init();


  /* USER CODE BEGIN 2 */

  ssd1306_Init();

  ssd1306_Fill(Black);

  ssd1306_UpdateScreen();

  /* USER CODE END 2 */


  while (1)

  {

    if (!gameOver)

    {

      /* 1. Input Handling (Pull-up: LOW = Pressed) */

      if (HAL_GPIO_ReadPin(JUMP_BTN_GPIO_Port, JUMP_BTN_Pin) == GPIO_PIN_RESET && !isJumping)

      {

        velocityY = -12;

        isJumping = 1;

      }


      /* 2. Physics Update */

      dinoY += velocityY;

      velocityY += gravity;


      if (dinoY >= GROUND_Y)

      {

        dinoY = GROUND_Y;

        isJumping = 0;

        velocityY = 0;

      }


      /* 3. Obstacle Update */

      cactusX -= 6;

      if (cactusX < -10)

      {

        cactusX = 128;

        score++;

      }


      /* 4. Collision Detection */

      // Hitbox sederhana: Jika kaktus berada di area Dino dan Dino tidak cukup tinggi

      if (cactusX < 25 && cactusX > 5 && (dinoY + DINO_HEIGHT) > 48)

      {

        gameOver = 1;

      }


      /* 5. Rendering */

      ssd1306_Fill(Black);


      // Menggambar Dino (Kotak)

      ssd1306_DrawRectangle(10, dinoY, 10 + DINO_WIDTH, dinoY + DINO_HEIGHT, White);


      // Menggambar Kaktus (Isi penuh)

      ssd1306_FillRectangle(cactusX, 48, cactusX + 8, 60, White);


      // Garis Tanah

      ssd1306_Line(0, 61, 127, 61, White);


      // Menampilkan Score

      sprintf(scoreBuf, "Score: %lu", score);

      ssd1306_SetCursor(0, 0);

      ssd1306_WriteString(scoreBuf, Font_7x10, White);


      ssd1306_UpdateScreen();

    }

    else

    {

        char hsBuf[20];


        ssd1306_Fill(Black);


        ssd1306_SetCursor(35, 25);

        ssd1306_WriteString("GAME OVER", Font_7x10, White);


        ssd1306_SetCursor(20, 10);

        sprintf(hsBuf, "HighScore: %lu", highScore);

        ssd1306_WriteString(hsBuf, Font_7x10, White);


        ssd1306_UpdateScreen();


        // Update high score

        if (score > highScore)

        {

            highScore = score;

        }


        // restart

        if (HAL_GPIO_ReadPin(JUMP_BTN_GPIO_Port, JUMP_BTN_Pin) == GPIO_PIN_RESET)

        {

            ResetGame();

            HAL_Delay(300);

        }

    }


  }

}

void ResetGame(void)

{

  dinoY = GROUND_Y;

  velocityY = 0;

  isJumping = 0;

  cactusX = 128;

  score = 0;

  gameOver = 0;

}

void MX_I2C1_Init(void)

{

  hi2c1.Instance = I2C1;

  hi2c1.Init.Timing = 0x00303D5D;

  hi2c1.Init.OwnAddress1 = 0;

  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;

  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;

  hi2c1.Init.OwnAddress2 = 0;

  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;

  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;


  if (HAL_I2C_Init(&hi2c1) != HAL_OK)

  {

    Error_Handler();

  }

}


void MX_GPIO_Init(void)

{

  GPIO_InitTypeDef GPIO_InitStruct = {0};


  __HAL_RCC_GPIOA_CLK_ENABLE();


  /* Konfigurasi PA0 sebagai Input Pull-up */

  GPIO_InitStruct.Pin = JUMP_BTN_Pin;

  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

  GPIO_InitStruct.Pull = GPIO_PULLUP;

  HAL_GPIO_Init(JUMP_BTN_GPIO_Port, &GPIO_InitStruct);

}


void Error_Handler(void)

{

  __disable_irq();

  while (1) {}

}

void SystemClock_Config(void)

{

  RCC_OscInitTypeDef RCC_OscInitStruct = {0};

  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};


  /** Configure the main internal regulator output voltage

  */

  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);


  /** Initializes the RCC Oscillators

  */

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;

  RCC_OscInitStruct.HSIState = RCC_HSI_ON;

  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;

  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;

  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV4;

  RCC_OscInitStruct.PLL.PLLN = 85;

  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;

  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;

  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;


  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

  {

    Error_Handler();

  }


  /** Initializes the CPU, AHB and APB buses clocks

  */

  RCC_ClkInitStruct.ClockType =

      RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|

      RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;


  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

  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_4) != HAL_OK)

  {

    Error_Handler();

  }

}


SLAVE
Flowchart


main.c
#include "main.h"

#include "stm32g4xx_hal_spi.h"

/* =========================================================
   GLOBAL HANDLE
   ========================================================= */
SPI_HandleTypeDef hspi1;

/* =========================================================
   GLOBAL VARIABLE
   ========================================================= */
static uint8_t rxData;

/* =========================================================
   MAIN
   ========================================================= */
int main(void)
{
    HAL_Init();

    SystemClock_Config();

    MX_GPIO_Init();
    MX_SPI1_Init();

    /* LED awal */
    HAL_GPIO_WritePin(LED_GREEN_GPIO_Port,
                      LED_GREEN_Pin,
                      GPIO_PIN_RESET);

    HAL_GPIO_WritePin(LED_RED_GPIO_Port,
                      LED_RED_Pin,
                      GPIO_PIN_RESET);

    while (1)
    {
        /* =====================================
           TERIMA DATA SPI
           ===================================== */
        HAL_SPI_Receive(&hspi1,
                        &rxData,
                        1,
                        HAL_MAX_DELAY);

        /* =====================================
           PROCESS COMMAND
           ===================================== */
        switch (rxData)
        {
            /* ================================
               GAME RUN
               ================================ */
            case CMD_GAME_RUN:

                HAL_GPIO_WritePin(LED_GREEN_GPIO_Port,
                                  LED_GREEN_Pin,
                                  GPIO_PIN_SET);

                HAL_GPIO_WritePin(LED_RED_GPIO_Port,
                                  LED_RED_Pin,
                                  GPIO_PIN_RESET);

                break;

            /* ================================
               GAME OVER
               ================================ */
            case CMD_GAME_OVER:

                HAL_GPIO_WritePin(LED_GREEN_GPIO_Port,
                                  LED_GREEN_Pin,
                                  GPIO_PIN_RESET);

                HAL_GPIO_WritePin(LED_RED_GPIO_Port,
                                  LED_RED_Pin,
                                  GPIO_PIN_SET);

                break;

            /* ================================
               JUMP SOUND
               ================================ */
            case CMD_JUMP_SOUND:

                Beep_Jump();

                break;

            /* ================================
               HIT SOUND
               ================================ */
            case CMD_HIT_SOUND:

                Beep_Hit();

                break;

            default:
                break;
        }
    }
}

/* =========================================================
   BEEP JUMP
   bib
   ========================================================= */
void Beep_Jump(void)
{
    HAL_GPIO_WritePin(BUZZER_GPIO_Port,
                      BUZZER_Pin,
                      GPIO_PIN_SET);

    HAL_Delay(80);

    HAL_GPIO_WritePin(BUZZER_GPIO_Port,
                      BUZZER_Pin,
                      GPIO_PIN_RESET);
}

/* =========================================================
   BEEP HIT
   bib bib biiiiib
   ========================================================= */
void Beep_Hit(void)
{
    /* bib */
    HAL_GPIO_WritePin(BUZZER_GPIO_Port,
                      BUZZER_Pin,
                      GPIO_PIN_SET);

    HAL_Delay(100);

    HAL_GPIO_WritePin(BUZZER_GPIO_Port,
                      BUZZER_Pin,
                      GPIO_PIN_RESET);

    HAL_Delay(100);

    /* bib */
    HAL_GPIO_WritePin(BUZZER_GPIO_Port,
                      BUZZER_Pin,
                      GPIO_PIN_SET);

    HAL_Delay(100);

    HAL_GPIO_WritePin(BUZZER_GPIO_Port,
                      BUZZER_Pin,
                      GPIO_PIN_RESET);

    HAL_Delay(100);

    /* biiiiib */
    HAL_GPIO_WritePin(BUZZER_GPIO_Port,
                      BUZZER_Pin,
                      GPIO_PIN_SET);

    HAL_Delay(500);

    HAL_GPIO_WritePin(BUZZER_GPIO_Port,
                      BUZZER_Pin,
                      GPIO_PIN_RESET);
}

/* =========================================================
   GPIO INIT
   ========================================================= */
void MX_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    /* =====================================
       CLOCK ENABLE
       ===================================== */
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();

    /* =====================================
       LED + BUZZER OUTPUT
       ===================================== */
    GPIO_InitStruct.Pin =
        LED_GREEN_Pin |
        LED_RED_Pin   |
        BUZZER_Pin;

    GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull  = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

    HAL_GPIO_Init(GPIOB,
                  &GPIO_InitStruct);

    /* =====================================
       SPI1 GPIO
       PA4 = NSS
       PA5 = SCK
       PA6 = MISO
       PA7 = MOSI
       ===================================== */
    GPIO_InitStruct.Pin =
        GPIO_PIN_4 |
        GPIO_PIN_5 |
        GPIO_PIN_6 |
        GPIO_PIN_7;

    GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;

    HAL_GPIO_Init(GPIOA,
                  &GPIO_InitStruct);
}

/* =========================================================
   SPI1 INIT
   ========================================================= */
void MX_SPI1_Init(void)
{
    hspi1.Instance = SPI1;

    hspi1.Init.Mode =
        SPI_MODE_SLAVE;

    hspi1.Init.Direction =
        SPI_DIRECTION_2LINES;

    hspi1.Init.DataSize =
        SPI_DATASIZE_8BIT;

    hspi1.Init.CLKPolarity =
        SPI_POLARITY_LOW;

    hspi1.Init.CLKPhase =
        SPI_PHASE_1EDGE;

    hspi1.Init.NSS =
        SPI_NSS_HARD_INPUT;

    hspi1.Init.FirstBit =
        SPI_FIRSTBIT_MSB;

    hspi1.Init.TIMode =
        SPI_TIMODE_DISABLE;

    hspi1.Init.CRCCalculation =
        SPI_CRCCALCULATION_DISABLE;

    if (HAL_SPI_Init(&hspi1) != HAL_OK)
    {
        Error_Handler();
    }
}

/* =========================================================
   CLOCK CONFIG
   ========================================================= */
void SystemClock_Config(void)
{
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

    HAL_PWREx_ControlVoltageScaling(
        PWR_REGULATOR_VOLTAGE_SCALE1);

    RCC_OscInitStruct.OscillatorType =
        RCC_OSCILLATORTYPE_HSI;

    RCC_OscInitStruct.HSIState =
        RCC_HSI_ON;

    RCC_OscInitStruct.PLL.PLLState =
        RCC_PLL_ON;

    RCC_OscInitStruct.PLL.PLLSource =
        RCC_PLLSOURCE_HSI;

    RCC_OscInitStruct.PLL.PLLM =
        RCC_PLLM_DIV4;

    RCC_OscInitStruct.PLL.PLLN =
        85;

    RCC_OscInitStruct.PLL.PLLR =
        RCC_PLLR_DIV2;

    HAL_RCC_OscConfig(&RCC_OscInitStruct);

    RCC_ClkInitStruct.ClockType =
        RCC_CLOCKTYPE_SYSCLK |
        RCC_CLOCKTYPE_HCLK   |
        RCC_CLOCKTYPE_PCLK1  |
        RCC_CLOCKTYPE_PCLK2;

    RCC_ClkInitStruct.SYSCLKSource =
        RCC_SYSCLKSOURCE_PLLCLK;

    RCC_ClkInitStruct.AHBCLKDivider =
        RCC_SYSCLK_DIV1;

    RCC_ClkInitStruct.APB1CLKDivider =
        RCC_HCLK_DIV1;

    RCC_ClkInitStruct.APB2CLKDivider =
        RCC_HCLK_DIV1;

    HAL_RCC_ClockConfig(
        &RCC_ClkInitStruct,
        FLASH_LATENCY_4
    );
}

/* =========================================================
   ERROR HANDLER
   ========================================================= */
void Error_Handler(void)
{
    __disable_irq();

    while (1)
    {

    }
}

5. Video Demo [kembali]


6. Kondisi [kembali]

Percobaan 2 Game Geomerty Jump (Komunikasi SPI – I2C)

7. Video Simulasi [kembali]

8. Download File [kembali]

  1. Download Tugas Pendahuluan klik disini
  2. Download Datasheet STM32 NUCLEO-G474RE klik disini





Tidak ada komentar:

Posting Komentar

MODUL 4

[KEMBALI KE MENU SEBELUMNYA] DAFTAR ISI 1. Judul 2. Tujuan 3. Alat dan Bahan 4. Dasar Teori 5. Percobaan Percobaan .....