適合初學者看看
串口通信 有加注釋,完整代碼下載:
菜單程序.zip
(2.65 KB, 下載次數: 62)
2016-12-9 23:50 上傳
點擊文件名下載附件
簡易菜單程序
預覽:
- #include <reg52.h>
- #include <intrins.h>
- #define uchar unsigned char
- sbit LCD_RS = P2^6;
- sbit LCD_RW = P2^5;
- sbit LCD_EN = P2^7;
- sbit PSB= P2^1; //串并口選擇端 并高串低
- //按鍵
- sbit KEY_PgDn=P3^0;
- sbit KEY_PgUp=P3^1;
- sbit KEY_Enter=P3^2;
- sbit KEY_Esc=P3^3;
- bit Menu1,Menu2,Menu3,Menu4,Menu5,Menu6,Enter_Menu,Menu0;
- unsigned char curr=1,currold;//全局變量,當前箭頭位置
- unsigned char code user16x16[]={ //箭頭圖片
- 0x00,0x00,0x20,0x00,0x30,0x00,0x38,0x00,0x3C,0x00,0x3E,0x00,0x3F,0x00,0x3F,0x80,
- 0x3F,0xC0,0x3F,0x80,0x3F,0x00,0x3E,0x00,0x3C,0x00,0x38,0x00,0x30,0x00,0x20,0x00,
- };
- unsigned char code *MainMenu[]=
- {
- {" 功能菜單"},
- {" 溫度顯示"},
- {" 自制萬年歷"},
- {" 我的設置"},
- {" 5.設置5"},
- {" 6.設置6"},
- {" 7.設置7"},
- {" 8.設置8"},
- {" 9.設置9"},
- {" 0.設置0"},
- };
- /***********************************************
- 延時函數
- ***********************************************/
- void DelayUs2x(unsigned char t)
- {
- while(--t);
- }
- void DelayMs(unsigned char t)
- {
-
- while(t--)
- {
- DelayUs2x(245);
- DelayUs2x(245);
- }
- }
- /*********************************************
- 數據讀寫端口
- *********************************************/
- void Lcd_Send_Date(uchar date)
- {
- uchar i;
- LCD_RS=1;
- for(i=0;i<8;i++)
- {
- if((date<<i)&0x80)
- LCD_RW=1;
- else
- LCD_RW=0;
- LCD_EN=0;
- LCD_EN=1;
- }
- }
- /***********************************************
- 寫入命令
- ***********************************************/
- void Write_Cmd(uchar com)
- {
- Lcd_Send_Date(0xf8);
- Lcd_Send_Date(0xf0&com);
- Lcd_Send_Date(com<<4);
- DelayMs(1);
- }
- /***********************************************
- 寫入數據
- ***********************************************/
- void Write_Data(uchar dat)
- {
- Lcd_Send_Date(0xfa);
- Lcd_Send_Date(dat&0xf0);
- Lcd_Send_Date(dat<<4);
- DelayMs(1);
- }
- /***********************************************
- 液晶屏初始化
- ***********************************************/
- void Init_ST7920()
- {
- DelayMs(40); //大于40MS的延時程序
- DelayMs(1); //延時
- Write_Cmd(0x30); //選擇基本指令集
- DelayUs2x(50); //延時大于100us
- Write_Cmd(0x30); //選擇8bit數據流
- DelayUs2x(20); //延時大于37us
- Write_Cmd(0x0c); //開顯示(無游標、不反白)
- DelayUs2x(50); //延時大于100us
- Write_Cmd(0x01); //清除顯示,并且設定地址指針為00H
- DelayMs(15); //延時大于10ms
- Write_Cmd(0x06); //指定在資料的讀取及寫入時,設定游標的移動方向及指定顯示的移位,光標從右向左加1位移動
- DelayUs2x(50); //延時大于100us
- }
- /***********************************************
- 用戶自定義字符
- ***********************************************/
- void CGRAM()
- {
- int i;
- Write_Cmd(0x30);
- Write_Cmd(0x40); //對CGRAM第一個自定義字符操作,
- for(i=0;i<16;i++)
- {
- Write_Data(user16x16[i*2]);
- Write_Data(user16x16[i*2+1]);
- }
- }
- /***********************************************
- 顯示用戶自定義字符
- ***********************************************/
- void DisplayCGRAM(unsigned char x,unsigned char y)
- {
- switch(y)
- {
- case 1: Write_Cmd(0x80+x);break;
- case 2: Write_Cmd(0x90+x);break;
- case 3: Write_Cmd(0x88+x);break;
- case 4: Write_Cmd(0x98+x);break;
- default:break;
- }
- Write_Data(00); //上面有一個字符操作0x04了 所以直接寫
- Write_Data(00); //寫字符 Write_Data(user16x16[i*2]);
- // Write_Data(user16x16[i*2+1]);
- }
- /***********************************************
- 顯示字符串
- x:橫坐標值,范圍0~8
- y:縱坐標值,范圍1~4
- ***********************************************/
- void LCD_PutString(unsigned char x,unsigned char y,unsigned char code *s)
- {
- switch(y)
- {
- case 1: Write_Cmd(0x80+x);break;
- case 2: Write_Cmd(0x90+x);break;
- case 3: Write_Cmd(0x88+x);break;
- case 4: Write_Cmd(0x98+x);break;
- default:break;
- }
- while(*s>0)
- {
- Write_Data(*s);
- s++;
- DelayUs2x(50);
- }
- }
- /***********************************************
- 清屏
- ***********************************************/
- void ClrScreen()
- {
- Write_Cmd(0x01);
- DelayMs(15);
- }
-
- /***********************************************
- 調用顯示更新
- ***********************************************/
- void DisplayUpdata(void)
- {
- unsigned char num; //輸入的CURR為1 執行完 DisplayUpdata后又變為0
- ClrScreen();
- num=sizeof(MainMenu)/sizeof(MainMenu[0]);//判斷數組中數值個數
- //num為此數組的語速的個數
- //代表數組中元素的個數,size(a)表示整個數組的字節數,size(a[0])表示一個元素的字節數,他們相除之后就表示這個數組中元素的個數
- if((0+(curr/4)*4)<num)
- LCD_PutString(0,1,MainMenu[0+(curr/4)*4]);
- else //如果超出數組最大元素,則寫空信息,不判斷此信息可能會出現亂碼 0是字節 1是行數
- LCD_PutString(0,1,"");
- // 2
- if((1+(curr/4)*4)<num)
- LCD_PutString(0,2,MainMenu[1+(curr/4)*4]); //num是字節數 1or2or3/4=0
- // <0curr<3 3<curr<8
- else // 0+(curr/4)*4=0 4
- LCD_PutString(0,2,""); // 1+(curr/4)*4=1 5
- //3 // 2+(curr/4)*4=2 6
- if((2+(curr/4)*4)<num) // 3+(curr/4)*4=3 7
- LCD_PutString(0,3,MainMenu[2+(curr/4)*4]);
- else
- LCD_PutString(0,3,"");
- //4
- if((3+(curr/4)*4)<num) //判斷行數
- LCD_PutString(0,4,MainMenu[3+(curr/4)*4]);
- else
- LCD_PutString(0,4,"");
- DisplayCGRAM(0,curr%4+1); //顯示字符串的函數 0%4+1=1 1%4+1=2 /2+1=3 /3+1=4
- }
- /*------------------------------------
- 主界面處理
- ------------------------------------*/
- void MainMenu_Pro()
- {
- if(curr!=currold) //光標位置變化,則更新顯示 按鍵按下去 字符串就變更位置了 CURR也就變了
- {
- DisplayUpdata();
- currold=curr; //把CURR的值賦給CURROLD 判斷下加一個一
- }
-
- if(!KEY_PgUp)
- {
- DelayMs(10);
- if(!KEY_PgUp)
- {
- while(!KEY_PgUp);
- {
- if(curr<sizeof(MainMenu)/sizeof(MainMenu[0])-1) //sizeof 求字節數
- //判斷數組中數值個數
- { curr++; }
- }
- }
- }
- else
- if(!KEY_PgDn)
- {
- DelayMs(10);
- if(!KEY_PgDn)
- {
- while(!KEY_PgDn);
- {
- if(curr>0)
- { curr--; }
- }
- }
- }
- else if(!KEY_Enter)
- {
- DelayMs(10);
- if(!KEY_Enter)
- {
- while(!KEY_Enter);
- switch(curr)
- {
- // case 0: Menu0=1;Enter_Menu=1;break;
- case 1: Menu1=1;Enter_Menu=1;ClrScreen();break;
- case 2: Menu2=1;Enter_Menu=1;ClrScreen();break;
- case 3: Menu3=1;Enter_Menu=1;ClrScreen();break;
- // case 4: Menu4=1;Enter_Menu=1;break;
- // case 5: Menu5=1;Enter_Menu=1;break;
- // case 6: FanHui1=1;Menu_Flag=0;guide=0;
- // Write_Cmd(0x01);break; //輪詢到有enter鍵,當guide指向返回時候直接去掉FanHui1控制的父菜單循環
- default:return;
- }
- TR1=0;
- }
- }
-
- }
- /*************************************************************
- 按鍵返回函數
- *************************************************************/
- void ESC()
- {
- DelayMs(10);
- if(!KEY_Esc)
- {
- while(!KEY_Esc);
- Menu1=0;
- Menu2=0;
- Menu3=0;
- Enter_Menu=0;
- DisplayUpdata();
- }
- }
- /*------------------------------------
- Menu1設置時間子菜單處理
- ------------------------------------*/
- void Menu1_Pro()
- {
- LCD_PutString(0,2,MainMenu[9]);
- if(!KEY_Esc)
- {
- ESC();
- }
- }
- /*------------------------------------
- Menu2設置時間子菜單處理
- ------------------------------------*/
- void Menu2_Pro()
- {
- LCD_PutString(0,2,MainMenu[1]);
- if(!KEY_Esc)
- {
- ESC();
- }
- }
- /*------------------------------------
- Menu3設置時間子菜單處理
- ------------------------------------*/
- void Menu3_Pro()
- {
- LCD_PutString(0,2,MainMenu[5]);
- if(!KEY_Esc)
- {
- ESC();
- }
- }
- /***********************************************
- MAIN
- ***********************************************/
- void main()
- {
- Init_ST7920();
- CGRAM(); //寫入自定義字符
- DisplayUpdata();
- while(1)
- {
- MainMenu_Pro();
- while(Enter_Menu) //進入子菜單標簽
- {
- // if(Menu0) Menu0_Pro(); //子菜單0處理函數
- // else
- if(Menu1) Menu1_Pro();
- else if(Menu2) Menu2_Pro();
- else if(Menu3) Menu3_Pro();
- // else if(Menu4) Menu4_Pro();
- // else if(Menu5) Menu5_Pro();
- }
- }
- }
復制代碼
|