# OLED多级菜单设计 **Repository Path**: fengdaokanhai/oled-multi-level-menu-design ## Basic Information - **Project Name**: OLED多级菜单设计 - **Description**: OLED多级菜单设计学习 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 2 - **Created**: 2024-01-20 - **Last Updated**: 2024-01-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 采用0.96寸OLED(128*64)进行测试,x:0-127,y:0-63 #### 基本思路 1. 首先定义一个菜单列表 2. 然后定义一个让菜单移动的函数ui_run(),主要是控制y的坐标实现纵向移动 3. 根据移动状态(是否到达目标位置,status=0,到达目标位置,status=1未到达目标位置),采用case语句进行判断,重新给y_trg和status进行赋值 4. 按键采用上拉输入模式 按键控制思路 1. 按键状态初始化 2. 按键扫描:判断按键是否按下,按下时设定对应的目标移动值y_trg 3. 根据y_trg,设置 u8g2.drawStr(x, y + i * 13, list[i].str); 4. 最后 ui_run(&y, &y_trg); #### 字符滚动效果 ```c++ void loop(void) { /*循环输出字符,同时输出两端字符,x轴不断改变实现移动。 * 第一段移动范围0-----128-----256 * 第二段移动范围-128-----0------128 */ int y = 1; // 调节位移速度,可用于加快字符位移速度 for (int x = 0; x < 256; x += y) { // x+=y ----->等价于x=x+y u8g2.clearBuffer(); // 清除内部缓冲区 u8g2.setFont(u8g2_font_ncenB08_tr); // 设置字体 u8g2.drawStr(x, 10, "Hello World!"); // 第一段输出位置 u8g2.drawStr(x - 128, 10, "Hello World!"); // 第二段输出位置 delay(20); // 延时程序,可以降低位移速度 u8g2.sendBuffer(); } } ``` #### ui移动函数 ```c++ /* a:当前位置 a_trg:目标位置 step:速度1,加速到达目标值 slow_cnt:速度2:减小震荡 */ int ui_run(short *a,short *a_trg,byte step,byte slow_cnt) { byte temp; temp = abs(*a_trg-*a) > slow_cnt ? step : 1; // 速度控制 if(*a < *a_trg) { *a += temp; } else if( *a > *a_trg) { *a -= temp; } else { return 0; } return 1; } ``` #### 按键扫描 ```c++ void key_scan() { for (int i = 0; i < 2; i++) { key[i].val = get_io_val(i); // 读取按键状态 if (key[i].val != key[i].last_val) { key[i].last_val = key[i].val; if (key[i].val == 0) { // 按键被按下 key_msg.id = i; key_msg.press = 1; // 按键按下 key_msg.update_flag = 1; // 更新标志 } } } } ``` #### ui显示 ```c++ void ui_proc(void) { int list_len = sizeof(list) / sizeof(SETTING_LIST); if(key_msg.update_flag && key_msg.press) { key_msg.update_flag = 0; if(key_msg.id) { ui_select++; if(ui_select >= list_len) { ui_select = list_len-1 ; } } else { ui_select--; if(ui_select < 0) { ui_select = 0; } } frame_y_trg = ui_select*20; // 根据字符的高度计算目标位置 frame_len_trg = list[ui_select].len*13; } ui_show(); } void ui_show(void) { int list_len = sizeof(list) / sizeof(SETTING_LIST); u8g2.clearBuffer(); for(int i = 0 ;i < list_len;i++) { u8g2.drawStr(x+2,y+i*20,list[i].str); } u8g2.drawRFrame(x,frame_y,frame_len,22,3); ui_run(&frame_y,&frame_y_trg,5,4); ui_run(&frame_len,&frame_len_trg,10,5); u8g2.sendBuffer(); } ```