【目的】移植多级菜单以及贪吃蛇游戏
【实验硬件】
1、【灵动 Mini-F5333开发板】
2、旋转编码器
3、OLED屏
【开发环境】
1、MDK5.38
2、TobudOS
【步骤】
1、下载多级菜单的源码,这是我在B站上学习到的,具体是哪位,如果大佬看到请联系我一下下。
2、复制我的TobudOS工程源码:https://mbb.eet-china.com/forum/topic/139033_1_1.html
3、加载源码的key、encoder、oled到工程里,把头文件更换成mm32的头文件,添加进工作组:
![image.png image.png](data/attachment/forum/202401/12/155916w6jirnbdui22922v.png)
4、按照OLED驱动的帖子,修改驱动:【灵动 Mini-F5333开发板】硬件I2C高速驱动OLED屏_嵌入式系统与MCU
具体的数据发送与命令发送代码如下:
/**
* 函 数:OLED写命令
* 参 数:Command 要写入的命令值,范围:0x00~0xFF
* 返 回 值:无
*/
void OLED_WriteCommand(uint8_t Command)
{
uint8_t dat;
dat = Command;
I2C_SendData(I2C2, 0x00);
while (RESET == I2C_GetFlagStatus(I2C2, I2C_STATUS_FLAG_TFE))
{
}
I2C_SendData(I2C2, dat);
while (RESET == I2C_GetFlagStatus(I2C2, I2C_STATUS_FLAG_TFE))
{
}
I2C_GenerateSTOP(I2C2, ENABLE);
while (RESET == I2C_GetFlagStatus(I2C2, I2C_STATUS_FLAG_TFE))
{
}
}
/**
* 函 数:OLED写数据
* 参 数:Data 要写入数据的起始地址
* 参 数:Count 要写入数据的数量
* 返 回 值:无
*/
void OLED_WriteData(uint8_t *Data, uint8_t Count)
{
uint16_t i;
I2C_SendData(I2C2, 0x40);
while (RESET == I2C_GetFlagStatus(I2C2, I2C_STATUS_FLAG_TFE))
{
}
for(int i =0; i < Count; i++)
{
I2C_SendData(I2C2, Data[i]);
while (RESET == I2C_GetFlagStatus(I2C2, I2C_STATUS_FLAG_TFE))
{
}
}
I2C_GenerateSTOP(I2C2, ENABLE);
while (RESET == I2C_GetFlagStatus(I2C2, I2C_STATUS_FLAG_TFE))
{
}
}
复制代码代码如下:
#include <stdio.h>
#include "platform.h"
#include "hal_tim.h"
void Encoder_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
TIM_ICInitTypeDef TIM_ICInitStruct;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
/* TIM1 */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_1); /* TIM1_CH1 */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1); /* TIM1_CH2 */
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStruct);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct);
TIM_TimeBaseInitStruct.TIM_Prescaler = 0;
TIM_TimeBaseInitStruct.TIM_Period = UINT16_MAX;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStruct);
// TIM_EncoderInterfaceConfig(TIM1, TIM_EncoderMode_TI1, TIM_ICPolarity_Falling, TIM_ICPolarity_Falling);
// TIM_EncoderInterfaceConfig(TIM1, TIM_EncoderMode_TI2, TIM_ICPolarity_Falling, TIM_ICPolarity_Falling);
TIM_EncoderInterfaceConfig(TIM1, TIM_EncoderMode_TI12, TIM_ICPolarity_Falling, TIM_ICPolarity_Falling);
TIM_ICStructInit(&TIM_ICInitStruct);
TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;
TIM_ICInitStruct.TIM_ICFilter = 6;
TIM_ICInit(TIM1, &TIM_ICInitStruct);
TIM_SetCounter(TIM1, 0);
TIM_Cmd(TIM1, ENABLE);
}
int16_t Encoder_Get(void)
{
/*除以4输出*/
int16_t temp;
temp = (TIM_GetCounter(TIM1)+2)/4;
if(temp)
{
TIM_SetCounter(TIM1, TIM_GetCounter(TIM1)-(temp*4));
return temp;
}
return 0;
}
void Encoder_Reset(void)
{
TIM_SetCounter(TIM1, 0);
}
复制代码uint8_t Key_Enter; //确认键
void Key_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
/* K1->PC4 */
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOC, &GPIO_InitStruct);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource4);
EXTI_StructInit(&EXTI_InitStruct);
EXTI_InitStruct.EXTI_Line = EXTI_Line4;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = EXTI4_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 5;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
/********************************************/
int8_t Key_Enter_Get(void)
{
if(Key_Enter)
{
Key_Enter = 0;
return 1;
}
return 0;
}
/***********************************************************************************************************************
* @brief This function handles EXTI4 Handler
* @note none
* @param none
* @retval none
*********************************************************************************************************************/
void EXTI4_IRQHandler(void)
{
/* K1 */
if (SET == EXTI_GetITStatus(EXTI_Line4))
{
Key_Enter += 1;
EXTI_ClearITPendingBit(EXTI_Line4);
}
}
复制代码void test_task(void *Parameter)
{
OLED_Init();
Encoder_Init();
Key_Init();
main_menu();
while(1)
{
OLED_ShowImage(0, 0, 128, 64, Wallpaper);
OLED_Update();
if(Key_Enter_Get())
{
main_menu();
}
}
}
复制代码![](static/image/filetype/zip.gif)
全部回复 0