//字库放在这里面,中文用多少生成多少#include "codetab.h"
//PB6 -- SCL; PB7 -- SDA */
#include "delay.h"
#include "stm32f10x.h"
#include "OLED_I2C.h"
#include "exti.h"
#include "stdio.h"
#include "key.h"
#include "stmflash.h"
#define FLASH_SAVE_ADDR 0X08009000 //设置FLASH 保存地址(必须为偶数,且其值要大于本代码所占用FLASH的大小+0X08000000)
//C8T6和CBT6(仅FLASH容量有区别)一般是在同一生产线生产的,
//如果CBT6的FLASH容量部分不能使用那么就作为C8T6
//36864= 0X9 000
//64K=0X10 000
#define linenumber 4
struct MenuItem
{
short MenuCount;//当前菜单项目总数
u8 *DisplayString;//当前项目要显示的字符
void(*Subs)();//选择某一菜单后执行的功能函数
struct MenuItem *ChildrenMenus;//当前项目的子菜单
struct MenuItem *ParentMenus;//当前项目的父菜单
};
struct mydata
{
float length1;
float length2;
float angle;
};
struct mydata rmydata;
int selectItem_current,selectItem_hidden,selectItem;
int key_num=0;
int juli,jiaodu;
void caidan(void);
int key_scan(void);//是否按下确认键
void display(struct MenuItem * MenuPoint,int selectItem_current,int selectItem_hidden);
void caidan_init(void);
void fun1(void);
void fun2(void);
void fun3(void);
void fun4(void);
void fun5(void);
void fun6(void);
int main(void)
{
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
I2C_Configuration();
OLED_Init();
OLED_CLS();
KEY_Init();
caidan_init();
//fun2();//第一次下载需要去掉fun2()前面的注释,不然程序直接卡死
STMFLASH_Read(FLASH_SAVE_ADDR,(u16*)&rmydata,sizeof(rmydata));
while(1)
{
key_num=KEY_Scan();
caidan();
delay_ms(20);
}
}
int my_min(int a,int b)
{
if (a<b)return a;
return b;
}
//由于定义从上往下,数组定义时子类都为NULL
//第一级
struct MenuItem MainMenu[] = {
{ 8,(u8 *)"第一",NULL,NULL,NULL },
{ 6,(u8 *)"第二",NULL,NULL,NULL },
{ 6,(u8 *)"第三",NULL,NULL,NULL },
{ 6,(u8 *)"第四",NULL,NULL,NULL },
{ 6,(u8 *)"第五",NULL,NULL,NULL },
{ 6,(u8 *)"第六",NULL,NULL,NULL },
{ 6,(u8 *)"参数初始化",fun2,NULL,NULL },
{ 6,(u8 *)"读取参数并显示",fun3,NULL,NULL }
};
//第二级
struct MenuItem Setmenu1[2]={
{ 2,(u8 *)"返回上一级",NULL,NULL,MainMenu },
{ 2,(u8 *)"确定",NULL,NULL,MainMenu },
};
struct MenuItem Setmenu2[] = {
{ 4,(u8 *)"返回上一级",NULL,NULL,MainMenu },
{ 3,(u8 *)"读取参数",fun3,NULL,MainMenu },
{ 3,(u8 *)"设定长度",fun4,NULL,MainMenu },
{ 3,(u8 *)"确定",fun1,NULL,MainMenu } };
struct MenuItem Setmenu3[] = {
{ 4,(u8 *)"返回上一级",NULL,NULL,MainMenu },
{ 3,(u8 *)"设定长度",fun5,NULL,MainMenu },
{ 3,(u8 *)"设定角度",fun6,NULL,MainMenu },
{ 3,(u8 *)"确定",NULL,NULL,MainMenu } };
struct MenuItem* MenuPoint=MainMenu;//当前菜单
void caidan_init(void)
{
MainMenu[0].ChildrenMenus = Setmenu1;
MainMenu[1].ChildrenMenus = Setmenu2;
MainMenu[2].ChildrenMenus = Setmenu3;
selectItem_current =1;
selectItem_hidden =0;
selectItem=selectItem_current+selectItem_hidden;
display(MenuPoint,selectItem_current,selectItem_hidden);
}
void display(struct MenuItem * MenuPoint,int selectItem_current,int selectItem_hidden)
{
int j;
u16 x=16;
u16 y=0;
OLED_Show(0,selectItem_current*2-2,(u8 *)"->");
for ( j= selectItem_hidden; j < my_min(MenuPoint->MenuCount,linenumber+selectItem_hidden);j++)
{
OLED_Show(x,y,MenuPoint[j].DisplayString);
y+=2;
}
}
void caidan(void)
{
if(key_num>0)
switch(key_num)
{
case WKUP_PRES:
{//上
OLED_CLS();
selectItem_current--;
if (selectItem_current==0)
{
if(selectItem_hidden>0)selectItem_hidden--;
selectItem_current++;
}
selectItem=selectItem_current+selectItem_hidden;
display(MenuPoint,selectItem_current,selectItem_hidden);
};break;
case KEY1_PRES:
{//下
OLED_CLS();
selectItem_current++;
if(selectItem_current>linenumber)//当前的行数超过总行数
{
if (selectItem_current+selectItem_hidden <= MenuPoint->MenuCount)
selectItem_hidden++;
selectItem_current--;
}
else if(selectItem_current>MenuPoint->MenuCount)selectItem_current--;
selectItem=selectItem_current+selectItem_hidden;
display(MenuPoint,selectItem_current,selectItem_hidden);
};break;
case KEY0_PRES:
{//右 确认进入此项目
if(selectItem== 1&&MenuPoint!=MainMenu)//满足退回上一级条件
{
OLED_CLS();
MenuPoint = MenuPoint[selectItem - 1].ParentMenus;
selectItem_current =1;
selectItem_hidden =0;
//selectItem = 1;
display(MenuPoint,selectItem_current,selectItem_hidden);
}
else if (MenuPoint[selectItem - 1].ChildrenMenus != NULL)//判断是否有下一级
{
OLED_CLS();
MenuPoint = MenuPoint[selectItem - 1].ChildrenMenus;
selectItem_current =1;
selectItem_hidden =0;
display(MenuPoint,selectItem_current,selectItem_hidden);
}
else if(MenuPoint[selectItem - 1].Subs != NULL)
MenuPoint[selectItem - 1].Subs();//功能函数执行
};break;
}
}
void fun1()
{
OLED_Show(16,0,(u8*)"fun1");
}
void fun2()//初始化参数
{
rmydata.length1=1.23;
rmydata.length2=2.34;
rmydata.angle=10.2;
STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)&rmydata,sizeof(rmydata));
}
void fun3()//读取并显示
{
u8 key;
char str[10];
OLED_CLS();
STMFLASH_Read(FLASH_SAVE_ADDR,(u16*)&rmydata,sizeof(rmydata));
sprintf(str,"长度1:%.2f",(float)rmydata.length1);
OLED_Show(16,0,(u8*)str);
sprintf((char*)str,"长度2:%.2f",(float)rmydata.length2);
OLED_Show(16,2,(u8*)str);
sprintf((char*)str,"角度:%.2f",(float)rmydata.angle);
OLED_Show(16,4,(u8*)str);
while(1)
{
key=KEY_Scan();
delay_ms(20);
if(key!=0)
{
OLED_CLS();
display(MenuPoint,selectItem_current,selectItem_hidden);
return;
}
}
}
void fun4()
{
char str[10];
u8 lengthwei[3],wei=2,jieshu=0;//0 个位 ,1小数点后1位 2小数点后2位
int current_length;
u8 i,key;
int time=0;
current_length=rmydata.length1*100;
lengthwei[0]=current_length/100;
lengthwei[1]=current_length%100/10;
lengthwei[2]=current_length%10;
OLED_CLS();
while(1)
{
key=KEY_Scan();
delay_ms(20);
if(key!=0)
{
if(key==1)jieshu=!jieshu;
else if(key==2)
{
if(jieshu==0)wei++;
else if(wei<=2) lengthwei[wei]--;
}
else if(key==3)
{
OLED_CLS();
display(MenuPoint,selectItem_current,selectItem_hidden);
rmydata.length1=current_length*0.01;
STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)&rmydata,sizeof(rmydata));
return;
}
else if(key==4)
{
if(jieshu==0)wei--;
else if(wei<=2) lengthwei[wei]++;
}
if(wei>=3)wei=2;
OLED_CLS();
}
time++;
if(time<=20)
{//.前一位的正下方显示^
if(wei==0)OLED_Show(8*5,2,(u8*)"^");
//.后的某一位正下方显示↑
else OLED_Show(8*6+8*wei,2,(u8*)"^");
}
else if(time<=40){if(jieshu==0)OLED_Show(0,2,(u8*)" ");}
else time=0;
for(i=0;i<3;i++)if(lengthwei[wei]>=10)lengthwei[wei]=9;
current_length=lengthwei[0]*100+lengthwei[1]*10+lengthwei[2];
sprintf((char*)str,"长度:%.2f",current_length*0.01);
OLED_Show(0,0,(u8*)str);
}
}
void fun5()
{
char str[10];
u8 lengthwei[3],wei=2,jieshu=0;//0 个位 ,1小数点后1位 2小数点后2位
int current_length;
u8 i,key;
int time=0;
current_length=rmydata.length2*100;
lengthwei[0]=current_length/100;
lengthwei[1]=current_length%100/10;
lengthwei[2]=current_length%10;
OLED_CLS();
while(1)
{
key=KEY_Scan();
delay_ms(20);
if(key!=0)
{
if(key==1)jieshu=!jieshu;
else if(key==2)
{
if(jieshu==0)wei++;
else if(wei<=2) lengthwei[wei]--;
}
else if(key==3)
{
OLED_CLS();
display(MenuPoint,selectItem_current,selectItem_hidden);
rmydata.length2=current_length*0.01;
STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)&rmydata,sizeof(rmydata));
return;
}
else if(key==4)
{
if(jieshu==0)wei--;
else if(wei<=2) lengthwei[wei]++;
}
if(wei>=3)wei=2;
OLED_CLS();
}
time++;
if(time<=20)
{//.前一位的正下方显示^
if(wei==0)OLED_Show(8*5,2,(u8*)"^");
//.后的某一位正下方显示↑
else OLED_Show(8*6+8*wei,2,(u8*)"^");
}
else if(time<=40){if(jieshu==0)OLED_Show(0,2,(u8*)" ");}
else time=0;
for(i=0;i<3;i++)if(lengthwei[wei]>=10)lengthwei[wei]=9;
current_length=lengthwei[0]*100+lengthwei[1]*10+lengthwei[2];
sprintf((char*)str,"长度:%.2f",current_length*0.01);
OLED_Show(0,0,(u8*)str);
}
}
void fun6()
{
char str[10];
u8 lengthwei[3],wei=2,jieshu=0;//0 个位 ,1小数点后1位 2小数点后2位
int current_angle;
u8 i,key;
int time=0;
current_angle=rmydata.angle*10;
lengthwei[0]=current_angle/100;
lengthwei[1]=current_angle%100/10;
lengthwei[2]=current_angle%10;
OLED_CLS();
//key=5;
while(1)
{
key=KEY_Scan();
delay_ms(20);
if(key!=0)
{
if(key==1)jieshu=!jieshu;
else if(key==2)
{
if(jieshu==0)wei++;
else if(wei<=2) lengthwei[wei]--;
}
else if(key==3)
{
OLED_CLS();
display(MenuPoint,selectItem_current,selectItem_hidden);
rmydata.angle=current_angle*0.1;
STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)&rmydata,sizeof(rmydata));
return;
}
else if(key==4)
{
if(jieshu==0)wei--;
else if(wei<=2) lengthwei[wei]++;
}
if(wei>=3)wei=2;
OLED_CLS();
}
time++;
if(time<=20)
{
if(wei==2)OLED_Show(8*8,2,(u8*)"^");
else OLED_Show(8*5+8*wei,2,(u8*)"^");
}
else if(time<=40){if(jieshu==0)OLED_Show(0,2,(u8*)" ");}
else time=0;
for(i=0;i<3;i++)if(lengthwei[wei]>=10)lengthwei[wei]=9;
current_angle=lengthwei[0]*100+lengthwei[1]*10+lengthwei[2];
sprintf((char*)str,"角度:%2.1f",current_angle*0.1);
OLED_Show(0,0,(u8 *)str);
}
}