本帖最后由 lulugl 于 2024-1-12 16:14 编辑

【目的】移植多级菜单以及贪吃蛇游戏
【实验硬件】
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
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))
  •         {
  •         }
  • }
  • 复制代码
    5、按照我的帖子旋转编码器的帖子,移植好编码器的代码:【灵动 Mini-F5333开发板】体验旋转统码器
    代码如下:
    #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);
  • }

  • 复制代码
    6、按建的驱动,根据官方示例exti中断示例,这里选用Key1。修改代码如下:
    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);
  •     }
  • }

  • 复制代码
    7、复制Game文夹进行,最后在任务中运行菜单项就可以下载代码了
    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();
  •                 }
  •         }
  • }
  • 复制代码
    附源码如下:
    MM32F5330_template.zip (1.18 MB, 下载次数: 11)
    全部回复 0
    暂无评论,快来抢沙发吧