打印
[应用相关]

在STM32上使用HAL库和SSD1306 OLED显示屏实现菜单功能

[复制链接]
271|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
小明的同学|  楼主 | 2023-4-26 20:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
注意,这里的代码使用了HAL库和STM32CubeMX代码生成器来初始化STM32芯片和I2C总线,以及SSD1306 OLED显示屏的硬件配置。确保正确配置了I2C总线和SSD1306 OLED屏幕,然后将以下代码添加到main.c文件中即可。
#include "main.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include "ssd1306.h"

#define OLED_RESET_PIN GPIO_PIN_15
#define OLED_RESET_PORT GPIOA
#define OLED_I2C_PORT hi2c1

SSD1306 display(&hi2c1, OLED_RESET_PORT, OLED_RESET_PIN);

// 菜单节点
struct MenuItem
{
  const char* name;  // 节点名称
  MenuItem* next;    // 下一个节点的指针
  void (*function)();  // 节点功能函数的指针
};

// 菜单类
class Menu
{
public:
  Menu();
  void AddItem(const char* name, void (*function)());
  void Run();

private:
  MenuItem* mHead;
};

// 菜单构造函数
Menu::Menu()
  : mHead(nullptr)
{
}

// 添加菜单节点
void Menu::AddItem(const char* name, void (*function)())
{
  MenuItem* item = new MenuItem;
  item->name = name;
  item->function = function;
  item->next = mHead;
  mHead = item;
}

// 运行菜单系统
void Menu::Run()
{
  display.clear();

  MenuItem* current = mHead;
  char input[32];

  // 遍历链表,打印菜单选项
  int y = 0;
  while (current != nullptr)
  {
    display.setCursor(0, y);
    display.println(current->name);
    y += 10;
    current = current->next;
  }
  display.display();

  // 等待用户输入选择
  HAL_UART_Transmit(&huart2, (uint8_t*)"Enter your choice: ", strlen("Enter your choice: "), HAL_MAX_DELAY);
  HAL_UART_Receive(&huart2, (uint8_t*)input, sizeof(input), HAL_MAX_DELAY);
  input[strcspn(input, "\r\n")] = 0;  // 去除输入末尾的回车符

  // 查找用户输入对应的菜单节点,并执行功能函数
  current = mHead;
  while (current != nullptr)
  {
    if (strcmp(current->name, input) == 0)
    {
      current->function();
      return;
    }
    current = current->next;
  }

  HAL_UART_Transmit(&huart2, (uint8_t*)"Invalid choice.\r\n", strlen("Invalid choice.\r\n"), HAL_MAX_DELAY);
}

// 菜单功能函数1
void Function1()
{
  HAL_UART_Transmit(&huart2, (uint8_t*)"Function 1 executed.\r\n", strlen("Function 1 executed.\r\n"), HAL_MAX_DELAY);
}

// 菜单功能函数2
void Function2()
{
  HAL_UART_Transmit(&huart2, (uint8_t*)"Function 2 executed.\r\n", strlen("Function 2 executed.\r\n"), HAL_MAX_DELAY);
}

int main()
{
  // 初始化硬件和HAL库
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_USART2_UART_Init();

  // 初始化OLED显示屏
  display.init();
  display.setFont(ArialMT_Plain_10);

  // 创建菜单对象,添加菜单选项
  Menu menu;
menu.AddItem("Option 1", Function1);
menu.AddItem("Option 2", Function2);

// 循环执行菜单
while (1)
{
menu.Run();
}
}


使用特权

评论回复
沙发
小明的同学|  楼主 | 2023-4-26 20:21 | 只看该作者
请注意,这里使用了OLED显示屏,需要先初始化并使用SSD1306库进行控制。此外,为了使用串口进行输入输出,还需要初始化并使用USART2库。其他部分与前面给出的示例代码相同。

使用特权

评论回复
板凳
zwsam| | 2024-1-21 09:16 | 只看该作者

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

121

主题

1358

帖子

2

粉丝