Lisleapex Blog
Published © MIT

A Small Game "Snake" Based on Microcontroller MAX7219

Snake, a classic, nostalgic game, is a must-write program for microcontrollers.

BeginnerWork in progress2 hours89
A Small Game "Snake" Based on Microcontroller MAX7219

Things used in this project

Hardware components

STC89C52RC
×1
MAX7219
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Solder Wire, Lead Free
Solder Wire, Lead Free

Story

Read more

Schematics

snake_8uLlUpuZIs.png

Code

Untitled file

Arduino
Timer 0
#ifndef __TIMER0_H__

#define __TIMER0_H__



void Timer0_Init(void);



#endif

2. 8 independent buttons

#ifndef __KEYSCAN_8_H__

#define __KEYSCAN_8_H__



unsigned char Key(void);

void Key_Tick(void);



#endif

3. 8X8LED dot matrix screen (MAX7219 driver)

#ifndef __MATRIXLED_MAX7219_H__

#define __MATRIXLED_MAX7219_H__



void MAX7219_WriteByte(unsigned char Byte);

void MAX7219_SendData(unsigned char Address,Data);

void MatrixLED_Clear(void);

void MatrixLED_Init(void);

void MatrixLED_MoveLeft(unsigned char *Array,unsigned int Offset);

void MatrixLED_MoveUp(unsigned char *Array,unsigned int Offset);



#endif

4. Main function

/*

by Gan Tengsheng@20241202

Effect view/operation demonstration: You can search "Gan Tengsheng" or "gantengsheng" on B station to view

MCU: STC89C52RC

Crystal oscillator: 12T@12.0000MHz

Peripheral: self-made 8-bit independent button, 8X8LED dot matrix screen (MAX7219 driver)

Principle analysis: https://blog.csdn.net/gantengsheng/article/details/143581157



Operation instructions:



(1) Self-made independent button version



K7 K2 Up: K7

Down: K6

K8 K5 K4 K1 Left: K8

Right: K5

K6 K3 Start/Pause/Continue: K1

Return: K2



(2) Puzhong development board matrix button version



S1 S2 S3 S4 Up: S10

Down: S14

S5 S6 S7 S8 Left: S13

Right: S15

S9 S10 S11 S12 Start/Pause/Continue: S16

Return: S12

S13 S14 S15 S16



*/



#include <REGX52.H> //Header file containing register definitions in the installation directory

#include <STDLIB.H> //Header file containing random function declarations in the installation directory

#include "Timer0.h" //Header file in the project directory

#include "KeyScan_8.h"

#include "MatrixLED_MAX7219.h"



unsigned char KeyNum; //Store the obtained key code value

unsigned char Mode; //Game mode, 0: Display the English name of the game "<<SNAKE>>", 1: Display the English word "DIFFICULTY" for difficulty,

//2: Difficulty selection interface (range is 1~5), 3: Game in progress, 4: Full screen flashing after the game ends,

//5: Display the score in English "SCORE", 6: Circular scrolling display score

unsigned char MoveSnakeFlag; //Snake body movement flag, 1: move, 0: do not move

unsigned char NowDirection=1; //Direction of the snake head movement, 1: right, 2: up, 3: left, 4: down, the default is to move right when the game starts

unsigned char LastDirection=1; //Direction of the last movement of the snake head, 1: right, 2: up, 3: left, 4: down, the default is to move right when the game starts

unsigned char Length=2; //Length of the snake, initial value is 2

unsigned char Head=1; //In the array that saves the data of the entire snake (a total of 64 data), the index of the data corresponding to the snake head (0~63), the initial length of the snake is 2, and only two data are used initially

//(the first and second data of the array), the snake head corresponds to the second data, the index is 1, the range of Head: 0~63

unsigned char GameOverFlag; //Flag of the game ending, 1: game ending, 0: game not ending

unsigned char FlashFlag; //Flashing flag, 1: not displayed, 0: displayed

unsigned char Food; //Save the location of the created food

unsigned char Offset1; //Offset, used to control the scrolling display of English letters to the left (cleared after switching modes)

unsigned char Offset2; //Offset, used to control the scrolling display of numbers up and down (not cleared after switching modes)

unsigned char RollFlag1; //Flag of scrolling display, fast speed, 1: scrolling, 0: not scrolling

unsigned char RollFlag2; //Flag of scrolling display, moderate speed, 1: scrolling, 0: not scrolling

unsigned char RollFlag3; //Flag of scrolling display, slow speed, 1: scrolling, 0: not scrolling

unsigned char RollUpFlag; //Difficulty selection interface, flag of digital scrolling display up, 1: scrolling, 0: not scrolling

unsigned char RollDownFlag; //Difficulty selection interface, the flag for the number to scroll down, 1: scroll, 0: not scroll

unsigned char RollCount; //Count of up and down scrolling

unsigned char ExecuteOnceFlag; //The flag for executing only once in each mode, 1: execute, 0: not execute

unsigned char SnakeMoveSpeed=100; //Snake movement speed, the smaller the value, the faster the speed, the default is 1s after power-on (timer timing 10ms)

unsigned char T0Count0, T0Count1, T0Count2, T0Count3; //Timer counting variable

unsigned char PauseFlag; //Pause flag, 1: pause, 0: not pause



//Use a one-bit array to save the data of which points of the dot matrix screen should be lit, each data is 0 or 1, 0 is not lit, 1 is lit

//When the display needs to be updated, combine these 64 data into 8 bytes, update to the display buffer array, and then write to the MAX7219 register

//It is also OK not to define this middle buffer array, and the data in the display buffer array can be directly updated by AND, OR, shift and other operations

//It can also be defined as a two-dimensional array

//Use idata to modify the array variable because the lower 128 bits of the direct addressing of the STC89C52RC's on-chip RAM are not enough, and the upper 128 bits of indirect addressing are needed

unsigned char idata MiddleBuffer[]={

0,0,0,0,0,0,0,0,

0,1,1,0,0,0,0,0, //The initial position of the snake is in the second column, second row (tail) and the third column, second row (head)

0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,

};



//Data of the snake body, the tens digit (1~8) indicates the column where the snake body is located, and the ones digit (1~8) indicates the row where the snake body is located

//The initial length is 2, the head corresponds to "32" (third column, second row), which is the first data in the array, so the initial value of the snake head Head is 1

//The tail corresponds to "22" (second column, second row), which is the 0th data in the array

unsigned char idata SnakeBody[]={

22,32,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,

};



//Screen display cache

//Requirement: vertical modulus, high bit at the top

unsigned char DisplayBuffer[]={

0x00,0x40,0x40,0x00,0x00,0x00,0x00,0x00,

};



unsigned char idata ScoreShow[]={ //Used to scroll and display the score

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //No display

0x00,0x00,0x00,0x00,0x00,0x00, //After the game, write the ten-digit digital font of the snake's length Length to this line

0x00,0x00,0x00,0x00,0x00,0x00, //After the game, write the one-digit digital font of the snake's length Length to this line

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //No display

};



//Negative code (bright spot is 1), vertical modulus, high bit on top, font size is 6*8

//Modified with code, indicating saving to ROM

unsigned char code Text_SNAKE[]={ //Game name "<<SNAKE>>"

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //No display

0x10,0x28,0x44,0x92,0x28,0x44,0x82,0x00, // <<

0x00,0x62,0x92,0x92,0x92,0x8C, // S

0x00,0xFE,0x20,0x10,0x08,0xFE, // N

0x00,0x3E,0x48,0x88,0x48,0x3E, // A

0x00,0xFE,0x10,0x28,0x44,0x82, // K

0x00,0xFE,0x92,0x92,0x92,0x82, // E

0x00,0x82,0x44,0x28,0x92,0x44,0x28,0x10, // >>

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //No display

};



unsigned char code Text_DIFFICULTY[]={ //English name of difficulty "<<DIFFICULTY>>"

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //No display

0x00,0xFE,0x82,0x82,0x44,0x38, // D

0x00,0x00,0x82,0xFE,0x82,0x00, // I

0x00,0xFE,0x90,0x90,0x90,0x80, // F

0x00,0xFE,0x90,0x90,0x90,0x80, // F

0x00,0x00,0x82,0xFE,0x82,0x00, // I

0x00,0x7C,0x82,0x82,0x82,0x44, // C

0x00,0xFC,0x02,0x02,0x02,0xFC, // U

0x00,0xFE,0x02,0x02,0x02,0x02, // L

0x00,0x80,0x80,0xFE,0x80,0x80, // T

0x00,0xE0,0x10,0x0E,0x10,0xE0, // Y

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // No display

0x00,0x00,0x00,0x42,0xFE,0x02,0x00,0x00, // 1 If you do not press the button to skip, it will automatically switch to the next mode after displaying "1"

};



unsigned char code DifficultySelect[]={ //Difficulty corresponding to the number, "1~5"

0x00,0x00,0x00,0x42,0xFE,0x02,0x00,0x00, // 1

0x00,0x00,0x42,0x86,0x8A,0x92,0x62,0x00, // 2

0x00,0x00,0x84,0x82,0xA2,0xD2,0x8C,0x00, // 3

0x00,0x00,0x18,0x28,0x48,0xFE,0x08,0x00, // 4

0x00,0x00,0xE4,0xA2,0xA2,0xA2,0x9C,0x00, // 5

0x00,0x00,0x00,0x42,0xFE,0x02,0x00,0x00, // 1 is the same as the first line because it is to be displayed in a circular scrolling manner

};



unsigned char code Text_SCORE[]={

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //No display

0x00,0x62,0x92,0x92,0x92,0x8C, // S

0x00,0x7C,0x82,0x82,0x82,0x44, // C

0x00,0x7C,0x82,0x82,0x82,0x7C, // O

0x00,0xFE,0x90,0x98,0x94,0x62, // R

0x00,0xFE,0x92,0x92,0x92,0x82, // E

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //No display

};

Credits

Lisleapex Blog
28 projects • 0 followers
Fast Delivery of High-Quality Electronic Components

Comments