标题:
12864简易菜单框架单片机源程序 串口通信 带注释
[打印本页]
作者:
兰小方
时间:
2016-12-9 23:51
标题:
12864简易菜单框架单片机源程序 串口通信 带注释
适合初学者看看
串口通信 有加注释,完整代码下载:
菜单程序.zip
(2.65 KB, 下载次数: 62)
2016-12-9 23:50 上传
点击文件名下载附件
简易菜单程序
下载积分: 黑币 -5
预览:
#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();
}
}
}
复制代码
作者:
素食猫爱钓鱼
时间:
2018-11-10 08:54
我要我要我要
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1