仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei截圖20201214090252343.jpg (119.58 KB, 下載次數: 77)
下載附件
2020-12-14 09:08 上傳
制作出來的LCD12864菜單實物圖如下:
通天塔.jpg (3.69 MB, 下載次數: 89)
下載附件
2020-12-14 09:12 上傳
單片機源程序如下:
- /*
- 名稱:GXD LCD多層菜單 v1.2
- 作者:TranSmart
- 特點:
- 可以在液晶LCM上顯示最大254層深度的菜單,可以非常方便的使用和移植。
- 字符型顯示適用于St7920控制芯片。
- 圖像顯示適用于st7656控制芯片,不帶字庫要自己實現漢字字符顯示
- 在圖像模式下支持焦點菜單反白,
- 焦點菜單反白流程是:
- 1.調用 LCD_disp_SetReverse(1),打開液晶反白顯示,以后的輸出都是反白顯示
- 2.輸出焦點菜單內容
- 3.調用 LCD_disp_SetReverse(0),關閉液晶反白顯示,以后的輸出都是正常顯示
- 可以根據此流程,在各種控制芯片上實現反白顯示。
- 歷史:
- 2009-9-22 添加在圖形模式下焦點行反白的功能
- 2009-8-2 添加N層菜單功能,修改屏幕參數定義
- 2009-3-4 初始版本
- 編譯環境:
- IDE-Version:
- uVision3 V3.33
- Copyright (c) Keil Elektronik GmbH / Keil Software, Inc 2006
- Tool Version Numbers:
- 工具鏈路徑:C:\Keil\C51\BIN\
- C Compiler: C51.Exe V8.05a
- Assembler: A51.Exe
- Linker/Locator: BL51.Exe V6.00
- Librarian: LIB51.Exe V4.24
- Hex Converter: OH51.Exe V2.6
- CPU DLL: S8051.DLL V3.06
- Dialog DLL: DP51.DLL V2.48b
- Target DLL: C:\KEIL\VW_C.DLL
- Dialog DLL: TP51.DLL V2.48b
- 版權聲明:
- 義務:
- 1.如果您在使用中發現任何BUG,請通知gongxd@126.com,我會及時改正,并給您一份最新的代碼
- 2.請保留本聲明
- 權利:
- 如果您同意履行上面的義務,您就可以完全免費將代碼應用于任何商業非商業用途
- 但本代碼版權歸中國傳惠gongxd@126.com 所有,否則嚴禁使用本代碼
- 建議:
- 如果您作了什么改進希望能通知gongxd@126.com,最好能共享一下,
- 我也會給您一份 最新 的代碼,共同進步嘛
- 后話:大家都不容易,如果您覺得這東西有點用,就盡情傳播吧
- */
- #include "menu.h"
- #include "menu_res.h"
- //菜單是否更新 1是 0否
- unsigned char MenuDisPlayUpdate;
- //所有菜單板的個數
- #define MenuAllCount sizeof(MenuPanel)/sizeof(MenuPanelStruct)
- Menu_Statestruct Menu_State;//菜單狀態定義
- //=================================================================================棧函數
- //棧大小,菜單深度
- #define StackSize MenuDeep
- //聲明堆棧元素類型
- typedef Menu_Statestruct StackElementType;
- //棧元素數組聲明
- StackElementType MenuParentStack[StackSize];
- //棧頂
- unsigned char StackTOP;
- //棧初始化
- void StackINI()
- {
- StackTOP=0;
- }
- //測試棧是否空 1 是 0 否
- unsigned char StackEmpty()
- {
- return StackTOP==0;
- }
- //測試棧是否滿 1 是 0 否
- unsigned char StackFull()
- {
- return StackTOP==StackSize;
- }
- //出棧
- StackElementType StackPOP()
- {
- if (StackTOP==0)
- {
- return MenuParentStack[0];
- }
- StackTOP--;
- return MenuParentStack[StackTOP];
- }
- //入棧
- void StackPush(StackElementType INElement)
- {
- if (StackTOP==StackSize)
- {
- return;
- }
- MenuParentStack[StackTOP]=INElement;
- StackTOP++;
- }
- //=================================================================================菜單函數
- //已經到最頂了
- void StackEmptyErr()
- {
- unsigned char code MenuTopErrMsg[]=
- {"已經到最頂了"};
- LCD_disp_CLS();
- LCD_disp_printR(MenuTopErrMsg,1,1);
- delayms(300);
- LCD_disp_CLS();
- //顯示主菜單
- Menu_State.CurrentPanel=0;//本級菜單的菜單索引號
- Menu_State.ItemStartDisplay=0; //顯示第一項對應的菜單條目索引
- Menu_State.FocusLine=1; //焦點在屏上是第幾項
- }
- //菜單達到最大深度,棧滿提示函數
- void StackFullErr()
- {
- unsigned char code MenuTopErrMsg[]=
- {"菜單棧滿無法繼續"};
- LCD_disp_CLS();
- LCD_disp_printR(MenuTopErrMsg,0,1);
- delayms(300);
- LCD_disp_CLS();
- }
- //默認菜單處理函數
- void voidNull()
- {
- }
- //光標所在行菜單項顯示
- void UpdatedisplayMenu_Focus(unsigned char *MenuTxttmp)
- {
- #if FocusReverse==1
- //圖像反色顯示 0 否 1是,執行此命令后的所有操作均是按照設置顯示
- LCD_disp_SetReverse(1);
- #endif
- //顯示菜單項
- LCD_disp_printR(MenuTxttmp,MenuItemDisplayStartX,Menu_State.FocusLine+MenuItemDisplayStartY);
-
- //是否顯示每行菜單前的指示 0 否 1是 ,推薦字符液晶使用,圖形液晶用反白
- #if FocusPointDisply==1
- //顯示前面的指針
- LCD_setpos(MenuPointX,Menu_State.FocusLine+MenuItemDisplayStartY);
- LCD_disp_Putchar(MenuPointASCII);
- #endif
-
- #if FocusReverse==1
- //圖像反色顯示 0 否 1是,執行此命令后的所有操作均是按照設置顯示
- LCD_disp_SetReverse(0);
- #endif
- }
- //菜單顯示更新函數
- void UpdatedisplayMenuPanel()
- {
- unsigned char i,DisplayLenCount;
- MenuItemStruct *p;
- p=MenuPanel[Menu_State.CurrentPanel].MenuPanelItem+Menu_State.ItemStartDisplay;
- DisplayLenCount=MenuPanel[Menu_State.CurrentPanel].MenuItemCount-Menu_State.ItemStartDisplay ;
- if (DisplayLenCount>ScreenHLine)
- {
- DisplayLenCount=ScreenHLine;
- }
- LCD_disp_CLS();
- for (i=0;i<DisplayLenCount;i++)
- {
- if (i==Menu_State.FocusLine)
- {
- //光標所在行菜單項顯示,可以自定義反白顯示等
- UpdatedisplayMenu_Focus(p->MenuTxt);
- }
- else
- {
- LCD_disp_printR(p->MenuTxt,MenuItemDisplayStartX,i+MenuItemDisplayStartY);
- }
- p++;
- }
- }
- //按鍵處理函數
- void UpdateMenuPanelkeyInner(unsigned char MenuKeyCode)
- {
- unsigned char i;
- //父菜單堆棧臨時元素
- Menu_Statestruct tmpParent;
- //菜單是否更新 1是 0否
- MenuDisPlayUpdate=1;
- switch (MenuKeyCode)
- {
- //一直按著向上鍵
- case MenuKey_UpCon:
- case MenuKey_Up:
- if (Menu_State.FocusLine>0)
- {
- Menu_State.FocusLine--; //焦點在屏上是第幾項
- }
- else
- {
- if (Menu_State.ItemStartDisplay>0)
- {
- Menu_State.ItemStartDisplay--;
- }
- else
- {
- Menu_State.ItemStartDisplay=MenuPanel[Menu_State.CurrentPanel].MenuItemCount-1;
- }
- }
- break;
- //一直按著向下鍵
- case MenuKey_DownCon:
- case MenuKey_Down:
- if ((Menu_State.ItemStartDisplay+Menu_State.FocusLine)<MenuPanel[Menu_State.CurrentPanel].MenuItemCount-1)
- {
- if (Menu_State.FocusLine<ScreenHLine-1 )
- {
- Menu_State.FocusLine++; //焦點在屏上是第幾項
- }
- else
- {
- Menu_State.ItemStartDisplay++; //顯示第一項對應的菜單條目索引
- }
- }
- else
- {
- Menu_State.FocusLine=0;
- Menu_State.ItemStartDisplay=0;
- }
- break;
- case MenuKey_Ok:
- i=Menu_State.FocusLine+Menu_State.ItemStartDisplay;
- if ((MenuPanel[Menu_State.CurrentPanel].MenuPanelItem+i)->MenuChildID==MenuNoChild)
- {
- (*((MenuPanel[Menu_State.CurrentPanel].MenuPanelItem+i)->CurrentOperate))();
- }
- else
- {
- if (StackFull()==0)
- {
- //父菜單顯示在屏幕上的第一條條目
- tmpParent.ItemStartDisplay=Menu_State.ItemStartDisplay;
- //焦點在屏上是第幾項
- tmpParent.FocusLine=Menu_State.FocusLine;
- //父菜單號
- tmpParent.CurrentPanel=Menu_State.CurrentPanel;//本級菜單的菜單索引號
- //入棧
- StackPush(tmpParent);
- Menu_State.CurrentPanel=(MenuPanel[Menu_State.CurrentPanel].MenuPanelItem+i)->MenuChildID;//父菜單的菜單索引號
- Menu_State.ItemStartDisplay=0; //顯示第一項對應的菜單條目索引
- Menu_State.FocusLine=0; //焦點在屏上是第幾項
-
- }
- else
- {
- //菜單達到最大深度,棧滿提示函數
- StackFullErr();
- }
- };
- break;
- //一直按著返回鍵
- case MenuKey_CancelCon:
- case MenuKey_Cancel:
- //測試棧是否空 1 是 0 否
- if( StackEmpty()==0)
- {
- tmpParent=StackPOP();
- Menu_State.CurrentPanel=tmpParent.CurrentPanel;
- Menu_State.ItemStartDisplay=tmpParent.ItemStartDisplay; //顯示第一項對應的菜單條目索引
- Menu_State.FocusLine=tmpParent.FocusLine; //焦點在屏上是第幾項
-
- }
- else
- {
- //菜單已經到最頂了,棧空提示函數
- StackEmptyErr();
- }
- break;
- default:
- //菜單是否更新 1是 0否
- MenuDisPlayUpdate=0;
- break;
- }
- }
- void UpdateMenuPanelkey(unsigned char MenuKeyCode)
- {
- if (MenuKeyCode==MenuKey_Null)
- {
- return;
- }
- //弄這兩個函數并列目的是減小RAM使用
- UpdateMenuPanelkeyInner(MenuKeyCode);//更新按鍵
- //菜單是否更新 1是 0否
- if (MenuDisPlayUpdate==1)
- {
- UpdatedisplayMenuPanel();//更新菜單顯示
- }
- }
- void init_Menu()
- {
- //菜單棧初始化
- StackINI();
- Menu_State.CurrentPanel=0;//本級菜單的菜單索引號
- Menu_State.ItemStartDisplay=0; //顯示第一項對應的菜單條目索引
- Menu_State.FocusLine=1; //焦點在屏上是第幾項
- UpdatedisplayMenuPanel();//更新菜單
- }
復制代碼
51hei截圖20201214090803015.jpg (99.51 KB, 下載次數: 65)
下載附件
2020-12-14 09:08 上傳
所有資料51hei提供下載:
ST7565 串行液晶驅動 多層液晶菜單 Proteus仿真 ST7565 串行液晶驅動.rar
(136.09 KB, 下載次數: 211)
2020-12-14 09:07 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|