先上一个效果视频
基于stm32的OLED界面设计
【写在前面】
个人提供的一种简易二级界面搭建思路,如果要搭建复杂界面建议采用结构体封装状态变量的方法。需要源码的小伙伴可以下载:https://download.csdn.net/download/hdu_master/87611127
【硬件需求】
1.处理器:STM32F407
2.0.96寸OLED显示屏(IIC/SPI/8086皆可)
3.至少四个外部按键
按键 | 功能 |
---|---|
KEY1 | 实现光标下移 |
KEY2 | 实现光标复位 |
KEY3 | 确认键跳转至下一级界面 |
KEY4 | 返回至上一级界面 |
【软件思路】
上电显示菜单界面,光标停留在初始位置。在外部中断中更改显示的状态变量。
绘制箭头光标
/**
* @brief 向缓存中写入光标数据
* @param 光标左顶点的坐标
* @retval 无
* @attention 没有马上显示
*/
void Show_Arrow(u8 x,u8 y)
{
OLED_DrawLine(x,y,x+8,y);
OLED_DrawPoint(x+1,y-1);
OLED_DrawPoint(x+1,y+1);
OLED_DrawPoint(x+2,y-2);
OLED_DrawPoint(x+2,y+2);
}
光标动态移位
/**
* @brief 根据选择变量显示光标
* @param 当前的选择变量
* @retval 无
* @attention 没有马上显示
*/
void Show_SIGN(int choose)
{
switch(choose)
{
case 1:
Show_Arrow(100,25);
break;
case 2:
Show_Arrow(100,40);
break;
case 3:
Show_Arrow(100,55);
break;
default:break;
}
}
菜单显示
/**
* @brief 显示当前状态的菜单
* @param 无
* @retval 无
* @attention 立即生效显示
*/
void Show_MENU(void)
{
OLED_Clear_BUT();
/*第一行居中显示*/
//OLED_DrawLine(0,0,40,0);
OLED_ShowString(47,0,"MENU",16);
OLED_DrawLine(0,14,127,14);
OLED_DrawLine(0,15,127,15);
/*第二行靠左显示模式1*/
OLED_ShowString(0,18,"1.Mode-one",12);
OLED_ShowString(0,33,"2.Mode-two",12);
OLED_ShowString(0,48,"3.Mode-three",12);
/*显示箭头*/
Show_SIGN(CHOOSE_STATE);
OLED_Refresh();
}
GUI显示
/**
* @brief 显示当前界面
* @param 无
* @retval 无
* @attention 立即生效显示
*/
void Show_GUI(void)
{
if(MENU_FLAG)
{
Show_MENU();
}
if(CONFIRM_FLAG)
{
OLED_Clear_BUT();
switch(CHOOSE_STATE)
{
case 1:
OLED_ShowString(35,20,"Mode-one",16);
break;
case 2:
OLED_ShowString(35,20,"Mode-two",16);
break;
case 3:
OLED_ShowString(30,20,"Mode-three",16);
break;
default:break;
}
OLED_Refresh();
}
}
KEY1外部中断
void KEY1_IRQHandler(void)
{
//确保是否产生了EXTI Line中断
if(EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET)
{
CHOOSE_STATE++;
if(CHOOSE_STATE>3){
CHOOSE_STATE=3;
}
//当松手时读到高电平退出while循环
while(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_1)==0);
//清除中断标志位
EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE);
}
}
KEY2外部中断
//复位选择键
void KEY2_IRQHandler(void)
{
//确保是否产生了EXTI Line中断
if(EXTI_GetITStatus(KEY2_INT_EXTI_LINE) != RESET)
{
CHOOSE_STATE=1;
while(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_2)==0);
EXTI_ClearITPendingBit(KEY2_INT_EXTI_LINE);
}
}
KEY3外部中断
void KEY3_IRQHandler(void)
{
//确保是否产生了EXTI Line中断
if(EXTI_GetITStatus(KEY3_INT_EXTI_LINE) != RESET)
{
MENU_FLAG = 0;
CONFIRM_FLAG = 1;
LED1_TOGGLE;
while(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_3)==0);
EXTI_ClearITPendingBit(KEY3_INT_EXTI_LINE);
}
}
KEY4外部中断
void KEY4_IRQHandler(void)
{
//确保是否产生了EXTI Line中断
if(EXTI_GetITStatus(KEY4_INT_EXTI_LINE) != RESET)
{
MENU_FLAG = 1;
CONFIRM_FLAG = 0;
while(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_4)==0);
EXTI_ClearITPendingBit(KEY4_INT_EXTI_LINE);
}
}