#include "gpio.h"
#define OLED_SCLK_Clr() HAL_GPIO_WritePin(SCL_GPIO_Port,SCL_Pin,GPIO_PIN_RESET)
#define OLED_SCLK_Set() HAL_GPIO_WritePin(SCL_GPIO_Port,SCL_Pin,GPIO_PIN_SET)
#define OLED_SDIN_Clr() HAL_GPIO_WritePin(SDA_GPIO_Port,SDA_Pin,GPIO_PIN_RESET)
#define OLED_SDIN_Set() HAL_GPIO_WritePin(SDA_GPIO_Port,SDA_Pin,GPIO_PIN_SET)
#define OLED_CMD 0 //дÃüÁî
#define OLED_DATA 1 //дÊý¾Ý
#define u8 unsigned char
#define u32 unsigned int
void OLED_ClearPoint(u8 x,u8 y);
void OLED_ColorTurn(u8 i);
void OLED_DisplayTurn(u8 i);
void I2C_Start(void);
void I2C_Stop(void);
void I2C_WaitAck(void);
void Send_Byte(u8 dat);
void OLED_WR_Byte(u8 dat,u8 mode);
void OLED_DisPlay_On(void);
void OLED_DisPlay_Off(void);
void OLED_Refresh(void);
void OLED_Clear(void);
void OLED_DrawPoint(u8 x,u8 y);
void OLED_DrawLine(u8 x1,u8 y1,u8 x2,u8 y2);
void OLED_DrawCircle(u8 x,u8 y,u8 r);
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size1);
void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 size1);
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size1);
void OLED_ShowChinese(u8 x,u8 y,u8 num,u8 size1);
void OLED_ScrollDisplay(u8 num,u8 space);
void OLED_WR_BP(u8 x,u8 y);
void OLED_ShowPicture(u8 x0,u8 y0,u8 x1,u8 y1,u8 BMP[]);
void OLED_Init(void);
void OLED_DrawBitmap(int x,int y,u8 *bitmap,u8 w,u8 h);
#include "oled.h"
u8 OLED_GRAM[8][128]={0};
void I2C_Start(void)
{
OLED_SDIN_Set();
OLED_SCLK_Set();
OLED_SDIN_Clr();
OLED_SCLK_Clr();
}
//½áÊøÐźÅ
void I2C_Stop(void)
{
OLED_SCLK_Set();
OLED_SDIN_Clr();
OLED_SDIN_Set();
}
//µÈ´ýÐźÅÏìÓ¦
void I2C_WaitAck(void) //²âÊý¾ÝÐźŵĵçƽ
{
OLED_SCLK_Set();
OLED_SCLK_Clr();
}
//дÈëÒ»¸ö×Ö½Ú
void Send_Byte(u8 dat)
{
u8 i;
for(i=0;i<8;i++)
{
OLED_SCLK_Clr();//½«Ê±ÖÓÐźÅÉèÖÃΪµÍµçƽ
if(dat&0x80)//½«datµÄ8λ´Ó×î¸ßλÒÀ´ÎдÈë
{
OLED_SDIN_Set();
}
else
{
OLED_SDIN_Clr();
}
OLED_SCLK_Set();//½«Ê±ÖÓÐźÅÉèÖÃΪ¸ßµçƽ
OLED_SCLK_Clr();//½«Ê±ÖÓÐźÅÉèÖÃΪµÍµçƽ
dat<<=1;
}
}
//·¢ËÍÒ»¸ö×Ö½Ú
//ÏòSSD1306дÈëÒ»¸ö×Ö½Ú¡£
//mode:Êý¾Ý/ÃüÁî±êÖ¾ 0,±íʾÃüÁî;1,±íʾÊý¾Ý;
void OLED_WR_Byte(u8 dat,u8 mode)
{
I2C_Start();
Send_Byte(0x78);
I2C_WaitAck();
if(mode){Send_Byte(0x40);}
else{Send_Byte(0x00);}
I2C_WaitAck();
Send_Byte(dat);
I2C_WaitAck();
I2C_Stop();
}
//¿ªÆôOLEDÏÔʾ
void OLED_DisPlay_On(void)
{
OLED_WR_Byte(0x8D,OLED_CMD);//µçºÉ±ÃʹÄÜ
OLED_WR_Byte(0x14,OLED_CMD);//¿ªÆôµçºÉ±Ã
OLED_WR_Byte(0xAF,OLED_CMD);//µãÁÁÆÁÄ»
}
//¹Ø±ÕOLEDÏÔʾ
void OLED_DisPlay_Off(void)
{
OLED_WR_Byte(0x8D,OLED_CMD);//µçºÉ±ÃʹÄÜ
OLED_WR_Byte(0x10,OLED_CMD);//¹Ø±ÕµçºÉ±Ã
OLED_WR_Byte(0xAF,OLED_CMD);//¹Ø±ÕÆÁÄ»
}
//¸üÐÂÏÔ´æµ½OLED
void OLED_Refresh(void)
{
u8 i,n;
for(i=0;i<8;i++)
{
OLED_WR_Byte(0xb0+i,OLED_CMD); //ÉèÖÃÐÐÆðʼµØÖ·
OLED_WR_Byte(0x00,OLED_CMD); //ÉèÖõÍÁÐÆðʼµØÖ·
OLED_WR_Byte(0x10,OLED_CMD); //ÉèÖøßÁÐÆðʼµØÖ·
I2C_Start();
Send_Byte(0x78);
I2C_WaitAck();
Send_Byte(0x40);
I2C_WaitAck();
for(n=0;n<128;n++)
{
Send_Byte(OLED_GRAM[i][n]);
I2C_WaitAck();
}
// OLED_WR_Byte(OLED_GRAM[i][n],OLED_DATA);
I2C_Stop();
}
}
//ÇåÆÁº¯Êý
void OLED_Clear(void)
{
u8 i,n;
for(i=0;i<8;i++)
{
for(n=0;n<128;n++)
{
OLED_GRAM[i][n]=0;//Çå³ýËùÓÐÊý¾Ý
}
}
//OLED_Refresh();//¸üÐÂÏÔʾ
}
//»µã
//x:0~127
//y:0~63
void OLED_DrawPoint(u8 x,u8 y)
{
u8 i,m,n;
i=y/8;
m=y%8;
n=1<<m;
OLED_GRAM[i][x]|=n;
}
//Çå³ýÒ»¸öµã
//x:0~127
//y:0~63
void OLED_ClearPoint(u8 x,u8 y)
{
u8 i,m,n;
i=y/8;
m=y%8;
n=1<<m;
OLED_GRAM[i][x]=~OLED_GRAM[i][x];
OLED_GRAM[i][x]|=n;
OLED_GRAM[i][x]=~OLED_GRAM[i][x];
}
void OLED_DrawBitmap(int x,int y,unsigned char *bitmap,unsigned char w,unsigned char h){
u8 i,n,m,temp;
for(i=0;i<h/8;i++){
for(n=0;n<w;n++){
if(x+n>0 && x+n<128){
temp=bitmap[w*i+n];
for(m=0;m<8;m++){
if((temp>>m) & 0x01) OLED_DrawPoint(x+n,y+m+i*8);
}
}
}
}
}
//»Ïß
//x:0~128
//y:0~64
void OLED_DrawLine(u8 x1,u8 y1,u8 x2,u8 y2)
{
u8 i,k,k1,k2,y0;
if((x1<0)||(x2>128)||(y1<0)||(y2>64)||(x1>x2)||(y1>y2))return;
if(x1==x2) //»ÊúÏß
{
for(i=0;i<(y2-y1);i++)
{
OLED_DrawPoint(x1,y1+i);
}
}
else if(y1==y2) //»ºáÏß
{
for(i=0;i<(x2-x1);i++)
{
OLED_DrawPoint(x1+i,y1);
}
}
else //»Ð±Ïß
{
k1=y2-y1;
k2=x2-x1;
k=k1*10/k2;
for(i=0;i<(x2-x1);i++)
{
OLED_DrawPoint(x1+i,y1+i*k/10);
}
}
}
void OLED_Init(void)
{
OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel
OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
OLED_WR_Byte(0x40,OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register
OLED_WR_Byte(0xCF,OLED_CMD);// Set SEG Output Current Brightness
OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping 0xa0×óÓÒ·´ÖÃ 0xa1Õý³£
OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction 0xc0ÉÏÏ·´Öà 0xc8Õý³£
OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display
OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty
OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
OLED_WR_Byte(0x00,OLED_CMD);//-not offset
OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
OLED_WR_Byte(0xf0,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
OLED_WR_Byte(0x12,OLED_CMD);
OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh
OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level
OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
OLED_WR_Byte(0x02,OLED_CMD);//
OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable
OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)
OLED_WR_Byte(0xAF,OLED_CMD);
}
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "tim.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "oled.h"
#include "actor.h"
#include "time.h"
#include "stdlib.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#define WIDTH 128
#define HEIGHT 64
#define PLAYERSPEED 1
#define PLAYERSHAPEWIDTH 16
#define PLAYERSHAPEHEIGHT 16
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
struct ACTOR{
int16_t x;
int16_t y;
uint8_t w;
uint8_t h;
uint8_t *shape;
uint8_t living;
};
//struct ACTOR bigboat;
//struct ACTOR playerplane;
struct ACTOR player_lefthand;
struct ACTOR player_righthand;
struct ACTOR enemy_hugwug;
struct ACTOR bullet;
enum key_state{
left_state,
right_state,
fire_state,
none_state,
};
uint8_t key_flag=none_state;
uint8_t whichhand=0;
uint8_t bullet_frame=0;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
void on_enter();
void on_input();
void get_key();
void on_update();
void on_draw();
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM3_Init();
/* USER CODE BEGIN 2 */
OLED_Init();
on_enter();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
on_input();
on_update();
on_draw();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
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 according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
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_DIV1;
RCC_OscInitStruct.PLL.PLLN = 8;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_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_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
void on_enter(){
// bigboat.x=15;
// bigboat.y=0;
// bigboat.shape=(uint8_t *)big_boat;
// playerplane.x=(128-16)/2;
// playerplane.y=63-16;
// playerplane.shape=(uint8_t *)plane;
player_lefthand.w=32;
player_lefthand.h=32;
player_lefthand.x=10;
player_lefthand.y=HEIGHT-player_lefthand.h;
player_lefthand.shape=(uint8_t *)lefthand;
player_lefthand.living=1;
player_righthand.w=32;
player_righthand.h=32;
player_righthand.x=player_lefthand.x+player_righthand.w+10;
player_righthand.y=HEIGHT-player_righthand.h;
player_righthand.shape=(uint8_t *)righthand;
player_righthand.living=1;
enemy_hugwug.w=16;
enemy_hugwug.h=32;
enemy_hugwug.x=(WIDTH-enemy_hugwug.w)/2;
enemy_hugwug.y=0;
enemy_hugwug.shape=(uint8_t *)hugwug;
bullet.x=0;
bullet.y=0;
bullet.w=8;
bullet.h=8;
bullet.shape=(uint8_t *)smallhand;
bullet.living=0;
}
void get_key(){
if(!HAL_GPIO_ReadPin(KEY_LEFT_GPIO_Port,KEY_LEFT_Pin)) key_flag=left_state;
else if(!HAL_GPIO_ReadPin(KEY_RIGHT_GPIO_Port,KEY_RIGHT_Pin)) key_flag=right_state;
else if(!HAL_GPIO_ReadPin(KEY_FIRE_GPIO_Port,KEY_FIRE_Pin)) key_flag=fire_state;
else key_flag=none_state;
}
void on_input(){
get_key();
}
void on_update(){
bullet_frame++;
uint8_t x0;
enemy_hugwug.x++;
if(enemy_hugwug.x>128) enemy_hugwug.x=-16;
if(bullet.living ){
bullet.y-=5;
if(bullet.y<=4){
bullet.living=0;
player_lefthand.living=1;
player_righthand.living=1;
}
if(player_lefthand.living==0) bullet.x+=2;
if(player_righthand.living==0) bullet.x-=2;
}
// bigboat.y++;
// if(bigboat.y>64){
// bigboat.y=-32;
// bigboat.x=rand()%WIDTH;
// }
// switch(key_flag){
// case left_state:
// playerplane.x-=PLAYERSPEED;
// if(playerplane.x<=0) playerplane.x=0;
// break;
// case right_state:
// playerplane.x+=PLAYERSPEED;
// if(playerplane.x+16>=127) playerplane.x=WIDTH-16;
// break;
// case fire_state:
// playerplane.x-=PLAYERSPEED;
// if(playerplane.x==0) playerplane.x=0;
// break;
// }
switch(key_flag){
case left_state:
player_lefthand.x-=PLAYERSPEED;
if(player_lefthand.x<=0){
player_lefthand.x=0;
}
player_righthand.x=player_lefthand.x+player_righthand.w+10;
break;
case right_state:
player_lefthand.x+=PLAYERSPEED;
if(player_lefthand.x+74>=127) player_lefthand.x=WIDTH-74;
player_righthand.x=player_lefthand.x+player_righthand.w+10;
break;
case fire_state:
if(!bullet.living) {
bullet.living=1;
bullet.y=60;
whichhand++;
if(whichhand%3==0){
player_lefthand.living=0;
bullet.x=player_lefthand.x+12;
}
else {
player_righthand.living=0;
bullet.x=player_righthand.x+player_righthand.y-12;
}
// whichhand++;
// if(whichhand%2){
// x0=player_lefthand.x+player_lefthand.w/2;
// OLED_DrawLine(x0,63,player_lefthand.x+(WIDTH-74)/2,10);
// }
// else {
// x0=player_righthand.x+player_righthand.w/2;
// OLED_DrawLine(player_lefthand.x+(WIDTH-74)/2,10,x0,63);
// }
break;
}
}
}
void on_draw(){
OLED_Clear();
// OLED_DrawRect(0,0,16,32);
// OLED_DrawBitmap(bigboat.x,bigboat.y,bigboat.shape,32,32);
// // OLED_ShowPicture((128-16)/2,5,(128-16)/2+16,7,(u8 *)plane);
// OLED_DrawBitmap(playerplane.x,playerplane.y,playerplane.shape,16,16);
if(player_lefthand.living) OLED_DrawBitmap(player_lefthand.x,player_lefthand.y,player_lefthand.shape,player_lefthand.w,player_lefthand.h);
if(player_righthand.living) OLED_DrawBitmap(player_righthand.x,player_righthand.y,player_righthand.shape,player_righthand.w,player_righthand.h);
OLED_DrawBitmap(enemy_hugwug.x,enemy_hugwug.y,enemy_hugwug.shape,enemy_hugwug.w,enemy_hugwug.h);
if(bullet.living) OLED_DrawBitmap(bullet.x,bullet.y,bullet.shape,bullet.w,bullet.h);
OLED_Refresh();
}
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */