久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3337|回復: 3
打印 上一主題 下一主題
收起左側

STM32C8T6單片機IIC OLED0.96GUI 菜單程序設計

[復制鏈接]
跳轉到指定樓層
樓主
ID:302293 發表于 2022-4-25 10:40 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
   程序測試正常,有什么問題可以一起研究

單片機源程序如下:
  1. /**
  2. * @file GUI.c
  3. * @author LQH
  4. * @brief  使用本庫時,注意初始化字符串一定要占滿15個字符,不然,不會將上次的字符覆蓋
  5. * @version 0.1
  6. * @date 2022-02-13
  7. *
  8. * @copyright Copyright (c) 2022
  9. *
  10. */
  11. #include "GUI.h"
  12. #include "oled.h"
  13. #include "bmp.h"

  14. #include "keyscan.h"
  15. #include "mytime.h"

  16. int8_t selectItem = 0;//當前菜單在當前菜單頁的索引,最大為3,一頁最多顯示四個菜單
  17. int8_t scrollBar  = 0;//滾動條
  18. struct Menu_t *menuPoint;//當前菜單

  19. //拿來做測試的數據
  20. int8_t kp = 0;
  21. int8_t ki = 0;
  22. int8_t kd = 0;
  23. int16_t count_test=0;
  24. uint16_t count1=0,count2=2,count3=4,count4=6,count5=8;

  25. //一些菜單的功能函數
  26. void KpSub(void);
  27. void KiAdd(void);
  28. void KdAdd(void);
  29. void KpAdd(void);
  30. void HourAdd(void);
  31. void MinuteAdd(void);
  32. void SecondAdd(void);
  33. void YearAdd(void);
  34. void MonthAdd(void);
  35. void DayAdd(void);
  36. void TimeOK(void);
  37. void TimeSetInit(void);

  38. //主UI
  39. struct MenuProperty_t MainUIProperty={1,0};
  40. struct Menu_t MainUI=
  41. {&MainUIProperty,"MainUI" ,NULL,NULL,NULL};

  42. //主菜單
  43. struct MenuProperty_t menuMainProperty={4,0};
  44. struct Menu_t menuMain[4]=
  45. {
  46.         {&menuMainProperty,"last menu     ", NULL,NULL, &MainUI,NULL},
  47.         {&menuMainProperty,"Animal        ", NULL,NULL, &MainUI,NULL},
  48.         {&menuMainProperty,"Pid           ", NULL,NULL, &MainUI,NULL},
  49.         {&menuMainProperty,"Time set      ", NULL,TimeSetInit, &MainUI,NULL}
  50. };
  51. //animal的子菜單
  52. struct MenuProperty_t setMenu1Property={6,2};
  53. struct Menu_t setMenu1[6]=
  54. {
  55.         {&setMenu1Property,"last menu     ",NULL,NULL,menuMain,NULL},
  56.         {&setMenu1Property,"bull          ",NULL,NULL,menuMain,NULL},
  57.         {&setMenu1Property,"bird          ",NULL,NULL,menuMain,NULL},
  58.         {&setMenu1Property,"dog           ",NULL,NULL,menuMain,NULL},
  59.         {&setMenu1Property,"bow           ",NULL,NULL,menuMain,NULL},
  60.         {&setMenu1Property,"fish          ",NULL,NULL,menuMain,NULL}
  61. };
  62. //Pid的子菜單
  63. struct MenuProperty_t setMenu2Property={5,1};
  64. struct Menu_t setMenu2[5]=
  65. {
  66.         {&setMenu2Property,"last menu      ",NULL, NULL, menuMain,NULL},
  67.         {&setMenu2Property,"KP   0         ",KpSub,KpAdd,menuMain,NULL},
  68.         {&setMenu2Property,"KI   0         ",NULL, KiAdd,menuMain,NULL},
  69.         {&setMenu2Property,"KD   0         ",NULL, KdAdd,menuMain,NULL},
  70.         {&setMenu2Property,"PWM  0         ",NULL, NULL, menuMain,NULL},
  71. };
  72. //Time set的子菜單
  73. struct MenuProperty_t setMenu3Property={8,4};
  74. struct Menu_t setMenu3[8]=
  75. {
  76.         {&setMenu3Property,"last menu      ",NULL, NULL,menuMain,NULL},
  77.         {&setMenu3Property,"Hour   0       ",NULL, HourAdd,menuMain,NULL},
  78.         {&setMenu3Property,"Minute 0       ",NULL, MinuteAdd,menuMain,NULL},
  79.         {&setMenu3Property,"Second 0       ",NULL, SecondAdd,menuMain,NULL},
  80.         {&setMenu3Property,"Year   0       ",NULL, YearAdd,menuMain,NULL},
  81.         {&setMenu3Property,"Month  0       ",NULL, MonthAdd,menuMain,NULL},
  82.         {&setMenu3Property,"Day    0       ",NULL, DayAdd,menuMain,NULL},
  83.         {&setMenu3Property,"OK             ",NULL, TimeOK,menuMain,NULL},
  84. };

  85. void KpSub()
  86. {
  87.         kp--;
  88. }

  89. void KpAdd()
  90. {
  91.         kp++;
  92. }

  93. void KiAdd()
  94. {
  95.         ki++;
  96. }

  97. void KdAdd()
  98. {
  99.         kd++;
  100. }

  101. void HourAdd(void)
  102. {
  103.         myTimeTemp.Hour++;
  104.         if(myTimeTemp.Hour>23)
  105.                 myTimeTemp.Hour=0;        
  106. }
  107. void MinuteAdd(void)
  108. {
  109.         myTimeTemp.Minute++;
  110.         if(myTimeTemp.Minute>59)
  111.                 myTimeTemp.Minute=0;        
  112. }
  113. void SecondAdd(void)
  114. {
  115.         myTimeTemp.Second++;
  116.         if(myTimeTemp.Second>59)
  117.                 myTimeTemp.Second=0;
  118. }
  119. void YearAdd(void)
  120. {
  121.         myTimeTemp.Year++;
  122. }
  123. void MonthAdd(void)
  124. {
  125.         myTimeTemp.Month++;
  126.         if(myTimeTemp.Month>12)
  127.                 myTimeTemp.Month=1;
  128. }
  129. void DayAdd(void)
  130. {
  131.         myTimeTemp.Day++;
  132.         if(myTimeTemp.Day>30)
  133.                 myTimeTemp.Day=1;
  134. }
  135. void TimeOK(void)
  136. {
  137.         myTime = myTimeTemp;
  138. }

  139. void TimeSetInit(void)
  140. {
  141.         myTimeTemp = myTime;
  142. }
  143. /**
  144. * @brief 主界面,可以自己設置圖畫,我這里畫了兩條線和一個時鐘
  145. *
  146. */
  147. void MainUiSet()
  148. {
  149.         int i;
  150.         u8 time_x = 18,time_y = 12,date_x=26,date_y=40;
  151.         for(i=1;i<15;i++)
  152.         {
  153.                 OLED_ShowChar(8*i,0, '-',16,1);
  154.                 OLED_ShowChar(8*i,48,'-',16,1);
  155.         }        

  156.         OLED_ShowNum(time_x,    time_y,myTime.Hour  ,2,24,1);
  157.         OLED_ShowChar(time_x+24,time_y,':'   ,24,1);
  158.         OLED_ShowNum(time_x+36, time_y,myTime.Minute,2,24,1);
  159.         OLED_ShowChar(time_x+60,time_y,':'   ,24,1);
  160.         OLED_ShowNum(time_x+72, time_y,myTime.Second,2,24,1);
  161.         
  162.         OLED_ShowNum(date_x,    date_y,myTime.Year  ,4,16,1);
  163.         OLED_ShowChar(date_x+32,date_y,'/'   ,16,1);
  164.         OLED_ShowNum(date_x+40, date_y,myTime.Month,2,16,1);
  165.         OLED_ShowChar(date_x+56,date_y,'/'   ,16,1);
  166.         OLED_ShowNum(date_x+64, date_y,myTime.Day,  2,16,1);
  167. }

  168. /**
  169.   * @Name    DisplayRefreash
  170.   * @brief   刷新當前菜單頁的所有菜單項
  171.   * @param   nowMenu: 當前菜單指針
  172. **                         selectItem: 當前菜單在當前菜單頁的索引,指小光標在第幾行
  173. **           scrollBar:滾動條所在位置
  174.   * @retval  void
  175.   * @author  LQH
  176.   * @Data    2022-01-27
  177.   */
  178. void DisplayRefreash(struct Menu_t *nowMenu,u8 selectItem,u8 scrollBar)
  179. {
  180.         int i = 0;
  181.         static u8 lastSelectItem=0;//記錄上次索引
  182.         if(nowMenu==&MainUI)//當回到主菜單時,由于沒有全占屏,所以全部清屏,再畫
  183.         {
  184.                 OLED_Clear();
  185.                 MainUiSet();
  186.         }else
  187.         {        
  188.                 OLED_ShowChar(0,lastSelectItem*16, ' ',16,1);//清除上次索引
  189.                 OLED_ShowChar(0,selectItem*16,     '>',16,1);//畫出這次索引
  190.                 for(i=0;i<(nowMenu->MenuProperty->MenuLen-nowMenu->MenuProperty->scrollBarLen);i++)
  191.                 {
  192.                         OLED_ShowString(8,i*16,nowMenu[i+scrollBar].displayString,16,1);
  193.                 }
  194.         }
  195.         OLED_Refresh();
  196.         lastSelectItem = selectItem;
  197. }
  198. /**
  199.   * @Name    DisplayRefreashDate
  200.   * @brief   刷新當前菜單頁的所有菜單項,主要拿來更新數據
  201.   * @param   nowMenu:    當前菜單指針
  202. **                         selectItem: 當前菜單在當前菜單頁的索引,指小光標在第幾行
  203. **           scrollBar: 滾動條所在位置
  204.   * @retval  void
  205.   * @author  LQH
  206.   * @Data    2022-01-27
  207.   */
  208. void DisplayRefreashData(struct Menu_t *nowMenu,u8 selectItem,u8 scrollBar)
  209. {
  210.         int i = 0;
  211.         for(i=0;i<(nowMenu->MenuProperty->MenuLen-nowMenu->MenuProperty->scrollBarLen);i++)
  212.         {
  213.                 OLED_ShowString(8,i*16,nowMenu[i+scrollBar].displayString,16,1);
  214.         }
  215.         OLED_Refresh();
  216. }

  217. /**
  218.   * @name    GuiInit
  219.   * @brief   一些菜單初始化主要是主菜單頁的子菜單確定,由于父菜單結構體初始化時不能初始化子菜單
  220.   *                  所以在這里初始化
  221.   * @param   :
  222.   * @retval  void
  223.   * @author  LQH
  224.   * @date    2022-01-27
  225.   */
  226. void GuiInit()
  227. {
  228.         MainUI.childrenMenu = menuMain;
  229.         menuMain[1].childrenMenu = setMenu1;
  230.         menuMain[2].childrenMenu = setMenu2;
  231.         menuMain[3].childrenMenu = setMenu3;
  232.         menuPoint = &MainUI;
  233.         DisplayRefreash(menuPoint,selectItem,scrollBar);
  234. }
  235. /**
  236.   * @name    GuiDataDisplayRefresh
  237.   * @brief   菜單頁的數據更新,記得一定要字符串占滿15個字符
  238.   * @param   :
  239.   * @retval  void
  240.   * @author  LQH
  241.   * @date    2022-01-27
  242.   */
  243. void GuiDataDisplayRefresh()
  244. {
  245.         if(menuPoint == setMenu1)
  246.         {
  247.                 sprintf((char*)setMenu1[1].displayString,"bull  %3d     ",count1);
  248.                 sprintf((char*)setMenu1[2].displayString,"bird  %3d     ",count2);
  249.                 sprintf((char*)setMenu1[3].displayString,"dog   %3d     ",count3);
  250.                 sprintf((char*)setMenu1[4].displayString,"bow   %3d     ",count4);
  251.                 sprintf((char*)setMenu1[5].displayString,"fish  %3d     ",count5);
  252.                 DisplayRefreashData(menuPoint,selectItem,scrollBar);
  253.         }
  254.         else if(menuPoint==setMenu2)
  255.         {
  256.                 sprintf((char*)setMenu2[1].displayString,"KP   %3d      ",kp);
  257.                 sprintf((char*)setMenu2[2].displayString,"KI   %3d      ",ki);
  258.                 sprintf((char*)setMenu2[3].displayString,"KD   %3d      ",kd);
  259.                 sprintf((char*)setMenu2[4].displayString,"PWM  %3d      ",0);
  260.                 DisplayRefreashData(menuPoint,selectItem,scrollBar);
  261.         }
  262.         else if(menuPoint==setMenu3)
  263.         {
  264.                 sprintf((char*)setMenu3[1].displayString,"Hour   %2d    ",myTimeTemp.Hour);        
  265.                 sprintf((char*)setMenu3[2].displayString,"Minute %2d    ",myTimeTemp.Minute);        
  266.                 sprintf((char*)setMenu3[3].displayString,"Second %2d    ",myTimeTemp.Second);        
  267.                 sprintf((char*)setMenu3[4].displayString,"Year   %4d    ",myTimeTemp.Year);
  268.                 sprintf((char*)setMenu3[5].displayString,"Month  %2d    ",myTimeTemp.Month);
  269.                 sprintf((char*)setMenu3[6].displayString,"Day    %2d    ",myTimeTemp.Day);
  270.                 DisplayRefreashData(menuPoint,selectItem,scrollBar);
  271.         }
  272.         else if(menuPoint==&MainUI)
  273.         {
  274.                 MainUiSet();
  275.                 OLED_Refresh();
  276.         }
  277. }
  278. /**
  279.   * @Name    GuiControl
  280.   * @brief   按鍵控制,按鍵控制的確定變量在keyscan.c中,按鍵掃描實現又是放在定時器里面的
  281.   * @param   : [輸入/出]
  282.   * @retval  void
  283.   * @author  LQH
  284.   * @Data    2022-01-27
  285.   */
  286. void GuiControl()
  287. {
  288.         if(isKeyUp==1)//上鍵按下
  289.         {
  290.                 isKeyUp=0;//標志位清零
  291.                 selectItem--;//當前菜單在當前菜單頁的索引--
  292.                 if(selectItem<0&&scrollBar!=0)//小于0,但是滾動條不在0,就減滾動條
  293.                 {
  294.                         selectItem = 0;
  295.                         scrollBar--;
  296.                 }else if(selectItem<0&&scrollBar==0)//小于0,滾動條也在0,就將索引移到最后,滾動條到最大
  297.                 {
  298.                         selectItem = menuPoint->MenuProperty->MenuLen-1-menuPoint->MenuProperty->scrollBarLen;
  299.                         scrollBar  = menuPoint->MenuProperty->scrollBarLen;
  300.                 }
  301.                 DisplayRefreash(menuPoint,selectItem,scrollBar);//刷新顯示
  302.         }else if(isKeyDown==1)//和上鍵差不多
  303.         {
  304.                 isKeyDown=0;
  305.                 selectItem++;
  306.                 //假如索引大于最大值,但是滾動條不在最大值,保持索引最大值,滾動條++
  307.                 if(selectItem>(menuPoint->MenuProperty->MenuLen-1-menuPoint->MenuProperty->scrollBarLen)&&scrollBar!=menuPoint->MenuProperty->scrollBarLen)
  308.                 {
  309.                         selectItem = menuPoint->MenuProperty->MenuLen-1-menuPoint->MenuProperty->scrollBarLen;
  310.                         scrollBar++;
  311.                         
  312.                 }
  313.                 //假如索引大于最大值,滾動條在最大值,移動到第一個位置
  314.                 else if(selectItem>(menuPoint->MenuProperty->MenuLen-1-menuPoint->MenuProperty->scrollBarLen)&&scrollBar==menuPoint->MenuProperty->scrollBarLen)
  315.                 {
  316.                         selectItem=0;
  317.                         scrollBar =0;
  318.                 }
  319.                 DisplayRefreash(menuPoint,selectItem,scrollBar);
  320.         }else if(isKeyLeft==1)
  321.         {
  322.                 //假如當前菜單的func1不為空,執行相關函數
  323.                 if(menuPoint[selectItem+scrollBar].func1!=NULL)
  324.                 {
  325.                         menuPoint[selectItem+scrollBar].func1();
  326.                 }
  327.                 isKeyLeft=0;
  328.                 DisplayRefreash(menuPoint,selectItem,scrollBar);
  329.         }else if(isKeyRight==1)
  330.         {
  331.                 if(selectItem==0 && scrollBar==0 && menuPoint[selectItem].fatherMenu!=NULL)//假如索引為零而且父菜單不為空,指向父指針
  332.                 {
  333.                         menuPoint = menuPoint[selectItem].fatherMenu;
  334.                 }
  335.                 else if(menuPoint[selectItem+scrollBar].childrenMenu!=NULL)//假如該索引子菜單頁不為空,指向子菜單
  336.                 {
  337.                         if(menuPoint[selectItem+scrollBar].func2!=NULL)//假如當前菜單的func2不為空,執行相關函數
  338.                         {
  339.                                 menuPoint[selectItem+scrollBar].func2();
  340.                         }
  341.                         menuPoint = menuPoint[selectItem+scrollBar].childrenMenu;
  342.                         selectItem = 0;
  343.                 }
  344.                 else if(menuPoint[selectItem+scrollBar].func2!=NULL)//假如當前菜單的func2不為空,執行相關函數
  345.                 {
  346.                         menuPoint[selectItem+scrollBar].func2();
  347.                 }
  348.                 isKeyRight=0;
  349.                 DisplayRefreash(menuPoint,selectItem,scrollBar);
  350.         }else if(isKeyOk==1)
  351.         {
  352.                 isKeyOk=0;
  353.                 DisplayRefreash(menuPoint,selectItem,scrollBar);
  354.         }
  355.         GuiDataDisplayRefresh();
  356. }
復制代碼

Keil代碼下載:
代碼.7z (218.14 KB, 下載次數: 121)


評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏5 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:286761 發表于 2022-9-7 16:35 | 只看該作者
太好了,最近在搞這個。剛好可以參考一下。。。。謝謝樓主分享
回復

使用道具 舉報

板凳
ID:286761 發表于 2022-9-7 16:36 | 只看該作者
太好了,剛好最近在研究這方面的東西。謝謝樓主分享.....
回復

使用道具 舉報

地板
ID:656801 發表于 2022-9-14 23:26 | 只看該作者
好資料  可以用上了
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美日韩亚洲三区 | 国产成人精品视频在线观看 | 久久久久久一区 | 精品国产欧美一区二区三区成人 | 激情欧美一区二区三区中文字幕 | 日韩欧美国产一区二区三区 | 麻豆天堂 | 久久综合久 | 精品欧美一区二区三区久久久 | 超碰成人免费 | 精品国产精品三级精品av网址 | 国产精品久久久久久久久久久久久 | av在线一区二区三区 | 国产精品亚洲一区二区三区在线 | 亚洲国产精品久久久久秋霞不卡 | 成人3d动漫一区二区三区91 | 中文字幕亚洲区一区二 | 亚洲欧美精品在线 | 亚洲bt 欧美bt 日本bt | 国产在线a | 免费一区在线 | a免费视频 | 日韩视频在线观看一区二区 | 亚洲一区二区在线播放 | 日韩精品在线观看免费 | 日本又色又爽又黄的大片 | 大乳boobs巨大吃奶挤奶 | 亚洲欧美日韩精品久久亚洲区 | 羞羞视频免费在线观看 | 亚洲v日韩v综合v精品v | 国产欧美一区二区三区日本久久久 | 北条麻妃99精品青青久久主播 | 欧美日韩在线精品 | 日韩视频一区在线观看 | 国产精品高清一区二区三区 | 黄a网站 | 欧美精品区 | 国产在线永久免费 | 九九综合| 精品国产乱码久久久久久闺蜜 | av天天看 |