本帖最后由 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
具体的数据发送与命令发送代码如下:
  1. /**
  2.   * 函    数:OLED写命令
  3.   * 参    数:Command 要写入的命令值,范围:0x00~0xFF
  4.   * 返 回 值:无
  5.   */
  6. void OLED_WriteCommand(uint8_t Command)
  7. {
  8.         uint8_t dat;
  9.         dat = Command;
  10.         I2C_SendData(I2C2, 0x00);

  11.         while (RESET == I2C_GetFlagStatus(I2C2, I2C_STATUS_FLAG_TFE))
  12.         {
  13.         }
  14.         
  15.         I2C_SendData(I2C2, dat);

  16.         while (RESET == I2C_GetFlagStatus(I2C2, I2C_STATUS_FLAG_TFE))
  17.         {
  18.         }
  19.         I2C_GenerateSTOP(I2C2, ENABLE);

  20.         while (RESET == I2C_GetFlagStatus(I2C2, I2C_STATUS_FLAG_TFE))
  21.         {
  22.         }
  23. }

  24. /**
  25.   * 函    数:OLED写数据
  26.   * 参    数:Data 要写入数据的起始地址
  27.   * 参    数:Count 要写入数据的数量
  28.   * 返 回 值:无
  29.   */
  30. void OLED_WriteData(uint8_t *Data, uint8_t Count)
  31. {
  32.          uint16_t i;

  33.         I2C_SendData(I2C2, 0x40);

  34.         while (RESET == I2C_GetFlagStatus(I2C2, I2C_STATUS_FLAG_TFE))
  35.         {
  36.         }
  37.         for(int i =0; i < Count; i++)
  38.         {
  39.                 I2C_SendData(I2C2, Data[i]);

  40.                 while (RESET == I2C_GetFlagStatus(I2C2, I2C_STATUS_FLAG_TFE))
  41.                 {
  42.                 }
  43.         }

  44.         I2C_GenerateSTOP(I2C2, ENABLE);

  45.         while (RESET == I2C_GetFlagStatus(I2C2, I2C_STATUS_FLAG_TFE))
  46.         {
  47.         }
  48. }
5、按照我的帖子旋转编码器的帖子,移植好编码器的代码:【灵动 Mini-F5333开发板】体验旋转统码器
代码如下:
  1. #include <stdio.h>
  2. #include "platform.h"
  3. #include "hal_tim.h"

  4. void Encoder_Init(void)
  5. {
  6.     GPIO_InitTypeDef        GPIO_InitStruct;
  7.     TIM_ICInitTypeDef       TIM_ICInitStruct;
  8.     TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;

  9.     /* TIM1 */
  10.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

  11.     GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_1);   /* TIM1_CH1 */
  12.     GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);   /* TIM1_CH2 */

  13.     GPIO_StructInit(&GPIO_InitStruct);
  14.     GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_8 | GPIO_Pin_9;
  15.     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
  16.     GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_IPU;
  17.     GPIO_Init(GPIOA, &GPIO_InitStruct);

  18.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

  19.     TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct);
  20.     TIM_TimeBaseInitStruct.TIM_Prescaler = 0;
  21.     TIM_TimeBaseInitStruct.TIM_Period    = UINT16_MAX;
  22.                 TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
  23.     TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStruct);

  24. //    TIM_EncoderInterfaceConfig(TIM1, TIM_EncoderMode_TI1, TIM_ICPolarity_Falling, TIM_ICPolarity_Falling);
  25. //    TIM_EncoderInterfaceConfig(TIM1, TIM_EncoderMode_TI2, TIM_ICPolarity_Falling, TIM_ICPolarity_Falling);
  26.     TIM_EncoderInterfaceConfig(TIM1, TIM_EncoderMode_TI12, TIM_ICPolarity_Falling, TIM_ICPolarity_Falling);

  27.     TIM_ICStructInit(&TIM_ICInitStruct);
  28.     TIM_ICInitStruct.TIM_Channel  = TIM_Channel_1;
  29.     TIM_ICInitStruct.TIM_ICFilter = 6;
  30.     TIM_ICInit(TIM1, &TIM_ICInitStruct);

  31.     TIM_SetCounter(TIM1, 0);
  32.     TIM_Cmd(TIM1, ENABLE);

  33. }

  34. int16_t Encoder_Get(void)
  35. {
  36.         
  37.         /*除以4输出*/
  38.         int16_t temp;
  39.         temp = (TIM_GetCounter(TIM1)+2)/4;
  40.         if(temp)
  41.         {
  42.                 TIM_SetCounter(TIM1, TIM_GetCounter(TIM1)-(temp*4));
  43.                 return temp;
  44.         }
  45.         return 0;
  46. }

  47. void Encoder_Reset(void)
  48. {
  49.         TIM_SetCounter(TIM1, 0);
  50. }

6、按建的驱动,根据官方示例exti中断示例,这里选用Key1。修改代码如下:
  1. uint8_t Key_Enter;        //确认键

  2. void Key_Init(void)
  3. {
  4.         GPIO_InitTypeDef GPIO_InitStruct;
  5.         EXTI_InitTypeDef EXTI_InitStruct;
  6.         NVIC_InitTypeDef NVIC_InitStruct;
  7.         RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
  8.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

  9.         /* K1->PC4 */
  10.     GPIO_StructInit(&GPIO_InitStruct);
  11.     GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_4;
  12.     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;
  13.     GPIO_Init(GPIOC, &GPIO_InitStruct);

  14.         SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource4);

  15.     EXTI_StructInit(&EXTI_InitStruct);
  16.     EXTI_InitStruct.EXTI_Line    = EXTI_Line4;
  17.     EXTI_InitStruct.EXTI_Mode    = EXTI_Mode_Interrupt;
  18.     EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
  19.     EXTI_InitStruct.EXTI_LineCmd = ENABLE;
  20.     EXTI_Init(&EXTI_InitStruct);

  21.         NVIC_InitStruct.NVIC_IRQChannel = EXTI4_IRQn;
  22.     NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 5;
  23.     NVIC_InitStruct.NVIC_IRQChannelSubPriority = 5;
  24.     NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
  25.     NVIC_Init(&NVIC_InitStruct);
  26. }

  27. /********************************************/

  28. int8_t Key_Enter_Get(void)
  29. {
  30.         if(Key_Enter)
  31.         {
  32.                 Key_Enter = 0;
  33.                 return 1;
  34.         }
  35.         return 0;
  36. }


  37. /***********************************************************************************************************************
  38.   * @brief  This function handles EXTI4 Handler
  39.   * @note   none
  40.   * @param  none
  41.   * @retval none
  42.   *********************************************************************************************************************/
  43. void EXTI4_IRQHandler(void)
  44. {
  45.     /* K1 */
  46.     if (SET == EXTI_GetITStatus(EXTI_Line4))
  47.     {
  48.         Key_Enter += 1;

  49.         EXTI_ClearITPendingBit(EXTI_Line4);
  50.     }
  51. }

7、复制Game文夹进行,最后在任务中运行菜单项就可以下载代码了
  1. void test_task(void *Parameter)
  2. {
  3.         OLED_Init();
  4.         Encoder_Init();
  5.         Key_Init();
  6.         
  7.         main_menu();
  8.         while(1)
  9.         {
  10.                 OLED_ShowImage(0, 0, 128, 64, Wallpaper);
  11.                 OLED_Update();
  12.                
  13.                 if(Key_Enter_Get())
  14.                 {
  15.                         main_menu();
  16.                 }
  17.         }
  18. }
附源码如下:
MM32F5330_template.zip (1.18 MB, 下载次数: 11)
全部回复 0
暂无评论,快来抢沙发吧