标题:
基于51单片机的红外遥控简易LCD12864菜单程序(四项 八项)
[打印本页]
作者:
qinqin
时间:
2015-6-6 15:06
标题:
基于51单片机的红外遥控简易LCD12864菜单程序(四项 八项)
本帖最后由 qinqin 于 2015-6-6 15:11 编辑
本程序已通过实际电路测试
四项菜单程序:
#include<reg52.h>
#define uchar unsigned char
sbit rs=P1^0; // lcd12864 RS端
sbit rw=P1^1; // lcd12864 RW端
sbit en=P1^2; // lcd12864 EN端
sbit ultra_red=P3^3; //红外接受端
uchar cc=0; //指针
uchar dat[4]; //红外线信号数据存放单元:dat[0]存放用户码;dat[1]存放用户反码;dat[2]存放数据码;dat[3]存放数据反码。
bit r; //指针
uchar code user1[]={"北京城市学院"};
uchar code user2[]={"08级本科"};
uchar code user3[]={"微电子"};
uchar code user4[]={"王云"};
uchar code table1[]={"菜单1 "};
uchar code table2[]={"菜单2 "};
uchar code table3[]={"菜单3 "};
uchar code table4[]={"菜单4 "};
uchar code tt1[]={0x08,0x20,0x08,0x20,0xFF,0xFE,0x08,0x20,0x00,0x10,0x00,0xF8,0x3F,0x00,0x11,0x10,
0x08,0x20,0x01,0x00,0x7F,0xFC,0x05,0x40,0x09,0x20,0x31,0x18,0xC1,0x06,0x01,0x00,}; //“菜”
uchar code tt2[]={0x10,0x10,0x08,0x20,0x04,0x40,0x3F,0xF8,0x21,0x08,0x21,0x08,0x3F,0xF8,0x21,0x08,
0x21,0x08,0x3F,0xF8,0x01,0x00,0x01,0x00,0xFF,0xFE,0x01,0x00,0x01,0x00,0x01,0x00};//“单”
uchar code tt3[]={0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x70,0x00,0x10,0x00,0x10,0x00,0x10,0x00,
0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x7C,0x00,0x00,0x00,0x00,0x00};//“1”
uchar code tt4[]={0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x04,0x00,
0x04,0x00,0x08,0x00,0x10,0x00,0x20,0x00,0x42,0x00,0x7E,0x00,0x00,0x00,0x00,0x00};//“2”
uchar code tt5[]={0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x42,0x00,0x42,0x00,0x04,0x00,0x18,0x00,
0x04,0x00,0x02,0x00,0x02,0x00,0x42,0x00,0x44,0x00,0x38,0x00,0x00,0x00,0x00,0x00};//“3”
uchar code tt6[]={0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x0C,0x00,0x14,0x00,0x24,0x00,0x24,0x00,
0x44,0x00,0x44,0x00,0x7E,0x00,0x04,0x00,0x04,0x00,0x1E,0x00,0x00,0x00,0x00,0x00};//“4”
//////////////////////////////////////////////////////// 延时程序
void delay(uchar H,uchar L)
{ TH0=H;TL0=L;
TF0=0;
while(!TF0);
}
////////////////////////////////////////////////// lcd12864写指令程序
void w_comd(uchar dat)
{ en=1;rs=0;rw=0;
P0=dat;
delay(0xff,0xb8);
en=0; // en从1变到0,指令写入
delay(0xff,0xb8);
}
////////////////////////////////////// lcd12864写数据程序
void w_data(uchar dat)
{ en=1;rs=1;rw=0;
P0=dat;
delay(0xff,0xb8);
en=0;// en从1变到0,数据写入
delay(0xff,0xb8);
}
///////////////////////////////////////////////////////// 初始化lcd12864
void set_lcd12864()
{ w_comd(0x01); //清屏
delay(0xee,0x08);
w_comd(0x30); //设定基本指令
w_comd(0x0c);
w_comd(0x06);
w_comd(0x02);
delay(0xee,0x08);
}
///////////////////////////////////////////////////// 显示程序段
void view(uchar addr,uchar *i)
{ w_comd(addr); //写入行列地址
while(*i!='\0') // 指针所指内容不为空循环
{ w_data(*i);
i++;
}
}
/////////////////////////////////////////////////////// cgram数据写入程序段
void cgram_data(uchar addr,uchar *i)
{ uchar a;
w_comd(addr); //地址写入
for(a=0;a<32;a++) //写入32个8位数据
w_data(0xff-(*i++)); //为反白输出,所以此处采用0XFF减原有数据,达到翻白效果
} //(用程序翻白,只能使一三行,或二四行同时翻白)
/////////////////////////////////////////// 显示自定义字符
void cgram_display(uchar addr,uchar z)
{ w_comd(addr); //写入行列地址
w_data(0x00); //不知道为什么,必需得写,不然就会出错
w_data(z); //对应编码写入,编码一定要与写入cgram地址一一对应,不然也会出错
}
/////////////////////////////////////////////////////// 写cgram数据程序
void cgram()
{ view(0x83,table1);
view(0x93,table2);
view(0x8b,table3);
view(0x9b,table4);
w_comd(0x30);
w_comd(0x02);//允许修改cgram地址
delay(0xee,0x08);
switch(cc)
{ case 0: cgram_data(0x40,tt1);
cgram_display(0x83,0x00);
cgram_data(0x50,tt2);
cgram_display(0x84,0x02);
cgram_data(0x60,tt3);
cgram_display(0x85,0x04);
break;
case 1: cgram_data(0x40,tt1);
cgram_display(0x93,0x00);
cgram_data(0x50,tt2);
cgram_display(0x94,0x02);
cgram_data(0x60,tt4);
cgram_display(0x95,0x04);
break;
case 2: cgram_data(0x40,tt1);
cgram_display(0x8b,0x00);
cgram_data(0x50,tt2);
cgram_display(0x8c,0x02);
cgram_data(0x60,tt5);
cgram_display(0x8d,0x04);
break;
case 3: cgram_data(0x40,tt1);
cgram_display(0x9b,0x00);
cgram_data(0x50,tt2);
cgram_display(0x9c,0x02);
cgram_data(0x60,tt6);
cgram_display(0x9d,0x04);
break;
default: break;
}
}
////////////////////////////////////////////
void display()
{ cgram();
}
////////////////////////////////////////////////
void main()
{ uchar i;
TMOD=0x01; //启用定时器0方式1
TR0=1; //启动定时器0
EA=1; //开总中断
set_lcd12864();//初始化LCD12864
view(0x81,user1);
for(i=10;i>0;i--)
delay(0x15,0xa0);
view(0x92,user2);
for(i=10;i>0;i--)
delay(0x15,0xa0);
view(0x8b,user3);
for(i=10;i>0;i--)
delay(0x15,0xa0);
view(0x9b,user4);
for(i=50;i>0;i--)
delay(0x15,0xa0);
w_comd(0x01);
delay(0xee,0x08);
while(1)
{
r=0;
delay(0x3c,0xb0);
display();
dat[4]=0;
EX1=1;
while(!r) // 等待中断
delay(0xff,0x9c);
}
}
//////////////////////////////////////// 红外中断程序
void int1()interrupt 2
{ uchar i,j,n=0;
dat[4]=0;
EX1=0; //必须将中断关闭,否则将无法准确解读
delay(0xf8,0x30);
if(ultra_red) //延时2ms后判断是否为高电平,若是,则跳出中断(红外发射端发射信号以9ms高电平开始,接收端接受信号与发射信号相反)
{ r=1;
delay(0x15,0xa0);
return;
}
while(!ultra_red) delay(0xff,0x9c);//等待9ms低电平
while(ultra_red) delay(0xff,0x9c); //等待4.5ms高电平
for(i=0;i<4;i++)
for(j=0;j<8;j++)
{ while(!ultra_red) delay(0xff,0x9c); //等待0.56ms的低电平区
while(ultra_red)
{ delay(0xff,0x9c); //每0.1ms,指针n自加1
n++;
}
dat[i]>>=1; //最高位写入0
if(n>6) dat[i]=dat[i]|0x80; //若n>6,说明高电平持续时间大于0.56ms,则将高位置1
n=0; //指针清零
}
if(dat[2]==~dat[3]) //若数据码与数据反码的非相同,说明解码成功
{ switch(dat[2])
{ case 0x01: cc=0;break;//根据自己的红外发射器编码
case 0x02: cc=1;break;
case 0x03: cc=2;break;
case 0x04: cc=3;break;
default:break;
}
复制代码
八项菜单程序:
#include<reg52.h>
#define uchar unsigned char
sbit rs=P1^0; // lcd12864 RS端
sbit rw=P1^1; // lcd12864 RW端
sbit en=P1^2; // lcd12864 EN端
sbit ultra_red=P3^3; //红外接受端
uchar cc=0; //指针
uchar dat[4]; //红外线信号数据存放单元:dat[0]存放用户码;dat[1]存放用户反码;dat[2]存放数据码;dat[3]存放数据反码。
bit r; //指针
uchar code user1[]={"北京城市学院"};
uchar code user2[]={"08级本科"};
uchar code user3[]={"微电子"};
uchar code user4[]={"王云"};
uchar code table1[]={"菜单1 "};
uchar code table2[]={"菜单2 "};
uchar code table3[]={"菜单3 "};
uchar code table4[]={"菜单4 "};
uchar code table5[]={"菜单5 "};
uchar code table6[]={"菜单6 "};
uchar code table7[]={"菜单7 "};
uchar code table8[]={"菜单8 "};
uchar code tt1[]={0x08,0x20,0x08,0x20,0xFF,0xFE,0x08,0x20,0x00,0x10,0x00,0xF8,0x3F,0x00,0x11,0x10,
0x08,0x20,0x01,0x00,0x7F,0xFC,0x05,0x40,0x09,0x20,0x31,0x18,0xC1,0x06,0x01,0x00,}; //“菜”
uchar code tt2[]={0x10,0x10,0x08,0x20,0x04,0x40,0x3F,0xF8,0x21,0x08,0x21,0x08,0x3F,0xF8,0x21,0x08,
0x21,0x08,0x3F,0xF8,0x01,0x00,0x01,0x00,0xFF,0xFE,0x01,0x00,0x01,0x00,0x01,0x00};//“单”
uchar code tt3[]={0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x70,0x00,0x10,0x00,0x10,0x00,0x10,0x00,
0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x7C,0x00,0x00,0x00,0x00,0x00};//“1”
uchar code tt4[]={0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x04,0x00,
0x04,0x00,0x08,0x00,0x10,0x00,0x20,0x00,0x42,0x00,0x7E,0x00,0x00,0x00,0x00,0x00};//“2”
uchar code tt5[]={0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x42,0x00,0x42,0x00,0x04,0x00,0x18,0x00,
0x04,0x00,0x02,0x00,0x02,0x00,0x42,0x00,0x44,0x00,0x38,0x00,0x00,0x00,0x00,0x00};//“3”
uchar code tt6[]={0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x0C,0x00,0x14,0x00,0x24,0x00,0x24,0x00,
0x44,0x00,0x44,0x00,0x7E,0x00,0x04,0x00,0x04,0x00,0x1E,0x00,0x00,0x00,0x00,0x00};//“4”
uchar code tt7[]={0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x58,0x00,
0x64,0x00,0x02,0x00,0x02,0x00,0x42,0x00,0x44,0x00,0x38,0x00,0x00,0x00,0x00,0x00,};//"5"
uchar code tt8[]={0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x24,0x00,0x40,0x00,0x40,0x00,0x58,0x00,
0x64,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x24,0x00,0x18,0x00,0x00,0x00,0x00,0x00,};//"6"
uchar code tt9[]={0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x44,0x00,0x44,0x00,0x08,0x00,0x08,0x00,
0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x00,0x00,};//"7"
uchar code tt10[]={0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x24,0x00,
0x18,0x00,0x24,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,};//"8"
//////////////////////////////////////////////////////// 延时程序
void delay(uchar H,uchar L)
{ TH0=H;TL0=L;
TF0=0;
while(!TF0);
}
////////////////////////////////////////////////// lcd12864写指令程序
void w_comd(uchar dat)
{ en=1;rs=0;rw=0;
P0=dat;
delay(0xff,0xb8);
en=0; // en从1变到0,指令写入
delay(0xff,0xb8);
}
////////////////////////////////////// lcd12864写数据程序
void w_data(uchar dat)
{ en=1;rs=1;rw=0;
P0=dat;
delay(0xff,0xb8);
en=0;// en从1变到0,数据写入
delay(0xff,0xb8);
}
///////////////////////////////////////////////////////// 初始化lcd12864
void set_lcd12864()
{ w_comd(0x01); //清屏
delay(0xee,0x08);
w_comd(0x30); //设定基本指令
w_comd(0x0c);
w_comd(0x06);
w_comd(0x02);
delay(0xee,0x08);
}
///////////////////////////////////////////////////// 显示程序段
void view(uchar addr,uchar *i)
{ w_comd(addr); //写入行列地址
while(*i!='\0') // 指针所指内容不为空循环
{ w_data(*i);
i++;
}
}
/////////////////////////////////////////////////////// cgram数据写入程序段
void cgram_data(uchar addr,uchar *i)
{ uchar a;
w_comd(addr); //地址写入
for(a=0;a<32;a++) //写入32个8位数据
w_data(0xff-(*i++)); //为反白输出,所以此处采用0XFF减原有数据,达到翻白效果
} //(用程序翻白,只能使一三行,或二四行同时翻白)
/////////////////////////////////////////// 显示自定义字符
void cgram_display(uchar addr,uchar z)
{ w_comd(addr); //写入行列地址
w_data(0x00); //不知道为什么,必需得写,不然就会出错
w_data(z); //对应编码写入,编码一定要与写入cgram地址一一对应,不然也会出错
}
/////////////////////////////////////////////////////// 写cgram数据程序
void cgram()
{ view(0x80,table1);
view(0x90,table2);
view(0x88,table3);
view(0x98,table4);
view(0x84,table5);
view(0x94,table6);
view(0x8c,table7);
view(0x9c,table8);
w_comd(0x30);
w_comd(0x02);//允许修改cgram地址
delay(0xee,0x08);
switch(cc)
{ case 0: cgram_data(0x40,tt1);
cgram_display(0x80,0x00);
cgram_data(0x50,tt2);
cgram_display(0x81,0x02);
cgram_data(0x60,tt3);
cgram_display(0x82,0x04);
break;
case 1: cgram_data(0x40,tt1);
cgram_display(0x90,0x00);
cgram_data(0x50,tt2);
cgram_display(0x91,0x02);
cgram_data(0x60,tt4);
cgram_display(0x92,0x04);
break;
case 2: cgram_data(0x40,tt1);
cgram_display(0x88,0x00);
cgram_data(0x50,tt2);
cgram_display(0x89,0x02);
cgram_data(0x60,tt5);
cgram_display(0x8a,0x04);
break;
case 3: cgram_data(0x40,tt1);
cgram_display(0x98,0x00);
cgram_data(0x50,tt2);
cgram_display(0x99,0x02);
cgram_data(0x60,tt6);
cgram_display(0x9a,0x04);
break;
case 4: cgram_data(0x40,tt1);
cgram_display(0x84,0x00);
cgram_data(0x50,tt2);
cgram_display(0x85,0x02);
cgram_data(0x60,tt7);
cgram_display(0x86,0x04);
break;
case 5: cgram_data(0x40,tt1);
cgram_display(0x94,0x00);
cgram_data(0x50,tt2);
cgram_display(0x95,0x02);
cgram_data(0x60,tt8);
cgram_display(0x96,0x04);
break;
case 6: cgram_data(0x40,tt1);
cgram_display(0x8c,0x00);
cgram_data(0x50,tt2);
cgram_display(0x8d,0x02);
cgram_data(0x60,tt9);
cgram_display(0x8e,0x04);
break;
case 7: cgram_data(0x40,tt1);
cgram_display(0x9c,0x00);
cgram_data(0x50,tt2);
cgram_display(0x9d,0x02);
cgram_data(0x60,tt10);
cgram_display(0x9e,0x04);
break;
default: break;
}
}
////////////////////////////////////////////
void display()
{ cgram();
}
////////////////////////////////////////////////
void main()
{ uchar i;
TMOD=0x01; //启用定时器0方式1
TR0=1; //启动定时器0
EA=1; //开总中断
set_lcd12864();//初始化LCD12864
view(0x81,user1);
for(i=10;i>0;i--)
delay(0x15,0xa0);
view(0x92,user2);
for(i=10;i>0;i--)
delay(0x15,0xa0);
view(0x8b,user3);
for(i=10;i>0;i--)
delay(0x15,0xa0);
view(0x9b,user4);
for(i=50;i>0;i--)
delay(0x15,0xa0);
w_comd(0x01);
delay(0xee,0x08);
while(1)
{
r=0;
delay(0x3c,0xb0);
display();
dat[4]=0;
EX1=1;
while(!r) // 等待中断
delay(0xff,0x9c);
}
}
//////////////////////////////////////// 红外中断程序
void int1()interrupt 2
{ uchar i,j,n=0;
dat[4]=0;
EX1=0; //必须将中断关闭,否则将无法准确解读
delay(0xf8,0x30);
if(ultra_red) //延时2ms后判断是否为高电平,若是,则跳出中断(红外发射端发射信号以9ms高电平开始,接收端接受信号与发射信号相反)
{ r=1;
delay(0x15,0xa0);
return;
}
while(!ultra_red) delay(0xff,0x9c);//等待9ms低电平
while(ultra_red) delay(0xff,0x9c); //等待4.5ms高电平
for(i=0;i<4;i++)
for(j=0;j<8;j++)
{ while(!ultra_red) delay(0xff,0x9c); //等待0.56ms的低电平区
while(ultra_red)
{ delay(0xff,0x9c); //每0.1ms,指针n自加1
n++;
}
dat[i]>>=1; //最高位写入0
if(n>6) dat[i]=dat[i]|0x80; //若n>6,说明高电平持续时间大于0.56ms,则将高位置1
n=0; //指针清零
}
if(dat[2]==~dat[3]) //若数据码与数据反码的非相同,说明解码成功
{ switch(dat[2])
{ case 0x01: cc=0;break;
case 0x02: cc=1;break;
case 0x03: cc=2;break;
case 0x04: cc=3;break;
case 0x05: cc=4;break;
case 0x06: cc=5;break;
case 0x07: cc=6;break;
case 0x08: cc=7;break;
case 0x09: cc=8;break;
default:break;
}
复制代码
作者:
沉默默
时间:
2015-6-7 17:48
帮顶~~~~~~~~~~~~~~~~~~~~~~~~
作者:
来生只想做头猪
时间:
2018-11-8 09:29
楼主可否打包资料上传给我们看看
作者:
凌净清河
时间:
2018-11-11 19:50
这个程序只是演示作用,楼主并没有预留出功能控制的位置和接口,而且也没有考虑到每一级菜单的长度问题,例如一个菜单是“射频卡管理”这五个字,那么你菜单的位置就放不下啦,同时,多级菜单的思路也没有体现。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1