找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4430|回复: 3
打印 上一主题 下一主题
收起左侧

单片机ST7565串行12864液晶驱动程序+多层液晶菜单+Proteus仿真

  [复制链接]
跳转到指定楼层
楼主
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)

制作出来的LCD12864菜单实物图如下:


单片机源程序如下:
  1. /*
  2. 名称:GXD LCD多层菜单 v1.2
  3. 作者:TranSmart  

  4. 特点:
  5. 可以在液晶LCM上显示最大254层深度的菜单,可以非常方便的使用和移植。
  6. 字符型显示适用于St7920控制芯片。
  7. 图像显示适用于st7656控制芯片,不带字库要自己实现汉字字符显示
  8. 在图像模式下支持焦点菜单反白,
  9. 焦点菜单反白流程是:
  10. 1.调用 LCD_disp_SetReverse(1),打开液晶反白显示,以后的输出都是反白显示
  11. 2.输出焦点菜单内容
  12. 3.调用 LCD_disp_SetReverse(0),关闭液晶反白显示,以后的输出都是正常显示
  13. 可以根据此流程,在各种控制芯片上实现反白显示。


  14. 历史:
  15. 2009-9-22 添加在图形模式下焦点行反白的功能
  16. 2009-8-2  添加N层菜单功能,修改屏幕参数定义
  17. 2009-3-4  初始版本

  18. 编译环境:

  19. IDE-Version:
  20. uVision3 V3.33
  21. Copyright (c) Keil Elektronik GmbH / Keil Software, Inc 2006

  22. Tool Version Numbers:
  23. 工具链路径:C:\Keil\C51\BIN\
  24. C Compiler: C51.Exe V8.05a
  25. Assembler: A51.Exe
  26. Linker/Locator: BL51.Exe V6.00
  27. Librarian: LIB51.Exe V4.24
  28. Hex Converter: OH51.Exe V2.6
  29. CPU DLL: S8051.DLL V3.06
  30. Dialog DLL: DP51.DLL V2.48b
  31. Target DLL: C:\KEIL\VW_C.DLL
  32. Dialog DLL: TP51.DLL V2.48b

  33. 版权声明:
  34. 义务:
  35. 1.如果您在使用中发现任何BUG,请通知gongxd@126.com,我会及时改正,并给您一份最新的代码
  36. 2.请保留本声明

  37. 权利:
  38. 如果您同意履行上面的义务,您就可以完全免费将代码应用于任何商业非商业用途
  39. 但本代码版权归中国传惠gongxd@126.com 所有,否则严禁使用本代码

  40. 建议:
  41. 如果您作了什么改进希望能通知gongxd@126.com,最好能共享一下,
  42. 我也会给您一份 最新 的代码,共同进步嘛

  43. 后话:大家都不容易,如果您觉得这东西有点用,就尽情传播吧
  44. */

  45. #include "menu.h"
  46. #include "menu_res.h"

  47. //菜单是否更新 1是 0否
  48. unsigned char  MenuDisPlayUpdate;


  49. //所有菜单板的个数
  50. #define MenuAllCount sizeof(MenuPanel)/sizeof(MenuPanelStruct)
  51. Menu_Statestruct  Menu_State;//菜单状态定义


  52. //=================================================================================栈函数

  53. //栈大小,菜单深度
  54. #define  StackSize  MenuDeep

  55. //声明堆栈元素类型
  56. typedef Menu_Statestruct StackElementType;
  57. //栈元素数组声明
  58. StackElementType  MenuParentStack[StackSize];

  59. //栈顶
  60. unsigned char StackTOP;

  61. //栈初始化
  62. void StackINI()
  63. {
  64. StackTOP=0;
  65. }
  66. //测试栈是否空 1 是 0 否
  67. unsigned char  StackEmpty()
  68. {
  69. return  StackTOP==0;
  70. }
  71. //测试栈是否满 1 是 0 否
  72. unsigned char  StackFull()
  73. {
  74. return  StackTOP==StackSize;
  75. }

  76. //出栈
  77. StackElementType  StackPOP()
  78. {
  79. if (StackTOP==0)
  80. {
  81. return MenuParentStack[0];
  82. }
  83. StackTOP--;
  84. return MenuParentStack[StackTOP];
  85. }

  86. //入栈
  87. void  StackPush(StackElementType INElement)
  88. {
  89. if (StackTOP==StackSize)
  90. {
  91. return;
  92. }
  93. MenuParentStack[StackTOP]=INElement;
  94. StackTOP++;
  95. }

  96. //=================================================================================菜单函数
  97. //已经到最顶了
  98. void  StackEmptyErr()
  99. {
  100. unsigned  char code MenuTopErrMsg[]=
  101. {"已经到最顶了"};
  102. LCD_disp_CLS();
  103. LCD_disp_printR(MenuTopErrMsg,1,1);
  104. delayms(300);
  105. LCD_disp_CLS();
  106. //显示主菜单
  107.     Menu_State.CurrentPanel=0;//本级菜单的菜单索引号
  108.     Menu_State.ItemStartDisplay=0; //显示第一项对应的菜单条目索引
  109.     Menu_State.FocusLine=1;  //焦点在屏上是第几项
  110. }

  111. //菜单达到最大深度,栈满提示函数
  112. void  StackFullErr()
  113. {
  114. unsigned  char code MenuTopErrMsg[]=
  115. {"菜单栈满无法继续"};
  116. LCD_disp_CLS();
  117. LCD_disp_printR(MenuTopErrMsg,0,1);
  118. delayms(300);
  119. LCD_disp_CLS();
  120. }

  121. //默认菜单处理函数
  122. void voidNull()
  123. {
  124. }

  125. //光标所在行菜单项显示
  126. void UpdatedisplayMenu_Focus(unsigned char *MenuTxttmp)
  127. {
  128. #if   FocusReverse==1
  129.     //图像反色显示 0 否 1是,执行此命令后的所有操作均是按照设置显示
  130.     LCD_disp_SetReverse(1);
  131. #endif   
  132.     //显示菜单项
  133.     LCD_disp_printR(MenuTxttmp,MenuItemDisplayStartX,Menu_State.FocusLine+MenuItemDisplayStartY);

  134. //是否显示每行菜单前的指示  0 否 1是 ,推荐字符液晶使用,图形液晶用反白
  135. #if  FocusPointDisply==1
  136.     //显示前面的指针
  137.     LCD_setpos(MenuPointX,Menu_State.FocusLine+MenuItemDisplayStartY);
  138.     LCD_disp_Putchar(MenuPointASCII);
  139. #endif   
  140.   
  141. #if   FocusReverse==1
  142.     //图像反色显示 0 否 1是,执行此命令后的所有操作均是按照设置显示
  143.     LCD_disp_SetReverse(0);
  144. #endif


  145. }

  146. //菜单显示更新函数
  147. void UpdatedisplayMenuPanel()
  148. {
  149.     unsigned char i,DisplayLenCount;

  150.     MenuItemStruct *p;
  151.     p=MenuPanel[Menu_State.CurrentPanel].MenuPanelItem+Menu_State.ItemStartDisplay;
  152.     DisplayLenCount=MenuPanel[Menu_State.CurrentPanel].MenuItemCount-Menu_State.ItemStartDisplay ;
  153.     if (DisplayLenCount>ScreenHLine)
  154.     {
  155.         DisplayLenCount=ScreenHLine;
  156.     }
  157.     LCD_disp_CLS();

  158.     for (i=0;i<DisplayLenCount;i++)
  159.     {
  160.         if (i==Menu_State.FocusLine)
  161.         {
  162.         //光标所在行菜单项显示,可以自定义反白显示等
  163.             UpdatedisplayMenu_Focus(p->MenuTxt);
  164.         }
  165.         else
  166.         {
  167.             LCD_disp_printR(p->MenuTxt,MenuItemDisplayStartX,i+MenuItemDisplayStartY);
  168.         }
  169.         p++;
  170.     }




  171. }

  172. //按键处理函数
  173. void UpdateMenuPanelkeyInner(unsigned char MenuKeyCode)
  174. {
  175.     unsigned char i;
  176.     //父菜单堆栈临时元素
  177.     Menu_Statestruct  tmpParent;

  178.     //菜单是否更新 1是 0否
  179.         MenuDisPlayUpdate=1;

  180.     switch (MenuKeyCode)
  181.     {

  182.     //一直按着向上键
  183.     case   MenuKey_UpCon:

  184.     case  MenuKey_Up:


  185.         if (Menu_State.FocusLine>0)
  186.         {
  187.             Menu_State.FocusLine--;  //焦点在屏上是第几项
  188.         }
  189.         else
  190.         {
  191.             if (Menu_State.ItemStartDisplay>0)
  192.             {
  193.                 Menu_State.ItemStartDisplay--;
  194.             }
  195.             else
  196.             {
  197.                 Menu_State.ItemStartDisplay=MenuPanel[Menu_State.CurrentPanel].MenuItemCount-1;
  198.             }

  199.         }

  200.         break;

  201.      //一直按着向下键
  202.    case   MenuKey_DownCon:
  203.     case  MenuKey_Down:
  204.         if ((Menu_State.ItemStartDisplay+Menu_State.FocusLine)<MenuPanel[Menu_State.CurrentPanel].MenuItemCount-1)
  205.         {
  206.             if (Menu_State.FocusLine<ScreenHLine-1 )
  207.             {
  208.                 Menu_State.FocusLine++;  //焦点在屏上是第几项
  209.             }
  210.             else
  211.             {
  212.                 Menu_State.ItemStartDisplay++; //显示第一项对应的菜单条目索引
  213.             }
  214.         }
  215.         else
  216.         {
  217.             Menu_State.FocusLine=0;
  218.             Menu_State.ItemStartDisplay=0;
  219.         }

  220.         break;
  221.     case  MenuKey_Ok:

  222.         i=Menu_State.FocusLine+Menu_State.ItemStartDisplay;
  223.         if ((MenuPanel[Menu_State.CurrentPanel].MenuPanelItem+i)->MenuChildID==MenuNoChild)
  224.         {
  225.             (*((MenuPanel[Menu_State.CurrentPanel].MenuPanelItem+i)->CurrentOperate))();
  226.         }
  227.         else
  228.         {
  229.              if (StackFull()==0)
  230.              {
  231.             //父菜单显示在屏幕上的第一条条目
  232.             tmpParent.ItemStartDisplay=Menu_State.ItemStartDisplay;
  233.              //焦点在屏上是第几项
  234.             tmpParent.FocusLine=Menu_State.FocusLine;
  235.             //父菜单号
  236.             tmpParent.CurrentPanel=Menu_State.CurrentPanel;//本级菜单的菜单索引号
  237.             //入栈
  238.             StackPush(tmpParent);


  239.             Menu_State.CurrentPanel=(MenuPanel[Menu_State.CurrentPanel].MenuPanelItem+i)->MenuChildID;//父菜单的菜单索引号
  240.             Menu_State.ItemStartDisplay=0; //显示第一项对应的菜单条目索引
  241.             Menu_State.FocusLine=0;  //焦点在屏上是第几项
  242.             
  243.              }
  244.              else
  245.              {
  246.                 //菜单达到最大深度,栈满提示函数
  247.                     StackFullErr();

  248.              }

  249.         };
  250.         break;
  251.     //一直按着返回键
  252.    case MenuKey_CancelCon:
  253.     case  MenuKey_Cancel:
  254.             //测试栈是否空 1 是 0 否
  255.             if( StackEmpty()==0)
  256.             {            
  257.                 tmpParent=StackPOP();
  258.                 Menu_State.CurrentPanel=tmpParent.CurrentPanel;
  259.                 Menu_State.ItemStartDisplay=tmpParent.ItemStartDisplay; //显示第一项对应的菜单条目索引
  260.                 Menu_State.FocusLine=tmpParent.FocusLine;  //焦点在屏上是第几项
  261.             
  262.             }
  263.             else
  264.             {
  265.               //菜单已经到最顶了,栈空提示函数
  266.                     StackEmptyErr();

  267.             }

  268.         break;

  269.         default:
  270.          //菜单是否更新 1是 0否
  271.               MenuDisPlayUpdate=0;
  272.          break;

  273.     }
  274. }

  275. void UpdateMenuPanelkey(unsigned char MenuKeyCode)
  276. {
  277. if (MenuKeyCode==MenuKey_Null)
  278. {
  279.         return;
  280. }
  281. //弄这两个函数并列目的是减小RAM使用
  282. UpdateMenuPanelkeyInner(MenuKeyCode);//更新按键
  283. //菜单是否更新 1是 0否
  284. if (MenuDisPlayUpdate==1)
  285. {
  286. UpdatedisplayMenuPanel();//更新菜单显示
  287. }

  288. }


  289. void init_Menu()
  290. {   
  291.     //菜单栈初始化
  292.     StackINI();

  293.     Menu_State.CurrentPanel=0;//本级菜单的菜单索引号
  294.     Menu_State.ItemStartDisplay=0; //显示第一项对应的菜单条目索引
  295.     Menu_State.FocusLine=1;  //焦点在屏上是第几项
  296.     UpdatedisplayMenuPanel();//更新菜单
  297. }
复制代码

所有资料51hei提供下载:
ST7565 串行液晶驱动 多层液晶菜单 Proteus仿真 ST7565 串行液晶驱动.rar (136.09 KB, 下载次数: 210)

评分

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

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏8 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:461260 发表于 2020-12-22 18:01 | 只看该作者
下载来学习一下,现在即使不知道怎么做菜单问题
回复

使用道具 举报

板凳
ID:96744 发表于 2022-4-3 01:16 | 只看该作者
整了些PFC的ST7565串口屏,焊好升压电容和接线,找到楼主的程序下载测试液晶屏,能显示,但字模偏了几列,应该是128和132的区别造成的,明天再修改程序试试。楼主辛苦了。
回复

使用道具 举报

地板
ID:256792 发表于 2023-7-7 11:57 | 只看该作者
alunli 发表于 2022-4-3 01:16
整了些PFC的ST7565串口屏,焊好升压电容和接线,找到楼主的程序下载测试液晶屏,能显示,但字模偏了几列, ...

我用在了oled上,也是这样,解决了吗‘
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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