找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3704|回复: 4
收起左侧

STM32F1C8T6 OLED12864菜单源程序 行数限定+参数设定

  [复制链接]
ID:861056 发表于 2022-3-5 12:14 | 显示全部楼层 |阅读模式
菜单+行数限定+参数设定 - 4按键
用于多级菜单显示完成各项功能选择

main函数

  1. //字库放在这里面,中文用多少生成多少#include "codetab.h"
  2. //PB6 -- SCL; PB7 -- SDA */

  3. #include "delay.h"
  4. #include "stm32f10x.h"
  5. #include "OLED_I2C.h"
  6. #include "exti.h"
  7. #include "stdio.h"
  8. #include "key.h"
  9. #include "stmflash.h"

  10. #define FLASH_SAVE_ADDR  0X08009000                //设置FLASH 保存地址(必须为偶数,且其值要大于本代码所占用FLASH的大小+0X08000000)
  11. //C8T6和CBT6(仅FLASH容量有区别)一般是在同一生产线生产的,
  12. //如果CBT6的FLASH容量部分不能使用那么就作为C8T6
  13. //36864= 0X9 000        
  14. //64K=0X10 000
  15. #define linenumber 4
  16. struct MenuItem
  17. {
  18.         short MenuCount;//当前菜单项目总数
  19.         u8 *DisplayString;//当前项目要显示的字符
  20.         void(*Subs)();//选择某一菜单后执行的功能函数
  21.         struct MenuItem *ChildrenMenus;//当前项目的子菜单
  22.         struct MenuItem *ParentMenus;//当前项目的父菜单
  23. };
  24. struct mydata
  25. {
  26.         float length1;
  27.         float length2;
  28.         float angle;
  29. };
  30. struct mydata rmydata;
  31. int selectItem_current,selectItem_hidden,selectItem;
  32. int key_num=0;
  33. int juli,jiaodu;

  34. void caidan(void);
  35. int key_scan(void);//是否按下确认键
  36. void display(struct MenuItem * MenuPoint,int selectItem_current,int selectItem_hidden);
  37. void caidan_init(void);
  38. void fun1(void);
  39. void fun2(void);
  40. void fun3(void);
  41. void fun4(void);
  42. void fun5(void);
  43. void fun6(void);

  44. int main(void)
  45. {
  46.         delay_init();                     //延时函数初始化         
  47.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
  48.         I2C_Configuration();
  49.         OLED_Init();        
  50.         OLED_CLS();
  51.         KEY_Init();
  52.         caidan_init();
  53.         //fun2();//第一次下载需要去掉fun2()前面的注释,不然程序直接卡死
  54.         STMFLASH_Read(FLASH_SAVE_ADDR,(u16*)&rmydata,sizeof(rmydata));
  55.         while(1)
  56.         {
  57.                 key_num=KEY_Scan();
  58.                 caidan();
  59.                 delay_ms(20);
  60.         }
  61. }
  62. int my_min(int a,int b)
  63. {
  64.         if (a<b)return a;
  65.         return b;
  66. }
  67. //由于定义从上往下,数组定义时子类都为NULL
  68. //第一级
  69. struct MenuItem MainMenu[] = {
  70. { 8,(u8 *)"第一",NULL,NULL,NULL },
  71. { 6,(u8 *)"第二",NULL,NULL,NULL },
  72. { 6,(u8 *)"第三",NULL,NULL,NULL },
  73. { 6,(u8 *)"第四",NULL,NULL,NULL },
  74. { 6,(u8 *)"第五",NULL,NULL,NULL },
  75. { 6,(u8 *)"第六",NULL,NULL,NULL },
  76. { 6,(u8 *)"参数初始化",fun2,NULL,NULL },
  77. { 6,(u8 *)"读取参数并显示",fun3,NULL,NULL }
  78. };
  79. //第二级
  80. struct MenuItem Setmenu1[2]={
  81. { 2,(u8 *)"返回上一级",NULL,NULL,MainMenu },
  82. { 2,(u8 *)"确定",NULL,NULL,MainMenu },
  83. };
  84. struct MenuItem Setmenu2[] = {
  85. { 4,(u8 *)"返回上一级",NULL,NULL,MainMenu },
  86. { 3,(u8 *)"读取参数",fun3,NULL,MainMenu },
  87. { 3,(u8 *)"设定长度",fun4,NULL,MainMenu },
  88. { 3,(u8 *)"确定",fun1,NULL,MainMenu } };
  89. struct MenuItem Setmenu3[] = {
  90. { 4,(u8 *)"返回上一级",NULL,NULL,MainMenu },
  91. { 3,(u8 *)"设定长度",fun5,NULL,MainMenu },
  92. { 3,(u8 *)"设定角度",fun6,NULL,MainMenu },
  93. { 3,(u8 *)"确定",NULL,NULL,MainMenu } };
  94. struct MenuItem* MenuPoint=MainMenu;//当前菜单

  95. void caidan_init(void)
  96. {
  97.         MainMenu[0].ChildrenMenus = Setmenu1;
  98.         MainMenu[1].ChildrenMenus = Setmenu2;
  99.         MainMenu[2].ChildrenMenus = Setmenu3;
  100.         selectItem_current =1;
  101.         selectItem_hidden  =0;
  102.         selectItem=selectItem_current+selectItem_hidden;
  103.         display(MenuPoint,selectItem_current,selectItem_hidden);
  104. }

  105. void display(struct MenuItem * MenuPoint,int selectItem_current,int selectItem_hidden)
  106. {
  107.         int j;
  108.         u16 x=16;
  109.         u16 y=0;
  110.         OLED_Show(0,selectItem_current*2-2,(u8 *)"->");
  111.         for ( j= selectItem_hidden; j < my_min(MenuPoint->MenuCount,linenumber+selectItem_hidden);j++)
  112.         {
  113.                 OLED_Show(x,y,MenuPoint[j].DisplayString);
  114.                 y+=2;
  115.         }
  116. }

  117. void caidan(void)
  118. {
  119.         if(key_num>0)
  120.         switch(key_num)
  121.         {
  122.                 case WKUP_PRES:
  123.                 {//上
  124.                         OLED_CLS();
  125.                         selectItem_current--;
  126.                         if (selectItem_current==0)
  127.                         {
  128.                                 if(selectItem_hidden>0)selectItem_hidden--;
  129.                                 selectItem_current++;
  130.                         }
  131.                         selectItem=selectItem_current+selectItem_hidden;
  132.                         display(MenuPoint,selectItem_current,selectItem_hidden);
  133.                 };break;
  134.                 case KEY1_PRES:
  135.                 {//下
  136.                         OLED_CLS();
  137.                         selectItem_current++;
  138.                         if(selectItem_current>linenumber)//当前的行数超过总行数
  139.                         {
  140.                                 if (selectItem_current+selectItem_hidden <= MenuPoint->MenuCount)
  141.                                         selectItem_hidden++;
  142.                                 selectItem_current--;
  143.                         }
  144.                         else if(selectItem_current>MenuPoint->MenuCount)selectItem_current--;
  145.                         selectItem=selectItem_current+selectItem_hidden;
  146.                         display(MenuPoint,selectItem_current,selectItem_hidden);
  147.                 };break;
  148.                 case KEY0_PRES:
  149.                 {//右 确认进入此项目
  150.                         if(selectItem== 1&&MenuPoint!=MainMenu)//满足退回上一级条件
  151.                         {
  152.                                         OLED_CLS();
  153.                                         MenuPoint = MenuPoint[selectItem - 1].ParentMenus;
  154.                                         selectItem_current =1;
  155.                                         selectItem_hidden  =0;
  156.                                         //selectItem = 1;
  157.                                         display(MenuPoint,selectItem_current,selectItem_hidden);
  158.                         }
  159.                         else if (MenuPoint[selectItem - 1].ChildrenMenus != NULL)//判断是否有下一级
  160.                         {                                
  161.                                 OLED_CLS();
  162.                                 MenuPoint = MenuPoint[selectItem - 1].ChildrenMenus;
  163.                                 selectItem_current =1;
  164.                                 selectItem_hidden  =0;
  165.                                 display(MenuPoint,selectItem_current,selectItem_hidden);
  166.                         }
  167.                         else if(MenuPoint[selectItem - 1].Subs != NULL)
  168.                                 MenuPoint[selectItem - 1].Subs();//功能函数执行
  169.                 };break;
  170.         }
  171. }
  172. void fun1()
  173. {
  174.         OLED_Show(16,0,(u8*)"fun1");
  175. }
  176. void fun2()//初始化参数
  177. {
  178.         rmydata.length1=1.23;
  179.         rmydata.length2=2.34;
  180.         rmydata.angle=10.2;
  181.         STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)&rmydata,sizeof(rmydata));
  182. }
  183. void fun3()//读取并显示
  184. {
  185.         u8 key;
  186.         char str[10];
  187.         OLED_CLS();
  188.         STMFLASH_Read(FLASH_SAVE_ADDR,(u16*)&rmydata,sizeof(rmydata));
  189.         sprintf(str,"长度1:%.2f",(float)rmydata.length1);
  190.         OLED_Show(16,0,(u8*)str);
  191.         sprintf((char*)str,"长度2:%.2f",(float)rmydata.length2);
  192.         OLED_Show(16,2,(u8*)str);
  193.         sprintf((char*)str,"角度:%.2f",(float)rmydata.angle);
  194.         OLED_Show(16,4,(u8*)str);
  195.         while(1)
  196.         {
  197.                 key=KEY_Scan();
  198.                 delay_ms(20);
  199.                 if(key!=0)
  200.                 {
  201.                         OLED_CLS();
  202.                         display(MenuPoint,selectItem_current,selectItem_hidden);
  203.                         return;
  204.                 }
  205.         }
  206. }

  207. void fun4()
  208. {
  209.         char str[10];
  210.         u8 lengthwei[3],wei=2,jieshu=0;//0 个位 ,1小数点后1位  2小数点后2位
  211.         int current_length;
  212.         u8 i,key;
  213.         int time=0;
  214.         current_length=rmydata.length1*100;
  215.         lengthwei[0]=current_length/100;
  216.         lengthwei[1]=current_length%100/10;
  217.         lengthwei[2]=current_length%10;
  218.         OLED_CLS();
  219.         while(1)
  220.         {
  221.                 key=KEY_Scan();
  222.                 delay_ms(20);
  223.                 if(key!=0)
  224.                 {
  225.                         if(key==1)jieshu=!jieshu;
  226.                         else if(key==2)
  227.                         {
  228.                                 if(jieshu==0)wei++;
  229.                                 else if(wei<=2) lengthwei[wei]--;
  230.                         }
  231.                         else if(key==3)
  232.                         {
  233.                                 OLED_CLS();
  234.                                 display(MenuPoint,selectItem_current,selectItem_hidden);
  235.                                 rmydata.length1=current_length*0.01;
  236.                                 STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)&rmydata,sizeof(rmydata));
  237.                                 return;
  238.                         }
  239.                         else if(key==4)
  240.                         {
  241.                                 if(jieshu==0)wei--;
  242.                                 else if(wei<=2) lengthwei[wei]++;
  243.                         }
  244.                         if(wei>=3)wei=2;
  245.                         OLED_CLS();
  246.                 }         
  247.                 time++;      
  248.                 if(time<=20)
  249.                 {//.前一位的正下方显示^
  250.                         if(wei==0)OLED_Show(8*5,2,(u8*)"^");
  251.                         //.后的某一位正下方显示↑
  252.                         else OLED_Show(8*6+8*wei,2,(u8*)"^");
  253.                 }
  254.                 else if(time<=40){if(jieshu==0)OLED_Show(0,2,(u8*)"                ");}
  255.                 else time=0;
  256.                 for(i=0;i<3;i++)if(lengthwei[wei]>=10)lengthwei[wei]=9;        
  257.                 current_length=lengthwei[0]*100+lengthwei[1]*10+lengthwei[2];
  258.                 sprintf((char*)str,"长度:%.2f",current_length*0.01);
  259.                 OLED_Show(0,0,(u8*)str);
  260.         }
  261. }
  262. void fun5()
  263. {
  264.         char str[10];
  265.         u8 lengthwei[3],wei=2,jieshu=0;//0 个位 ,1小数点后1位  2小数点后2位
  266.         int current_length;
  267.         u8 i,key;
  268.         int time=0;
  269.         current_length=rmydata.length2*100;
  270.         lengthwei[0]=current_length/100;
  271.         lengthwei[1]=current_length%100/10;
  272.         lengthwei[2]=current_length%10;
  273.         OLED_CLS();
  274.         while(1)
  275.         {
  276.                 key=KEY_Scan();
  277.                 delay_ms(20);
  278.                 if(key!=0)
  279.                 {
  280.                         if(key==1)jieshu=!jieshu;
  281.                         else if(key==2)
  282.                         {
  283.                                 if(jieshu==0)wei++;
  284.                                 else if(wei<=2) lengthwei[wei]--;
  285.                         }
  286.                         else if(key==3)
  287.                         {
  288.                                 OLED_CLS();
  289.                                 display(MenuPoint,selectItem_current,selectItem_hidden);
  290.                                 rmydata.length2=current_length*0.01;
  291.                                 STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)&rmydata,sizeof(rmydata));
  292.                                 return;
  293.                         }
  294.                         else if(key==4)
  295.                         {
  296.                                 if(jieshu==0)wei--;
  297.                                 else if(wei<=2) lengthwei[wei]++;
  298.                         }
  299.                         if(wei>=3)wei=2;
  300.                         OLED_CLS();
  301.                 }
  302.                 time++;
  303.                 if(time<=20)
  304.                 {//.前一位的正下方显示^
  305.                         if(wei==0)OLED_Show(8*5,2,(u8*)"^");
  306.                         //.后的某一位正下方显示↑
  307.                         else OLED_Show(8*6+8*wei,2,(u8*)"^");
  308.                 }
  309.                 else if(time<=40){if(jieshu==0)OLED_Show(0,2,(u8*)"                ");}
  310.                 else time=0;
  311.                 for(i=0;i<3;i++)if(lengthwei[wei]>=10)lengthwei[wei]=9;        
  312.                 current_length=lengthwei[0]*100+lengthwei[1]*10+lengthwei[2];
  313.                 sprintf((char*)str,"长度:%.2f",current_length*0.01);
  314.                 OLED_Show(0,0,(u8*)str);
  315.         }
  316. }

  317. void fun6()
  318. {
  319.         char str[10];
  320.         u8 lengthwei[3],wei=2,jieshu=0;//0 个位 ,1小数点后1位  2小数点后2位
  321.         int current_angle;
  322.         u8 i,key;
  323.         int time=0;
  324.         current_angle=rmydata.angle*10;
  325.         lengthwei[0]=current_angle/100;
  326.         lengthwei[1]=current_angle%100/10;
  327.         lengthwei[2]=current_angle%10;
  328.         OLED_CLS();
  329.         //key=5;
  330.         while(1)
  331.         {
  332.                 key=KEY_Scan();
  333.                 delay_ms(20);
  334.                 if(key!=0)
  335.                 {
  336.                         if(key==1)jieshu=!jieshu;
  337.                         else if(key==2)
  338.                         {
  339.                                 if(jieshu==0)wei++;
  340.                                 else if(wei<=2) lengthwei[wei]--;
  341.                         }
  342.                         else if(key==3)
  343.                         {
  344.                                 OLED_CLS();
  345.                                 display(MenuPoint,selectItem_current,selectItem_hidden);
  346.                                 rmydata.angle=current_angle*0.1;
  347.                                 STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)&rmydata,sizeof(rmydata));
  348.                                 return;
  349.                         }
  350.                         else if(key==4)
  351.                         {
  352.                                 if(jieshu==0)wei--;
  353.                                 else if(wei<=2) lengthwei[wei]++;
  354.                         }
  355.                         if(wei>=3)wei=2;
  356.                         OLED_CLS();
  357.                 }
  358.                 time++;
  359.                 if(time<=20)
  360.                 {
  361.                         if(wei==2)OLED_Show(8*8,2,(u8*)"^");
  362.                         else OLED_Show(8*5+8*wei,2,(u8*)"^");
  363.                 }
  364.                 else if(time<=40){if(jieshu==0)OLED_Show(0,2,(u8*)"                ");}
  365.                 else time=0;
  366.                 for(i=0;i<3;i++)if(lengthwei[wei]>=10)lengthwei[wei]=9;        
  367.                 current_angle=lengthwei[0]*100+lengthwei[1]*10+lengthwei[2];
  368.                 sprintf((char*)str,"角度:%2.1f",current_angle*0.1);
  369.                 OLED_Show(0,0,(u8 *)str);
  370.         }
  371. }
复制代码

Keil代码下载: 菜单+行数限定+参数设定 - 4按键 - 最后.7z (187.93 KB, 下载次数: 169)

评分

参与人数 1黑币 +30 收起 理由
admin + 30 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:1014699 发表于 2022-4-30 19:47 | 显示全部楼层
请问这个菜单界面效果是啥样的
回复

使用道具 举报

ID:861056 发表于 2023-8-1 17:18 | 显示全部楼层
bbbba 发表于 2022-4-30 19:47
请问这个菜单界面效果是啥样的

多级菜单显示,你可以修改里面的代码,换成自己想要的页面,很简单
回复

使用道具 举报

ID:1087948 发表于 2023-8-2 14:32 | 显示全部楼层
问一下这个是针对于4脚还是3脚
回复

使用道具 举报

5#
无效楼层,该帖已经被删除
ID:861056 发表于 2023-10-13 14:08 | 显示全部楼层
liyonghua111 发表于 2023-8-2 14:32
问一下这个是针对于4脚还是3脚

什么意思
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表