本帖最后由 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;
- }
复制代码
|