TP & LA MODUL 3



1. Prosedur [Kembali]

  1. Pahami terlebih dahulu kondisi yang akan digunakan
  2. Persiapkan alat dan bahan
  3. Buat rangkaian sesuai dengan kondisi dan modul
  4. Buka software STM32Cube IDE 
  5. Setelah membuka software, pilih perangkat STMG474RE
  6. Sesuaikan konfigurasi pin sesuai dengan rangkaian modul
  7. Buat kode program untuk mengoperasikan rangkaian tersebut sesuai dengan kondisi 
  8. Konfigurasi kan program dengan software STM32Cube IDE 
  9. Jalankan simulasi rangkaian.  
  10. Proses selesai

2. Hardware dan Diagram Blok [Kembali]

STM32 NUCLEO-G474RE

OLED
LED Red dan Green
Push Button

Buzzer
Beardboard

Diagram Blok

3. Rangkaian Simulasi dan Prinsip Kerja [Kembali]

Prinsip Kerja

Pada rangkaian game Geometry Jump ini digunakan dua buah mikrokontroler STM32 yang berkomunikasi menggunakan protokol I2C dengan konsep master dan slave. STM32 master berfungsi sebagai pengendali utama permainan, sedangkan STM32 slave bertugas menerima data dan mengontrol perangkat output seperti LED dan buzzer. Saat sistem pertama kali dinyalakan, kedua mikrokontroler melakukan inisialisasi pin GPIO, komunikasi I2C, serta perangkat input dan output yang digunakan. OLED pada sisi master digunakan untuk menampilkan tampilan permainan sederhana, sedangkan push button berfungsi sebagai kontrol untuk melakukan aksi lompat pada karakter game. Koneksi SDA dan SCL pada kedua STM32 memungkinkan proses pengiriman data berjalan secara sinkron antara master dan slave. Seluruh rangkaian memperoleh catu daya yang sama sehingga komunikasi dan respon perangkat dapat berjalan stabil selama permainan berlangsung.

Prinsip kerja permainan dimulai ketika push button ditekan untuk memulai game, kemudian master mengirimkan data “game run” ke slave melalui komunikasi I2C. Setelah data diterima, slave menyalakan LED hijau sebagai indikator bahwa permainan sedang aktif, sedangkan LED merah berada dalam kondisi mati. Ketika pemain menekan push button untuk melakukan lompatan, master membaca input tombol lalu mengirimkan data “jump” ke slave. Setelah menerima data tersebut, slave mengaktifkan buzzer sebagai efek suara lompatan sehingga sinkron dengan aksi karakter pada game. Selama permainan berlangsung, master terus memproses logika game seperti pergerakan karakter dan deteksi rintangan yang ditampilkan pada OLED. Komunikasi data antara kedua STM32 berlangsung secara terus-menerus agar kondisi permainan pada master dan indikator pada slave tetap sesuai secara real-time.

Apabila karakter terkena rintangan atau pemain gagal melakukan lompatan dengan tepat, master mendeteksi kondisi game over kemudian mengirimkan data tersebut ke slave melalui jalur I2C. Setelah menerima data game over, slave mematikan LED hijau dan menyalakan LED merah sebagai tanda permainan berakhir, kemudian buzzer juga diaktifkan untuk memberikan notifikasi suara. Jika selama permainan tombol tidak ditekan, maka master akan mengirimkan nilai logika “0” sehingga slave tidak mengaktifkan buzzer dan permainan tetap berjalan normal. Flowchart master menunjukkan bahwa seluruh keputusan utama seperti mulai game, aksi lompat, dan deteksi tabrakan diproses pada sisi master sebelum dikirim ke slave. Sementara itu, flowchart slave hanya berfungsi sebagai penerima data dan pengendali output berdasarkan instruksi dari master. Dengan pembagian tugas tersebut, sistem komunikasi I2C mampu membuat permainan bekerja lebih terstruktur, responsif, dan sinkron antara pengolah data dan perangkat output.

 4. Flowchart dan Listing Program [Kembali]



MAIN.C

#include "main.h" 

#include "ssd1306.h" 

#include <stdio.h> 

 

/* ================= SPI ================= */ 

SPI_HandleTypeDef hspi1; 

 

/* ================= OLED I2C ================= */ 

I2C_HandleTypeDef hi2c1; 

 

/* ================= COMMAND ================= */ 

#define CMD_GAME_RUN     0x01 

#define CMD_GAME_OVER    0x02 

#define CMD_JUMP_SOUND   0x03 

#define CMD_HIT_SOUND    0x04 

 

/* ================= CS PIN ================= */ 

#define CS_PORT GPIOA 

#define CS_PIN  GPIO_PIN_4 

 

/* ================= GAME ================= */ 

int dinoY, velocityY, cactusX; 

uint32_t score, highScore; 

uint8_t isJumping, gameOver; 

 

#define GRAVITY 2 

#define FRAME_DELAY 30 

#define GROUND_Y 48

#define DINO_HEIGHT 10 

char buf[20]; 

/* ================= SEND SPI ================= */ 

void Send_To_Slave(uint8_t cmd) 

HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_RESET); 

HAL_SPI_Transmit(&hspi1, &cmd, 1, 100); 

HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_SET); 

HAL_Delay(1); // penting untuk sync slave 

/* ================= MAIN ================= */ 

int main(void) 

HAL_Init(); 

SystemClock_Config(); 

MX_GPIO_Init(); 

MX_SPI1_Init(); 

MX_I2C1_Init(); 

ssd1306_Init(); 

HAL_GPIO_WritePin(GPIOA, CS_PIN, GPIO_PIN_SET); 

ResetGame(); 

while (1) 
if (!gameOver) 
UpdateGame(); 
DrawGame(); 
Send_To_Slave(CMD_GAME_RUN); 
else 
DrawGameOver(); 
if (score > highScore) 
highScore = score; 
Send_To_Slave(CMD_GAME_OVER); 
if (HAL_GPIO_ReadPin(JUMP_BTN_GPIO_Port, JUMP_BTN_Pin) == 
GPIO_PIN_RESET) 
ResetGame(); 
HAL_Delay(300); 
HAL_Delay(FRAME_DELAY); 
/* ================= GAME LOGIC ================= */
void UpdateGame(void) 
if (HAL_GPIO_ReadPin(JUMP_BTN_GPIO_Port, JUMP_BTN_Pin) == 
GPIO_PIN_RESET && !isJumping) 
velocityY = -12; 
isJumping = 1; 
Send_To_Slave(CMD_JUMP_SOUND); 
dinoY += velocityY; 
velocityY += GRAVITY; 
if (dinoY >= GROUND_Y) 
dinoY = GROUND_Y; 
velocityY = 0; 
isJumping = 0; 
cactusX -= (6 + score / 15); 
if (cactusX < -10) 
cactusX = 128; 
score++; 
if (cactusX < 25 && cactusX > 5 && (dinoY + DINO_HEIGHT) > 48) 
{
gameOver = 1; 
Send_To_Slave(CMD_HIT_SOUND); 
/* ================= DRAW ================= */ 
void DrawGame(void) 
ssd1306_Fill(Black); 
ssd1306_DrawRectangle(10, dinoY, 20, dinoY + DINO_HEIGHT, 
White); 
ssd1306_FillRectangle(cactusX, 48, cactusX + 8, 60, White); 
ssd1306_Line(0, 61, 127, 61, White); 
sprintf(buf, "Sc:%lu", score); 
ssd1306_SetCursor(0, 0); 
ssd1306_WriteString(buf, Font_7x10, White); 
sprintf(buf, "Hsc:%lu", highScore); 
ssd1306_SetCursor(80, 0); 
ssd1306_WriteString(buf, Font_7x10, White); 
ssd1306_UpdateScreen(); 
void DrawGameOver(void) 
ssd1306_Fill(Black);
ssd1306_SetCursor(30, 15); 
ssd1306_WriteString("GAME OVER", Font_7x10, White); 
sprintf(buf, "HighScore:%lu", highScore); 
ssd1306_SetCursor(25, 35); 
ssd1306_WriteString(buf, Font_7x10, White); 
ssd1306_UpdateScreen(); 
/* ================= RESET ================= */ 
void ResetGame(void) 
dinoY = GROUND_Y; 
velocityY = 0; 
cactusX = 128; 
score = 0; 
isJumping = 0; 
gameOver = 0; 
/* ================= SPI INIT ================= */ 
void MX_SPI1_Init(void) 
hspi1.Instance = SPI1; 
hspi1.Init.Mode = SPI_MODE_MASTER; 
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_SOFT; 
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; 
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; 
 
  HAL_SPI_Init(&hspi1); 
 
/* ================= GPIO ================= */ 
void MX_GPIO_Init(void) 
  __HAL_RCC_GPIOA_CLK_ENABLE(); 
 
  GPIO_InitTypeDef GPIO_InitStruct = {0}; 
 
  /* CS */ 
  GPIO_InitStruct.Pin = GPIO_PIN_4; 
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; 
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; 
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 
 
  /* BUTTON */ 
  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); 
}

MAIN.H
#ifndef __MAIN_H 
#define __MAIN_H
#ifdef __cplusplus 
extern "C" { 
#endif 
 
#include "stm32g4xx_hal.h" 
#include "ssd1306.h" 
#include "ssd1306_fonts.h" 
#include <stdio.h> 
 
/* Definisi Pin Hardware */ 
#define JUMP_BTN_Pin GPIO_PIN_0 
#define JUMP_BTN_GPIO_Port GPIOA 
 
/* Konstanta Permainan */ 
#define GROUND_Y 44 
#define DINO_WIDTH 15 
#define DINO_HEIGHT 15 
 
/* Prototipe Fungsi */ 
void SystemClock_Config(void); 
void MX_GPIO_Init(void); 
void MX_I2C1_Init(void); 
void Error_Handler(void); 
 
#ifdef __cplusplus 
#endif 
 
#endif /* __MAIN_H */

PROGRAM SLAVE
#include "main.h" 
/* ================= SPI ================= */ 
SPI_HandleTypeDef hspi1; 
/* ================= COMMAND ================= */ 
#define CMD_GAME_RUN     0x01 
#define CMD_GAME_OVER    0x02 
#define CMD_JUMP_SOUND   0x03 
#define CMD_HIT_SOUND    0x04 
/* ================= PROTOTYPE ================= */ 
void SystemClock_Config(void); 
void MX_GPIO_Init(void); 
void MX_SPI1_Init(void); 
void Send(uint8_t data); 
/* ================= MAIN ================= */ 
int main(void) 
HAL_Init(); 
SystemClock_Config(); 
MX_GPIO_Init(); 
MX_SPI1_Init(); 
while (1) 
Send(CMD_GAME_RUN); 
HAL_Delay(500); 
Send(CMD_JUMP_SOUND); 
HAL_Delay(500); 
Send(CMD_GAME_OVER); 
HAL_Delay(1000); 
/* ================= SEND SPI ================= */ 
void Send(uint8_t data) 
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // CS LOW 
HAL_SPI_Transmit(&hspi1, &data, 1, 100); 
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);   // CS HIGH 
/* ================= SPI INIT ================= */ 
void MX_SPI1_Init(void) 
hspi1.Instance = SPI1; 
hspi1.Init.Mode = SPI_MODE_MASTER; 
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_SOFT; 
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; 
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; 
HAL_SPI_Init(&hspi1); 
/* GPIO CS */ 
void MX_GPIO_Init(void) 
__HAL_RCC_GPIOA_CLK_ENABLE(); 
GPIO_InitTypeDef GPIO_InitStruct = {0}; 
GPIO_InitStruct.Pin = GPIO_PIN_4; 
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; 
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); 
/* CLOCK (simple safe) */ 
void SystemClock_Config(void) {}

5. Video Demo [Kembali]

6. Tugas Pendahuluan [Kembali]

1. Jelaskan apa itu protocol UART, SPI, dan I2C? 

Jawab:
UART merupakan protokol komunikasi serial asynchronous yang digunakan untuk pertukaran data antar perangkat secara serial tanpa menggunakan sinyal clock bersama. Pada komunikasi UART, data dikirim bit demi bit melalui dua jalur utama, yaitu TX (Transmit) untuk mengirim data dan RX (Receive) untuk menerima data. Karena bersifat asynchronous, kedua perangkat harus menggunakan konfigurasi baud rate yang sama agar komunikasi berjalan dengan benar. 

I2C adalah protokol komunikasi serial synchronous yang menggunakan dua jalur komunikasi, yaitu:

  • SDA (Serial Data) untuk jalur data
  • SCL (Serial Clock) untuk jalur clock

Pada sistem I2C terdapat konsep master dan slave. Master bertugas menghasilkan sinyal clock serta mengatur komunikasi, sedangkan slave merespons permintaan dari master berdasarkan alamat (address) yang dimiliki masing-masing perangkat.

SPI adalah protokol komunikasi serial synchronous berkecepatan tinggi yang menggunakan empat jalur utama, yaitu:

  • MOSI (Master Output Slave Input)
  • MISO (Master Input Slave Output)
  • SCLK/SCK (Serial Clock)
  • SS/CS (Slave Select/Chip Select)

Pada SPI, perangkat master menghasilkan sinyal clock dan memilih slave menggunakan pin SS/CS. Data dapat dikirim dan diterima secara bersamaan (full duplex), sehingga komunikasi SPI lebih cepat dibanding UART dan I2C.

2. Bagaimana konfigurasi komunikasi UART pada STM 32 F103C8T6 dan STM NUCLEO G474RE pada hardware dan software? 

Konfigurasi Hardware

Pada komunikasi UART digunakan dua jalur utama, yaitu TX (Transmit) dan RX (Receive). Koneksi dilakukan dengan menghubungkan pin TX mikrokontroler ke RX perangkat lain, dan RX ke TX, serta menyatukan GND kedua perangkat.

Pada STM32F103C8T6 umumnya digunakan:

  • TX : PA9
  • RX : PA10

Sedangkan pada STM32 NUCLEO G474RE dapat menggunakan:

  • TX : PA2
  • RX : PA3

Board NUCLEO juga dapat langsung terhubung ke komputer melalui ST-LINK USB sebagai virtual COM port.

Konfigurasi Software

Konfigurasi UART dilakukan menggunakan STM32CubeMX atau STM32CubeIDE dengan mengaktifkan peripheral USART/UART dan memilih mode asynchronous. Parameter yang diatur meliputi baud rate, data bits, parity, dan stop bit. Setelah konfigurasi selesai, komunikasi data dapat dilakukan menggunakan fungsi HAL UART seperti transmit dan receive.

3. Bagaimana konfigurasi SPI pada STM 32 F103C8T6 dan STM NUCLEO G474RE pada hardware dan software? 

Konfigurasi Hardware

SPI menggunakan empat jalur utama yaitu:

  • MOSI
  • MISO
  • SCK/SCLK
  • SS/CS

Pada STM32F103C8T6, SPI1 biasanya menggunakan:

  • PA7 : MOSI
  • PA6 : MISO
  • PA5 : SCK
  • PA4 : NSS/CS

Koneksi dilakukan antar pin yang sama antara master dan slave serta menghubungkan GND bersama.

Konfigurasi Software

Pada STM32CubeMX/CubeIDE, peripheral SPI diaktifkan lalu dipilih mode master atau slave. Selanjutnya diatur clock polarity (CPOL), clock phase (CPHA), dan baud rate SPI. Setelah generate code, komunikasi data dapat dilakukan menggunakan fungsi HAL SPI transmit dan receive.

4. Bagaimana konfigurasi I2C pada STM 32 F103C8T6 dan STM NUCLEO G474RE pada hardware dan software? 

Konfigurasi Hardware

I2C menggunakan dua jalur komunikasi:

  • SDA (Serial Data)
  • SCL (Serial Clock)

Pada STM32F103C8T6 umumnya digunakan:

  • PB7 : SDA
  • PB6 : SCL

Koneksi dilakukan dengan menghubungkan SDA ke SDA dan SCL ke SCL antar perangkat. Jalur I2C biasanya menggunakan resistor pull-up agar komunikasi stabil.

Konfigurasi Software

Konfigurasi I2C dilakukan melalui STM32CubeMX/CubeIDE dengan mengaktifkan peripheral I2C dan mengatur clock speed serta addressing mode. Setelah konfigurasi selesai, komunikasi data antara master dan slave dapat dilakukan menggunakan fungsi HAL I2C transmit dan receive.

5. Jelaskan perbedaan UART, SPI, dan I2C!

UART merupakan komunikasi asynchronous yang tidak menggunakan sinyal clock. UART hanya membutuhkan dua jalur utama yaitu TX dan RX. Komunikasi UART bersifat point-to-point sehingga hanya dapat menghubungkan dua perangkat secara langsung. UART sederhana dan mudah digunakan, tetapi kecepatannya relatif lebih rendah dan kurang cocok untuk banyak perangkat.

SPI adalah komunikasi synchronous yang menggunakan sinyal clock dari master. SPI membutuhkan empat jalur utama yaitu MOSI, MISO, SCLK, dan SS/CS. SPI memiliki kecepatan transfer paling tinggi dibanding UART dan I2C serta mendukung full duplex communication. Namun SPI membutuhkan lebih banyak pin terutama jika slave bertambah banyak.

I2C juga merupakan komunikasi synchronous, tetapi hanya membutuhkan dua jalur yaitu SDA dan SCL. I2C mendukung banyak perangkat dalam satu bus menggunakan sistem addressing. Jumlah pin lebih hemat dibanding SPI, namun kecepatan transfer data lebih rendah dibanding SPI.

           
        

7. Video Simulasi [Kembali]

8. Download File [Kembali]

Rangkaian dan Listing Project Master Download

Rangkaian dan Listing Project Slave Download

Soal Analisa Download 

Tugas Pendahuluan Download















Komentar

Postingan populer dari blog ini