打印
[STM32F1]

OLED12864菜单源程序

[复制链接]
123|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lzmm|  楼主 | 2023-12-30 23:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式



//字库放在这里面,中文用多少生成多少#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);
        }
}


使用特权

评论回复
沙发
湖畔群思| | 2024-1-27 08:07 | 只看该作者
学习中,谢谢分享,请教一下中文字符是否需要字库芯片支持?

使用特权

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

本版积分规则

386

主题

8578

帖子

11

粉丝