#include <U8g2lib.h>
#include <Wire.h>
#include <math.h>
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);//该驱动是1.3寸的OLED屏幕。---------U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);这是比较常用的0.9寸的OLED显示器的驱动
short x,x_trg; //x当前位置数值,x_trg 目标坐标值
short y=18,y_trg =18;
short frame_len,frame_len_trg;//框框的参数
short frame_y,frame_y_trg;
short frame_r = 2;
char ui_select = 0;//选择的列表
typedef struct //按键的变量
{
byte val; //当前值
byte last_val; //上次的值
}KEY_T;
typedef struct //按键消息
{
byte id;
byte press;//按
byte update_flag;//是否最新的
byte res;
}KEY_MSG;
KEY_MSG key_msg= {0};
KEY_T key[2] ={0};//两个按键
byte get_io_val(byte ch)//键按扫描
{
if(ch==0)
{
return digitalRead(2);
}
else
{
return digitalRead(3);
}
}
void key_init(void)//按键初始化,因为模拟就不去抖了
{
for(int i =0;i<2;i++)//把按键状态放到buff里面
{
key[i].val = key[i].last_val=get_io_val(i);
}
}
void key_scan(void)//按键扫描
{
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;
}
}
}
}
typedef struct
{
char* str;
byte len;//标题长度
}SETTING_LIST;
SETTING_LIST list[] =
{
{"list",4},
{"a123",4},
{"ab",2},
};
int ui_run(short *a,short *a_trg ,u8 step, u8 slow_cnt)
{
u8 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;
}
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+1,y+i*20,list[i].str); // 第一段输出位置
}
ui_run(&frame_y,&frame_y_trg,8,9);
ui_run(&frame_len,&frame_len_trg,10,11);
u8g2.drawRFrame(x,frame_y , frame_len ,22, frame_r);
u8g2.sendBuffer(); // transfer internal memory to the displa
}
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)
{
if(ui_select < list_len - 1 )//限位
{
ui_select ++;
frame_y_trg += 20;
}
}
else
{
if(ui_select > 0 )//限位
{
ui_select--;
frame_y_trg -=20;
}
}
frame_len_trg = list[ui_select].len*13;
}
ui_show();
}
void setup(void)
{
pinMode(2, INPUT_PULLUP);//按钮上拉
pinMode(3, INPUT_PULLUP);
key_init();//初始化按钮状态
u8g2.begin();
u8g2.setFont(u8g2_font_t0_22_mf); //设置字体
x_trg = 10;
//初始化选中目标
frame_len = frame_len_trg = list[ui_select].len*13;
}
void loop(void)
{
key_scan();
ui_proc();
}