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