LAPORAN AKHIR MODUL 3 PERCOBAAN 2
LAPORAN AKHIR MODUL 3 PERCOBAAN 2
1. Prosedur (kembali)
2. Hardware (kembali)
• STM NUCLEO G474RE (x2)
|
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 |
• OLED
• 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.
• 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.
• 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.
• 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.
3. Rangkaian Simulasi dan Prinsip Kerja (kembali)
4. Flowchart dan Listing Program (kembali)
#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
Main.h
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()
{
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 ================= */
{
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)
{
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_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.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)
#define __MAIN_H
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 */
/* ================= 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);
}
}
/* ================= 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
5. Video Demo (kembali)
6. Kondisi (kembali)
7. Video Simulasi (kembali)
8. Download File (kembali)
Komentar
Posting Komentar