基于RTOS的STM32游戏机

1.游戏机的主要功能

所有游戏都来着B站JL单片机博主开源

这款游戏机具备存档与继续游戏功能,允许玩家在任何时候退出当前游戏并保存进度,以便日后随时并继续之前的冒险。不仅如此,游戏机还支持多任务处理,玩家可以在退出当前游戏后,无缝切换至其他游戏进行娱乐,而当再次回到之前的游戏时,进度将完好无损,确保游戏体验的连续性和完整性。

除了游戏功能外,这款游戏机还内置了视频播放功能。特别值得一提的是,游戏机内置了一段蔡徐坤打篮球的精彩视频,让玩家在享受游戏乐趣的同时,也能欣赏到偶像的风采。

在游戏内容方面,这款游戏机配备了6款精心挑选的游戏,涵盖了多种类型和风格。

有谷歌小恐龙游戏,贪吃蛇,2048,飞翔的小鸟,飞机大战,俄罗斯方块。

还拥有一个可以查询各个游戏状态的任务。

2.需要的硬件

材料数量
stm32c8t6最小系统板1
按键2
摇杆2
OLED屏幕1

3.游戏机原理

基于RTOS系统创建一个菜单函数的任务,然后通过摇杆选择自己需要玩的游戏,再按下按键,

系统查询有没有创建该游戏任务,如果有就继续该任务,如果没有就参加一个新的任务。

进入游戏可以想退出时可以选择保存存档退出和直接退出返回到任务函数重新选择。菜单页面选择查询任务状态可以查看到那个游戏有存档,那个游戏没有存档。

4.实现代码

摇杆和按键的底层代码

#include "stm32f10x.h" // Device header
#include "key.h"
#include "delay.h"
uint8_t Key_KeyNumber;
//**定时器扫描按键**//
//采样次数
#define SAMPLES         30
int xw,yw,xw2,yw2;
void Joystick_Init(void)
{//开始GPIOB的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//将LDR引脚设为模拟输入GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);
}/******************************************************************* 函 数 名 称:ADC_Joystick_Init* 函 数 说 明:初始化ADC功能* 函 数 形 参:无* 函 数 返 回:无* 作       者:LC* 备       注:无
******************************************************************/void ADC_Joystick_Init(void)
{Joystick_Init();//开启ADC时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//ADC频率进行6分频RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADC结构体ADC_InitTypeDef ADC_InitStructure;ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;	//独立模式ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	//数据右对齐ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;	//软件触发ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;	//单次转换ADC_InitStructure.ADC_ScanConvMode = DISABLE;	//非扫描模式ADC_InitStructure.ADC_NbrOfChannel = 1;	//总通道数ADC_Init(ADC1, &ADC_InitStructure);	//初始化ADC1//开启ADC1ADC_Cmd(ADC1, ENABLE);//进行ADC校准ADC_ResetCalibration(ADC1);while(ADC_GetResetCalibrationStatus(ADC1) == SET);ADC_StartCalibration(ADC1);while(ADC_GetCalibrationStatus(ADC1) == SET);	
}/******************************************************************* 函 数 名 称:Get_Adc_Joystick_Value* 函 数 说 明:对DMA保存的数据进行平均值计算后输出* 函 数 形 参:CHx 第几个扫描的数据* 函 数 返 回:对应扫描的ADC值* 作       者:LC* 备       注:无
******************************************************************/
unsigned int Get_Adc_Joystick_Value(char CHx)
{uint32_t Data = 0;//设置采集通道ADC_RegularChannelConfig( ADC1, CHx, 1, ADC_SampleTime_55Cycles5 );//开始软件转换ADC_SoftwareStartConvCmd(ADC1,ENABLE);while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC )); // 等待转换结束for(int i = 0; i < SAMPLES; i++){Data += ADC_GetConversionValue(ADC1);//  Delay_ms(2);}Data = Data / SAMPLES;return Data;
}/******************************************************************* 函 数 名 称:Get_MQ2_Percentage_value* 函 数 说 明:读取摇杆值,并且返回百分比* 函 数 形 参:0=读取摇杆左右值,1=读取摇杆上下值* 函 数 返 回:返回百分比* 作       者:LC* 备       注:无
******************************************************************/
unsigned int Get_Joystick_Percentage_value(char dir)
{int adc_new = 0;int Percentage_value = 0;if( dir == 0){adc_new = Get_Adc_Joystick_Value(ADC_Channel_0);}else{adc_new = Get_Adc_Joystick_Value(ADC_Channel_1);}Percentage_value = ((float)adc_new/4095.0f) * 100.f;return Percentage_value;
}
unsigned int Get_Joystick2_Percentage_value(char dir)
{int adc_new = 0;int Percentage_value = 0;if( dir == 0){adc_new = Get_Adc_Joystick_Value(ADC_Channel_2);}else{adc_new = Get_Adc_Joystick_Value(ADC_Channel_3);}Percentage_value = ((float)adc_new/4095.0f) * 100.f;return Percentage_value;
}
void GPIO_KeyInit(void) // 初始化GPIO
{GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitTypeDef GPIO_InitStructure3;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = key_r_push_pin| key_l_push_pin;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(key_r_back_and_push_port, &GPIO_InitStructure);GPIO_InitStructure3.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure3.GPIO_Pin = sw1_pin | sw2_pin;GPIO_InitStructure3.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(sw_port, &GPIO_InitStructure3);
}void Timer_Init(void) // 初始化定时器
{TIM_TimeBaseInitTypeDef TimeBaseInitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);TIM_InternalClockConfig(TIM2);TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;TimeBaseInitStructure.TIM_Period = 300 - 1;TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;TimeBaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2, &TimeBaseInitStructure);TIM_ClearFlag(TIM2, TIM_FLAG_Update);TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&NVIC_InitStructure);TIM_Cmd(TIM2, ENABLE);
}uint8_t Key(void) // 获取按键值
{uint8_t Temp;Temp = Key_KeyNumber;Key_KeyNumber = 0;return Temp;
}uint8_t Get_Key(void) // 获取电平变化
{uint8_t KeyNum = 0;if((xw<30))    KeyNum = r_front_key_value;if((xw>70))    KeyNum = r_back_key_value;if((yw>70))    KeyNum = r_right_key_value;if((yw<30))    KeyNum = r_left_key_value;if((xw2<30))  KeyNum =l_front_key_value;if((xw2>70))  KeyNum=l_back_key_value;if((yw2>70))  KeyNum=l_right_key_value;if((yw2<30))  KeyNum=l_left_key_value;if (GPIO_ReadInputDataBit(key_r_back_and_push_port, key_r_push_pin) == 0){KeyNum = r_push_key_value;}if (GPIO_ReadInputDataBit(key_r_back_and_push_port, key_l_push_pin) == 0){KeyNum = l_push_key_value;}if (GPIO_ReadInputDataBit(sw_port, sw1_pin) == 0){KeyNum = sw1_key_value;}if (GPIO_ReadInputDataBit(sw_port, sw2_pin) == 0){KeyNum = sw2_key_value;}return KeyNum;
}void Loop_Key(void) // 扫描按键
{static uint8_t LastKey = 0, NowKey = 0;LastKey = NowKey;NowKey = Get_Key();if (LastKey == r_front_key_value && NowKey == 0){Key_KeyNumber = r_front_key_value;}if (LastKey == r_back_key_value && NowKey == 0){Key_KeyNumber = r_back_key_value;}if (LastKey == r_left_key_value && NowKey == 0){Key_KeyNumber = r_left_key_value;}if (LastKey == r_right_key_value && NowKey == 0){Key_KeyNumber = r_right_key_value;}if (LastKey == r_push_key_value && NowKey == 0){Key_KeyNumber = r_push_key_value;}if (LastKey == l_front_key_value && NowKey == 0){Key_KeyNumber = l_front_key_value;}if (LastKey == l_back_key_value && NowKey == 0){Key_KeyNumber = l_back_key_value;}if (LastKey == l_left_key_value && NowKey == 0){Key_KeyNumber = l_left_key_value;}if (LastKey == l_right_key_value && NowKey == 0){Key_KeyNumber = l_right_key_value;}if (LastKey == l_push_key_value && NowKey == 0){Key_KeyNumber = l_push_key_value;}if (LastKey == sw1_key_value && NowKey == 0){Key_KeyNumber = sw1_key_value;}if (LastKey == sw2_key_value && NowKey == 0){Key_KeyNumber = sw2_key_value;}}void Key_Init(void) // 按键初始化
{GPIO_KeyInit();Timer_Init();ADC_Joystick_Init();
}void TIM2_IRQHandler(void) // 定时器扫描(30ms)
{if (TIM_GetITStatus(TIM2, TIM_IT_Update) == 1){xw=Get_Joystick_Percentage_value(0);yw=Get_Joystick_Percentage_value(1);xw2=Get_Joystick2_Percentage_value(0);yw2=Get_Joystick2_Percentage_value(1);Loop_Key();TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}

菜单任务逻辑

int menu(void)
{while (1){//查询是否创建该任务vTaskGetInfo(game1_Handler, &game1_state, pdTRUE, eInvalid);vTaskGetInfo(game2_Handler, &game2_state, pdTRUE, eInvalid);vTaskGetInfo(game3_Handler, &game3_state, pdTRUE, eInvalid);vTaskGetInfo(game4_Handler, &game4_state, pdTRUE, eInvalid);vTaskGetInfo(game5_Handler, &game5_state, pdTRUE, eInvalid);vTaskGetInfo(game6_Handler, &game6_state, pdTRUE, eInvalid);vTaskGetInfo(game7_Handler, &game7_state, pdTRUE, eInvalid);vTaskGetInfo(  info_Handler, &info_state, pdTRUE, eInvalid);vTaskGetInfo(Video_Handler, &info_state, pdTRUE, eInvalid);B_OLED_Clear();//显示ui界面if(select<6){B_OLED_ShowString(14, 20, "1", B_OLED_8X16);B_OLED_ShowString(14 + (length_x + distance_x) * 1, 20, "2", B_OLED_8X16);B_OLED_ShowString(14 + (length_x + distance_x) * 2, 20, "3", B_OLED_8X16);B_OLED_ShowString(14 + (length_x + distance_x) * 3, 20, "4", B_OLED_8X16);B_OLED_ShowString(35, 50, "freeRTOS", B_OLED_6X8);B_OLED_DrawRectangle(distance_x, distance_y, length_x, length_y, B_OLED_UNFILLED);B_OLED_DrawRectangle(distance_x + length_x + distance_x, distance_y, length_x, length_y, B_OLED_UNFILLED);B_OLED_DrawRectangle(distance_x + (length_x + distance_x) * 2, distance_y, length_x, length_y, B_OLED_UNFILLED);B_OLED_DrawRectangle(distance_x + (length_x + distance_x) * 3, distance_y, length_x, length_y, B_OLED_UNFILLED);B_OLED_DrawRectangle(distance_x, length_y + distance_y2 + distance_y, length_x + (distance_x + length_x) * 3, length_y2, B_OLED_UNFILLED);if (select == 1){sprintf(text_menu, "Menu:dragon");B_OLED_ReverseArea(distance_x, distance_y, length_x, length_y);}else if (select == 2){sprintf(text_menu, "Menu:war");B_OLED_ReverseArea(distance_x + length_x + distance_x, distance_y, length_x, length_y);}else if (select == 3){sprintf(text_menu, "Menu:bird");B_OLED_ReverseArea(distance_x + (length_x + distance_x) * 2, distance_y, length_x, length_y);}else if (select == 4){sprintf(text_menu, "Menu:block");B_OLED_ReverseArea(distance_x + (length_x + distance_x) * 3, distance_y, length_x, length_y);}else if (select == 5){sprintf(text_menu, "Menu:info");B_OLED_ReverseArea(distance_x, length_y + distance_y2 + distance_y, length_x + (distance_x + length_x) * 3, length_y2);}	}if(select>=6){B_OLED_ShowString(14, 20, "6", B_OLED_8X16);B_OLED_ShowString(14 + (length_x + distance_x) * 1, 20, "7", B_OLED_8X16);B_OLED_ShowString(14 + (length_x + distance_x) * 2, 20, "8", B_OLED_8X16);B_OLED_ShowString(14 + (length_x + distance_x) * 3, 20, "9", B_OLED_8X16);B_OLED_ShowString(35, 50, "freeRTOS", B_OLED_6X8);B_OLED_DrawRectangle(distance_x, distance_y, length_x, length_y, B_OLED_UNFILLED);B_OLED_DrawRectangle(distance_x + length_x + distance_x, distance_y, length_x, length_y, B_OLED_UNFILLED);B_OLED_DrawRectangle(distance_x + (length_x + distance_x) * 2, distance_y, length_x, length_y, B_OLED_UNFILLED);B_OLED_DrawRectangle(distance_x + (length_x + distance_x) * 3, distance_y, length_x, length_y, B_OLED_UNFILLED);B_OLED_DrawRectangle(distance_x, length_y + distance_y2 + distance_y, length_x + (distance_x + length_x) * 3, length_y2, B_OLED_UNFILLED);if (select == 6)     B_OLED_ReverseArea(distance_x, distance_y, length_x, length_y),sprintf(text_menu, "Menu:Snake");if (select == 7)     B_OLED_ReverseArea(distance_x + length_x + distance_x, distance_y, length_x, length_y),sprintf(text_menu, "Menu:Video");if (select == 8)     B_OLED_ReverseArea(distance_x + (length_x + distance_x) * 2, distance_y, length_x, length_y),sprintf(text_menu, "Menu:2048");if (select == 9)     B_OLED_ReverseArea(distance_x + (length_x + distance_x) * 3, distance_y, length_x, length_y),sprintf(text_menu, "Menu:no");if (select == 10)    B_OLED_ReverseArea(distance_x, length_y + distance_y2 + distance_y, length_x + (distance_x + length_x) * 3, length_y2),sprintf(text_menu, "Menu:info");;}//判断改任务是否存在存在上面显示runif ((game1_state.eCurrentState == eRunning) || (game1_state.eCurrentState == eSuspended)){B_OLED_DrawCircle(15 + offset_state_x, 20 + offset_state_y, 2, B_OLED_UNFILLED);if (select == 1)B_OLED_ShowString(110, 0, "run", B_OLED_6X8);}if ((game2_state.eCurrentState == eRunning) || (game2_state.eCurrentState == eSuspended)){B_OLED_DrawCircle(15 + (length_x + distance_x) * 1 + offset_state_x, 20 + offset_state_y, 2, B_OLED_UNFILLED);if (select == 2)B_OLED_ShowString(110, 0, "run", B_OLED_6X8);}if ((game3_state.eCurrentState == eRunning) || (game3_state.eCurrentState == eSuspended)){B_OLED_DrawCircle(15 + (length_x + distance_x) * 2 + offset_state_x, 20 + offset_state_y, 2, B_OLED_UNFILLED);if (select == 3)B_OLED_ShowString(110, 0, "run", B_OLED_6X8);}if ((game4_state.eCurrentState == eRunning) || (game4_state.eCurrentState == eSuspended)){B_OLED_DrawCircle(15 + (length_x + distance_x) * 3 + offset_state_x, 20 + offset_state_y, 2, B_OLED_UNFILLED);if (select == 4)B_OLED_ShowString(110, 0, "run", B_OLED_6X8);}if ((game5_state.eCurrentState == eRunning) || (game5_state.eCurrentState == eSuspended)){B_OLED_DrawCircle(15 + offset_state_x, 20 + offset_state_y, 2, B_OLED_UNFILLED);if (select == 6)B_OLED_ShowString(110, 0, "run", B_OLED_6X8);}if ((game6_state.eCurrentState == eRunning) || (game6_state.eCurrentState == eSuspended)){B_OLED_DrawCircle(15 + offset_state_x, 20 + offset_state_y, 2, B_OLED_UNFILLED);if (select == 8)B_OLED_ShowString(110, 0, "run", B_OLED_6X8);}if ((game7_state.eCurrentState == eRunning) || (game7_state.eCurrentState == eSuspended)){B_OLED_DrawCircle(15 + offset_state_x, 20 + offset_state_y, 2, B_OLED_UNFILLED);if (select == 9)B_OLED_ShowString(110, 0, "run", B_OLED_6X8);}if ((info_state.eCurrentState == eRunning) || (info_state.eCurrentState == eSuspended)){B_OLED_DrawCircle(35 + offset_state_x2, 50 + offset_state_y2, 2, B_OLED_UNFILLED);if (select == 5||select == 10)B_OLED_ShowString(110, 0, "run", B_OLED_6X8);}if ((Video_state.eCurrentState == eRunning) || (Video_state.eCurrentState == eSuspended)){B_OLED_DrawCircle(35 + offset_state_x2, 50 + offset_state_y2, 2, B_OLED_UNFILLED);if (select == 7)B_OLED_ShowString(110, 0, "run", B_OLED_6X8);}B_OLED_ShowString(0, 0, text_menu, B_OLED_8X16);menu_key_num = Get_Key();if (menu_key_num != 0){if ((menu_key_num == r_push_key_value) || (menu_key_num == l_push_key_value)){return select;}switch (menu_key_num){case r_right_key_value:select++;break;case r_left_key_value:select--;break;case r_back_key_value:select += 4;break;case r_front_key_value:select -= 4;case l_right_key_value:select++;break;case l_left_key_value:select--;break;case l_back_key_value:select += 4;break;case l_front_key_value:select -= 4;default:break;}if (select > 10)select = 10;if (select < 1)select = 1;while (menu_key_num != 0){menu_key_num = Get_Key();}}B_OLED_Update();}
}

游戏任务逻辑

void startup()
{init();while(1){B_OLED_Clear();FrameLoop();
//		KeyLoop();GameLoop();B_OLED_Update();if (get_key_status() == sw1_key_value){vTaskResume(menuTask_Handler);vTaskSuspend(game6_Handler);}else if (get_key_status() == sw2_key_value){vTaskResume(menuTask_Handler);vTaskDelete(game6_Handler);}}}

查询任务状态和存档状态

int infos(){B_OLED_Clear();vTaskGetInfo(game1_Handler, &game1_state, pdTRUE, eInvalid);vTaskGetInfo(game2_Handler, &game2_state, pdTRUE, eInvalid);vTaskGetInfo(game3_Handler, &game3_state, pdTRUE, eInvalid);vTaskGetInfo(game4_Handler, &game4_state, pdTRUE, eInvalid);vTaskGetInfo(game1_Handler, &game5_state, pdTRUE, eInvalid);vTaskGetInfo(game2_Handler, &game6_state, pdTRUE, eInvalid);vTaskGetInfo(game3_Handler, &game7_state, pdTRUE, eInvalid);vTaskGetInfo(game4_Handler, &Video_state, pdTRUE, eInvalid);B_OLED_ShowString(0, 0, "game1", B_OLED_6X8);switch (game1_state.eCurrentState){case eRunning:B_OLED_ShowString(0, text_height+1, "eRunning", B_OLED_6X8);break;case eReady:B_OLED_ShowString(0, text_height + 1, "eReady", B_OLED_6X8);break;case eBlocked:B_OLED_ShowString(0, text_height + 1, "eBlocked", B_OLED_6X8);break;case eSuspended:B_OLED_ShowString(0, text_height + 1, "eSuspended", B_OLED_6X8);break;case eDeleted:B_OLED_ShowString(0, text_height + 1, "eDeleted", B_OLED_6X8);break;case eInvalid:B_OLED_ShowString(0, text_height + 1, "eInvalid", B_OLED_6X8);break;default:break;}sprintf(text, "pro:%1d", game1_state.uxBasePriority);B_OLED_ShowString(0, 2 * text_height + 1, text, B_OLED_6X8);// sprintf(text, "stack:%1d", game1_state.usStackHighWaterMark);// B_OLED_ShowString(0, 3 * text_height + 1, text, B_OLED_6X8);B_OLED_ShowString(0, 4 * text_height + 1, "game2", B_OLED_6X8);switch (game2_state.eCurrentState){case eRunning:B_OLED_ShowString(0, 5 * text_height + 1, "eRunning", B_OLED_6X8);break;case eReady:B_OLED_ShowString(0, 5 * text_height + 1, "eReady", B_OLED_6X8);break;case eBlocked:B_OLED_ShowString(0, 5 * text_height + 1, "eBlocked", B_OLED_6X8);break;case eSuspended:B_OLED_ShowString(0, 5 * text_height + 1, "eSuspended", B_OLED_6X8);break;case eDeleted:B_OLED_ShowString(0, 5 * text_height + 1, "eDeleted", B_OLED_6X8);break;case eInvalid:B_OLED_ShowString(0, 5 * text_height + 1, "eInvalid", B_OLED_6X8);break;default:break;}sprintf(text, "pro:%1d", game2_state.uxBasePriority);B_OLED_ShowString(0, 6 * text_height + 1, text, B_OLED_6X8);// sprintf(text, "stack:%1d", game2_state.usStackHighWaterMark);// B_OLED_ShowString(0, 7 * text_height + 1, text, B_OLED_6X8);B_OLED_ShowString(half, 0, "game3", B_OLED_6X8);switch (game3_state.eCurrentState){case eRunning:B_OLED_ShowString(half, text_height + 1, "eRunning", B_OLED_6X8);break;case eReady:B_OLED_ShowString(half, text_height + 1, "eReady", B_OLED_6X8);break;case eBlocked:B_OLED_ShowString(half, text_height + 1, "eBlocked", B_OLED_6X8);break;case eSuspended:B_OLED_ShowString(half, text_height + 1, "eSuspended", B_OLED_6X8);break;case eDeleted:B_OLED_ShowString(half, text_height + 1, "eDeleted", B_OLED_6X8);break;case eInvalid:B_OLED_ShowString(half, text_height + 1, "eInvalid", B_OLED_6X8);break;default:break;}sprintf(text, "pro:%1d", game3_state.uxBasePriority);B_OLED_ShowString(half, 2 * text_height + 1, text, B_OLED_6X8);// sprintf(text, "stack:%1d", game3_state.usStackHighWaterMark);// B_OLED_ShowString(half, 3 * text_height + 1, text, B_OLED_6X8);B_OLED_ShowString(half, 4 * text_height + 1, "game4", B_OLED_6X8);switch (game4_state.eCurrentState){case eRunning:B_OLED_ShowString(half, 5 * text_height + 1, "eRunning", B_OLED_6X8);break;case eReady:B_OLED_ShowString(half, 5 * text_height + 1, "eReady", B_OLED_6X8);break;case eBlocked:B_OLED_ShowString(half, 5 * text_height + 1, "eBlocked", B_OLED_6X8);break;case eSuspended:B_OLED_ShowString(half, 5 * text_height + 1, "eSuspended", B_OLED_6X8);break;case eDeleted:B_OLED_ShowString(half, 5 * text_height + 1, "eDeleted", B_OLED_6X8);break;case eInvalid:B_OLED_ShowString(half, 5 * text_height + 1, "eInvalid", B_OLED_6X8);break;default:break;}sprintf(text, "pro:%1d", game4_state.uxBasePriority);B_OLED_ShowString(half, 6 * text_height + 1, text, B_OLED_6X8);// sprintf(text, "stack:%1d", game4_state.usStackHighWaterMark);// B_OLED_ShowString(half, 7 * text_height + 1, text, B_OLED_6X8);B_OLED_Update();int a=0;while (1){if (((get_key_status() == l_right_key_value)||(get_key_status() ==r_right_key_value))&&(a==0)){ a=1;B_OLED_Clear();B_OLED_ShowString(0, 0, "game5", B_OLED_6X8);switch (game5_state.eCurrentState){case eRunning:B_OLED_ShowString(0, text_height+1, "eRunning", B_OLED_6X8);break;case eReady:B_OLED_ShowString(0, text_height + 1, "eReady", B_OLED_6X8);break;case eBlocked:B_OLED_ShowString(0, text_height + 1, "eBlocked", B_OLED_6X8);break;case eSuspended:B_OLED_ShowString(0, text_height + 1, "eSuspended", B_OLED_6X8);break;case eDeleted:B_OLED_ShowString(0, text_height + 1, "eDeleted", B_OLED_6X8);break;case eInvalid:B_OLED_ShowString(0, text_height + 1, "eInvalid", B_OLED_6X8);break;default:break;}sprintf(text, "pro:%1d", game5_state.uxBasePriority);B_OLED_ShowString(0, 2 * text_height + 1, text, B_OLED_6X8);// sprintf(text, "stack:%1d", game1_state.usStackHighWaterMark);// B_OLED_ShowString(0, 3 * text_height + 1, text, B_OLED_6X8);B_OLED_ShowString(0, 4 * text_height + 1, "game6", B_OLED_6X8);switch (game6_state.eCurrentState){case eRunning:B_OLED_ShowString(0, 5 * text_height + 1, "eRunning", B_OLED_6X8);break;case eReady:B_OLED_ShowString(0, 5 * text_height + 1, "eReady", B_OLED_6X8);break;case eBlocked:B_OLED_ShowString(0, 5 * text_height + 1, "eBlocked", B_OLED_6X8);break;case eSuspended:B_OLED_ShowString(0, 5 * text_height + 1, "eSuspended", B_OLED_6X8);break;case eDeleted:B_OLED_ShowString(0, 5 * text_height + 1, "eDeleted", B_OLED_6X8);break;case eInvalid:B_OLED_ShowString(0, 5 * text_height + 1, "eInvalid", B_OLED_6X8);break;default:break;}sprintf(text, "pro:%1d", game6_state.uxBasePriority);B_OLED_ShowString(0, 6 * text_height + 1, text, B_OLED_6X8);// sprintf(text, "stack:%1d", game2_state.usStackHighWaterMark);// B_OLED_ShowString(0, 7 * text_height + 1, text, B_OLED_6X8);B_OLED_ShowString(half, 0, "game7", B_OLED_6X8);switch (game7_state.eCurrentState){case eRunning:B_OLED_ShowString(half, text_height + 1, "eRunning", B_OLED_6X8);break;case eReady:B_OLED_ShowString(half, text_height + 1, "eReady", B_OLED_6X8);break;case eBlocked:B_OLED_ShowString(half, text_height + 1, "eBlocked", B_OLED_6X8);break;case eSuspended:B_OLED_ShowString(half, text_height + 1, "eSuspended", B_OLED_6X8);break;case eDeleted:B_OLED_ShowString(half, text_height + 1, "eDeleted", B_OLED_6X8);break;case eInvalid:B_OLED_ShowString(half, text_height + 1, "eInvalid", B_OLED_6X8);break;default:break;}sprintf(text, "pro:%1d", game7_state.uxBasePriority);B_OLED_ShowString(half, 2 * text_height + 1, text, B_OLED_6X8);// sprintf(text, "stack:%1d", game3_state.usStackHighWaterMark);// B_OLED_ShowString(half, 3 * text_height + 1, text, B_OLED_6X8);B_OLED_ShowString(half, 4 * text_height + 1, "Video", B_OLED_6X8);switch (Video_state.eCurrentState){case eRunning:B_OLED_ShowString(half, 5 * text_height + 1, "eRunning", B_OLED_6X8);break;case eReady:B_OLED_ShowString(half, 5 * text_height + 1, "eReady", B_OLED_6X8);break;case eBlocked:B_OLED_ShowString(half, 5 * text_height + 1, "eBlocked", B_OLED_6X8);break;case eSuspended:B_OLED_ShowString(half, 5 * text_height + 1, "eSuspended", B_OLED_6X8);break;case eDeleted:B_OLED_ShowString(half, 5 * text_height + 1, "eDeleted", B_OLED_6X8);break;case eInvalid:B_OLED_ShowString(half, 5 * text_height + 1, "eInvalid", B_OLED_6X8);break;default:break;}sprintf(text, "pro:%1d", Video_state.uxBasePriority);B_OLED_ShowString(half, 6 * text_height + 1, text, B_OLED_6X8);// sprintf(text, "stack:%1d", game4_state.usStackHighWaterMark);// B_OLED_ShowString(half, 7 * text_height + 1, text, B_OLED_6X8);B_OLED_Update();}if (((get_key_status() == l_left_key_value)||(get_key_status() ==r_left_key_value))&&(a==1)){a=0;B_OLED_Clear();B_OLED_ShowString(0, 0, "game1", B_OLED_6X8);switch (game1_state.eCurrentState){case eRunning:B_OLED_ShowString(0, text_height+1, "eRunning", B_OLED_6X8);break;case eReady:B_OLED_ShowString(0, text_height + 1, "eReady", B_OLED_6X8);break;case eBlocked:B_OLED_ShowString(0, text_height + 1, "eBlocked", B_OLED_6X8);break;case eSuspended:B_OLED_ShowString(0, text_height + 1, "eSuspended", B_OLED_6X8);break;case eDeleted:B_OLED_ShowString(0, text_height + 1, "eDeleted", B_OLED_6X8);break;case eInvalid:B_OLED_ShowString(0, text_height + 1, "eInvalid", B_OLED_6X8);break;default:break;}sprintf(text, "pro:%1d", game1_state.uxBasePriority);B_OLED_ShowString(0, 2 * text_height + 1, text, B_OLED_6X8);// sprintf(text, "stack:%1d", game1_state.usStackHighWaterMark);// B_OLED_ShowString(0, 3 * text_height + 1, text, B_OLED_6X8);B_OLED_ShowString(0, 4 * text_height + 1, "game2", B_OLED_6X8);switch (game2_state.eCurrentState){case eRunning:B_OLED_ShowString(0, 5 * text_height + 1, "eRunning", B_OLED_6X8);break;case eReady:B_OLED_ShowString(0, 5 * text_height + 1, "eReady", B_OLED_6X8);break;case eBlocked:B_OLED_ShowString(0, 5 * text_height + 1, "eBlocked", B_OLED_6X8);break;case eSuspended:B_OLED_ShowString(0, 5 * text_height + 1, "eSuspended", B_OLED_6X8);break;case eDeleted:B_OLED_ShowString(0, 5 * text_height + 1, "eDeleted", B_OLED_6X8);break;case eInvalid:B_OLED_ShowString(0, 5 * text_height + 1, "eInvalid", B_OLED_6X8);break;default:break;}sprintf(text, "pro:%1d", game2_state.uxBasePriority);B_OLED_ShowString(0, 6 * text_height + 1, text, B_OLED_6X8);// sprintf(text, "stack:%1d", game2_state.usStackHighWaterMark);// B_OLED_ShowString(0, 7 * text_height + 1, text, B_OLED_6X8);B_OLED_ShowString(half, 0, "game3", B_OLED_6X8);switch (game3_state.eCurrentState){case eRunning:B_OLED_ShowString(half, text_height + 1, "eRunning", B_OLED_6X8);break;case eReady:B_OLED_ShowString(half, text_height + 1, "eReady", B_OLED_6X8);break;case eBlocked:B_OLED_ShowString(half, text_height + 1, "eBlocked", B_OLED_6X8);break;case eSuspended:B_OLED_ShowString(half, text_height + 1, "eSuspended", B_OLED_6X8);break;case eDeleted:B_OLED_ShowString(half, text_height + 1, "eDeleted", B_OLED_6X8);break;case eInvalid:B_OLED_ShowString(half, text_height + 1, "eInvalid", B_OLED_6X8);break;default:break;}sprintf(text, "pro:%1d", game3_state.uxBasePriority);B_OLED_ShowString(half, 2 * text_height + 1, text, B_OLED_6X8);// sprintf(text, "stack:%1d", game3_state.usStackHighWaterMark);// B_OLED_ShowString(half, 3 * text_height + 1, text, B_OLED_6X8);B_OLED_ShowString(half, 4 * text_height + 1, "game4", B_OLED_6X8);switch (game4_state.eCurrentState){case eRunning:B_OLED_ShowString(half, 5 * text_height + 1, "eRunning", B_OLED_6X8);break;case eReady:B_OLED_ShowString(half, 5 * text_height + 1, "eReady", B_OLED_6X8);break;case eBlocked:B_OLED_ShowString(half, 5 * text_height + 1, "eBlocked", B_OLED_6X8);break;case eSuspended:B_OLED_ShowString(half, 5 * text_height + 1, "eSuspended", B_OLED_6X8);break;case eDeleted:B_OLED_ShowString(half, 5 * text_height + 1, "eDeleted", B_OLED_6X8);break;case eInvalid:B_OLED_ShowString(half, 5 * text_height + 1, "eInvalid", B_OLED_6X8);break;default:break;}sprintf(text, "pro:%1d", game4_state.uxBasePriority);B_OLED_ShowString(half, 6 * text_height + 1, text, B_OLED_6X8);// sprintf(text, "stack:%1d", game4_state.usStackHighWaterMark);// B_OLED_ShowString(half, 7 * text_height + 1, text, B_OLED_6X8);B_OLED_Update();}if (get_key_status() == sw1_key_value){B_OLED_Clear();B_OLED_Update();vTaskResume(menuTask_Handler);vTaskSuspend(info_Handler);}else if (get_key_status() == sw2_key_value){B_OLED_Clear();B_OLED_Update();vTaskResume(menuTask_Handler);vTaskDelete(info_Handler);}}}

-----------------------欢迎大家指正交流,有空可以一起讨论代码啊。--------------------------------

通过网盘分享的文件:stm32_FreeRTOS_Game-master.zip
链接: https://pan.baidu.com/s/1UAAb-8cHPl7ZP1pRVyJMAA 提取码: qpgg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/13638.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ONLYOFFICE 文档 8.3 已发布:PDF 图章、合并形状、更多格式支持等

ONLYOFFICE 最新版本的在线编辑器已发布&#xff0c;包含约 30 项新功能和多个错误修复。阅读本文&#xff0c;了解所有更新内容。 关于 ONLYOFFICE 文档 ONLYOFFICE 是一个开源项目&#xff0c;专注于高级和安全的文档处理。坐拥全球超过 1500 万用户&#xff0c;ONLYOFFICE …

第二次连接k8s平台注意事项

第二次重新打开集群平台 1.三台机子要在VMware打开 2.MobaBXterm连接Session 3.三个机子docker重启 systemctl restart docker4.主节点进行平台链接 docker pull kubeoperator/kubepi-server[rootnode1 home]# docker pull kubeoperator/kubepi-server [rootnode1 home]# # 运…

通过多层混合MTL结构提升股票市场预测的准确性,R²最高为0.98

“Boosting the Accuracy of Stock Market Prediction via Multi-Layer Hybrid MTL Structure” 论文地址&#xff1a;https://arxiv.org/pdf/2501.09760 ​​​​​​​ 摘要 本研究引入了一种创新的多层次混合多任务学习架构&#xff0c;致力于提升股市预测的效能。此架构融…

结合深度学习、自然语言处理(NLP)与多准则决策的三阶段技术框架,旨在实现从消费者情感分析到个性化决策

针对电商个性化推荐场景的集成机器学习和稳健优化三阶段方案。 第一阶段:在线评论数据处理&#xff0c;利用深度学习和自然语言处理技术进行特征挖掘&#xff0c;进而进行消费者情感分析&#xff0c;得到消费者偏好 在第一阶段&#xff0c;我们主要关注如何通过深度学习和自然语…

【React】受控组件和非受控组件

目录 受控组件非受控组件基于ref获取DOM元素1、在标签中使用2、在组件中使用 受控组件 表单元素的状态&#xff08;值&#xff09;由 React 组件的 state 完全控制。组件的 state 保存了表单元素的值&#xff0c;并且每次用户输入时&#xff0c;React 通过事件处理程序来更新 …

嵌入式八股文面试题(一)C语言部分

1. 变量/函数的声明和定义的区别&#xff1f; &#xff08;1&#xff09;变量 定义不仅告知编译器变量的类型和名字&#xff0c;还会分配内存空间。 int x 10; // 定义并初始化x int x; //同样是定义 声明只是告诉编译器变量的名字和类型&#xff0c;但并不为它分配内存空间…

【Android】jni开发之导入opencv和libyuv来进行图像处理

做视频图像处理时需要对其进行水印的添加&#xff0c;放在应用层调用工具性能方面不太满意&#xff0c;于是当下采用opencvlibyuv方法进行处理。 对于Android的jni开发不是很懂&#xff0c;我的需求是导入opencv方便在cpp中调用&#xff0c;但目前找到的教程都是把opencv作为模…

HTML应用指南:利用GET请求获取全国盒马门店位置信息

随着新零售业态的发展&#xff0c;门店位置信息的获取变得至关重要。作为新零售领域的先锋&#xff0c;盒马鲜生不仅在商业模式创新上持续领先&#xff0c;还积极构建广泛的门店网络&#xff0c;以支持其不断增长的用户群体。本篇文章&#xff0c;我们将继续探究GET请求的实际应…

20240206 adb 连不上手机解决办法

Step 1: lsusb 确认电脑 usb 端口能识别设备 lsusb不知道设备有没有连上&#xff0c;就插拔一下&#xff0c;对比观察多了/少了哪个设备。 Step 2: 重启 adb server sudo adb kill-serversudo adb start-serveradb devices基本上就可以了&#xff5e; Reference https://b…

【BUUCTF逆向题】[MRCTF2020]Transform

一.[MRCTF2020]Transform 64位无壳&#xff0c;IDA打开发现main函数进入反编译 阅读程序 先输入33位code再加密处理然后验证是否相等的题型 逆向看&#xff0c;验证数组byte_40F0E0已知 再往上看加密处理方式 就是将Str&#xff08;我们输入的flag&#xff09;的每一个索引处…

寒假2.5

题解 web:[网鼎杯 2020 朱雀组]phpweb 打开网址&#xff0c;一直在刷新&#xff0c;并有一段警告 翻译一下 查看源码 每隔五秒钟将会提交一次form1&#xff0c;index.php用post方式提交了两个参数func和p&#xff0c;func的值为date&#xff0c;p的值为Y-m-d h:i:s a 执行fu…

【正点原子K210连载】第六十七章 音频FFT实验 摘自【正点原子】DNK210使用指南-CanMV版指南

第六十七章 音频FFT实验 本章将介绍CanMV下FFT的应用&#xff0c;通过将时域采集到的音频数据通过FFT为频域。通过本章的学习&#xff0c;读者将学习到CanMV下控制FFT加速器进行FFT的使用。 本章分为如下几个小节&#xff1a; 32.1 maix.FFT模块介绍 32.2 硬件设计 32.3 程序设…

【Prometheus】如何通过golang生成prometheus格式数据

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

从零开始:OpenCV 图像处理快速入门教程

文章大纲 第1章 OpenCV 概述 1.1 OpenCV的模块与功能  1.2 OpenCV的发展 1.3 OpenCV的应用 第2章 基本数据类型 2.1 cv::Vec类 2.2 cv&#xff1a;&#xff1a;Point类 2.3 cv&#xff1a;&#xff1a;Rng类 2.4 cv&#xff1a;&#xff1a;Size类 2.5 cv&#xff1a;&…

Vim跳转文件及文件行结束符EOL

跳转文件 gf 从当前窗口打开那个文件的内容&#xff0c;操作方式&#xff1a;让光标停在文件名上&#xff0c;输入gf。 Ctrlo 从打开的文件返回之前的窗口 Ctrlwf 可以在分割的窗口打开跳转的文件&#xff0c;不过在我的实验不是次次都成功。 统一行尾格式 文本文件里存放的…

MLA 架构

注&#xff1a;本文为 “MLA 架构” 相关文章合辑。 未整理去重。 DeepSeek 的 MLA 架构 原创 老彭坚持 产品经理修炼之道 2025 年 01 月 28 日 10:15 江西 DeepSeek 的 MLA&#xff08;Multi-head Latent Attention&#xff0c;多头潜在注意力&#xff09;架构 是一种优化…

变压器-000000

最近一个项目是木田12V的充电器&#xff0c;要设计变压器&#xff0c;输出是12V,电压大于1.5A12.6*1.518.9W. 也就是可以将变压器当成初级输入的一个负载。输入端18.9W. 那么功率UI 。因为变压器的输入是线性上升的&#xff0c;所以电压为二份之一&#xff0c;也就是1/2*功率…

【DeepSeek】私有化本地部署图文(Win+Mac)

目录 一、DeepSeek本地部署【Windows】 1、安装Ollama 2、配置环境变量 3、下载模型 4、使用示例 a、直接访问 b、chatbox网页访问 二、DeepSeek本地部署【Mac】 1、安装Ollama 2、配置环境变量 3、下载模型 4、使用示例 5、删除已下载的模型 三、DeepSeek其他 …

02vue3实战-----项目目录详解

02vue3实战-----项目目录详解 1.目录完整结构2.extensions.json文件3.node_modules文件夹4.public文件夹5.src文件夹6.文件.gitignore7.文件env.d.ts8.文件index.html9.文件package-lock.json和文件package.json10.文件README.md11.文件vite.config.ts12.文件tsconfig.json和文…

ubuntu20.04+RTX4060Ti大模型环境安装

装显卡驱动 这里是重点&#xff0c;因为我是跑深度学习的&#xff0c;要用CUDA&#xff0c;所以必须得装官方的驱动&#xff0c;Ubuntu的附件驱动可能不太行. 进入官网https://www.nvidia.cn/geforce/drivers/&#xff0c;选择类型&#xff0c;最新版本下载。 挨个运行&#…