采用51單片機(jī)設(shè)計(jì)門(mén)禁系統(tǒng),4X4鍵盤(pán)用戶(hù)輸入密碼,錯(cuò)誤蜂鳴器叫一聲,正確LED閃爍,12864作為用戶(hù)界面,初始顯示“歡迎光臨”,正確與錯(cuò)誤時(shí)12864有相應(yīng)的提示。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (17.78 KB, 下載次數(shù): 119)
下載附件
2018-10-19 02:29 上傳
單片機(jī)源程序如下:
- #include <reg51.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define _nop {} //空操作
- #define PAGEADD 0xb8 //頁(yè)地址起始
- #define TIERADD 0x40 //行地址起始
- #define DIS_STARADD 0xc0 //開(kāi)始命令
- uchar row,column,c;
-
- sbit CS2 = P3 ^ 3;
- sbit CS1 = P3 ^ 4;
- sbit E = P3 ^ 5; //定義使能端
- sbit RW = P3 ^ 6;
- sbit DI = P3 ^ 7;
-
- sbit INT = P3 ^ 2; //外部中斷0引腳
- sbit buzzer = P3 ^ 0;
- sbit P3_1 = P3 ^ 1;
- sbit LED = P3 ^ 1;
-
- uchar flog = 0;
- uchar flog1 = 0;
- //鍵值數(shù)組
- uchar cc[] = {0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77};
- /****************************
- 漢字顯示
- *****************************/
- uchar code table2[] = { //加code在ROM
- //-- 密 --
- 0x10,0x4C,0x24,0x04,0xF4,0x84,0x4D,0x56,0x24,0x24,0x14,0x84,0x24,0x54,0x0C,0x00,//16字節(jié)
- 0x00,0x01,0xFD,0x41,0x40,0x41,0x41,0x7F,0x41,0x41,0x41,0x41,0xFC,0x00,0x00,0x00,
- //-- 碼 --
- 0x02,0x82,0xF2,0x4E,0x43,0xE2,0x42,0xFA,0x02,0x02,0x02,0xFF,0x02,0x80,0x00,0x00,
- 0x01,0x00,0x7F,0x20,0x20,0x7F,0x08,0x09,0x09,0x09,0x0D,0x49,0x81,0x7F,0x01,0x00,
- //-- 正 --
- 0x00,0x02,0x02,0xC2,0x02,0x02,0x02,0xFE,0x82,0x82,0x82,0xC2,0x83,0x02,0x00,0x00,
- 0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x40,0x40,0x60,0x40,0x00,
- //-- 確 --
- 0x04,0x84,0xE4,0x9C,0x84,0xC6,0x24,0xF0,0x28,0x27,0xF4,0x2C,0x24,0xF0,0x20,0x00,
- 0x01,0x00,0x7F,0x20,0x20,0xBF,0x40,0x3F,0x09,0x09,0x7F,0x09,0x89,0xFF,0x00,0x00, //半個(gè)屏
- //-- 歡 --
- 0x04, 0x34, 0xC4, 0x04, 0xC4, 0x3C, 0x20, 0x10, 0x0F, 0xE8, 0x08, 0x08, 0x28, 0x18, 0x00, 0x00,
- 0x10, 0x08, 0x06, 0x01, 0x82, 0x8C, 0x40, 0x30, 0x0C, 0x03, 0x0C, 0x10, 0x60, 0xC0, 0x40, 0x00,
- //-- 迎 --
- 0x40, 0x42, 0x44, 0xC8, 0x00, 0xFC, 0x04, 0x02, 0x82, 0xFC, 0x04, 0x04, 0x04, 0xFE, 0x04, 0x00,
- 0x00, 0x40, 0x20, 0x1F, 0x20, 0x47, 0x42, 0x41, 0x40, 0x7F, 0x40, 0x42, 0x44, 0x63, 0x20, 0x00,
- //-- 光 --
- 0x40, 0x40, 0x42, 0x44, 0x58, 0xC0, 0x40, 0x7F, 0x40, 0xC0, 0x50, 0x48, 0x46, 0x64, 0x40, 0x00,
- 0x00, 0x80, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x40, 0x40, 0x40, 0x70, 0x00,
- //-- 臨 --
- 0x00, 0xFC, 0x00, 0xFF, 0x40, 0x20, 0x10, 0x0C, 0x2B, 0x48, 0xC8, 0x08, 0x08, 0x8C, 0x08, 0x00,
- 0x00, 0x1F, 0x00, 0xFF, 0x00, 0xFF, 0x41, 0x41, 0x41, 0x7F, 0x41, 0x41, 0x41, 0xFF, 0x01, 0x00,
- //-- 密 --
- 0x10, 0x4C, 0x24, 0x04, 0xF4, 0x84, 0x4D, 0x56, 0x24, 0x24, 0x14, 0x84, 0x24, 0x54, 0x0C, 0x00,
- 0x00, 0x01, 0xFD, 0x41, 0x40, 0x41, 0x41, 0x7F, 0x41, 0x41, 0x41, 0x41, 0xFC, 0x00, 0x00, 0x00,
- //-- 碼 --
- 0x02, 0x82, 0xF2, 0x4E, 0x43, 0xE2, 0x42, 0xFA, 0x02, 0x02, 0x02, 0xFF, 0x02, 0x80, 0x00, 0x00,
- 0x01, 0x00, 0x7F, 0x20, 0x20, 0x7F, 0x08, 0x09, 0x09, 0x09, 0x0D, 0x49, 0x81, 0x7F, 0x01, 0x00,
- //-- 錯(cuò) --
- 0x80, 0x40, 0x70, 0xCF, 0x48, 0x48, 0x48, 0x48, 0x7F, 0x48, 0x48, 0x7F, 0xC8, 0x68, 0x40, 0x00,
- 0x00, 0x02, 0x02, 0x7F, 0x22, 0x12, 0x00, 0xFF, 0x49, 0x49, 0x49, 0x49, 0xFF, 0x01, 0x00, 0x00,
- //-- 誤 --
- 0x40, 0x42, 0xC4, 0x0C, 0x00, 0x40, 0x5E, 0x52, 0x52, 0xD2, 0x52, 0x52, 0x5F, 0x42, 0x00, 0x00,
- 0x00, 0x00, 0x7F, 0x20, 0x12, 0x82, 0x42, 0x22, 0x1A, 0x07, 0x1A, 0x22, 0x42, 0xC3, 0x42, 0x00,
- };
- //延遲函數(shù)
- void Delay_nms(uchar n)
- {
- uchar a;
- for (; n>0; n--)
- for (a = 0; a<100; a++);
- }
- //檢查狀態(tài)
- void LCD_Busy()
- {
- uchar busy;
- E = 0; //RW=1,E信號(hào)下降沿鎖存DB7~DB0;RW=1,E=1,DDRAM數(shù)據(jù)讀到DB7~DB0
- DI = 0; //DB7~DB0為指令數(shù)據(jù)
- RW = 1;
- while (1)
- {
- E = 1; //DDRAM數(shù)據(jù)讀到DB7~DB0
- _nop;
- _nop;
- busy = P2;//讀狀態(tài)標(biāo)志寄存器
- _nop;
- E = 0; // 下降沿鎖存DB7~DB0
- if ((busy & 0x90) == 0)//檢測(cè)BF和RST(復(fù)位重啟)位,兩者都為零時(shí)表示可以進(jìn)行寫(xiě)入
- break;
- }
- }
- //左屏輸入指令
- void WRCommand_L(uchar command)
- {
- CS1 = 1;
- CS2 = 0;
- LCD_Busy(); //檢查狀態(tài)
- DI = 0; //DB7~DB0為指令數(shù)據(jù)
- _nop;
- RW = 0;
- _nop;
- E = 1;
- _nop;
- P2 = command;
- _nop;
- E = 0; //RW=0,E下降沿?cái)?shù)據(jù)寫(xiě)到DB7~DB0
- _nop;
- }
- //右屏輸入指令
- void WRCommand_R(uchar command)
- {
- CS1 = 0;
- CS2 = 1;
- LCD_Busy();
- DI = 0;//指令
- _nop;
- RW = 0; //寫(xiě)
- _nop;
- E = 1;
- _nop;
- P2 = command;
- _nop;
- E = 0;
- _nop;
- }
- //左屏輸入數(shù)據(jù) (寫(xiě)一個(gè)字節(jié)的顯示數(shù)據(jù))
- void WRdata_L(uchar ucdata)
- {
- CS1 = 1;
- CS2 =0;
- LCD_Busy();
- DI = 1; //DB7~DB0為顯示數(shù)據(jù)
- _nop;
- RW = 0;
- _nop;
- E = 1;
- _nop;
- P2 = ucdata;
- _nop;
- E = 0;
- _nop;
- }
- //右屏輸入數(shù)據(jù)
- void WRdata_R(uchar ucdata)
- {
- CS1 =0;
- CS2 = 1;
- LCD_Busy();
- DI =1;
- _nop;
- RW = 0;
- _nop;
- E = 1;
- _nop;
- P2 = ucdata;
- _nop;
- E = 0;
- _nop;
- }
- //左屏顯示
- //字符為16*16顯示,分為兩部分寫(xiě)入32字節(jié)。前16個(gè)字節(jié)寫(xiě)入第一頁(yè)(16*8) 后16個(gè)字節(jié)寫(xiě)入第二頁(yè)(16*8)
- void C_display_L(uchar C_Pagenum, uchar C_Tiernum, uchar C_Temp) //C_Pagenum:頁(yè),C_Tiernum:行char C_Temp:第幾個(gè)字符
- {
- uchar k;
- C_Pagenum = PAGEADD | C_Pagenum; //首頁(yè)地址為 0xb8
- C_Tiernum = TIERADD | C_Tiernum; //首行地址為 0x40
- WRCommand_L(C_Pagenum); //左屏輸入
- WRCommand_L(C_Tiernum);
- for (k = 0; k<16; k++)
- {
- WRdata_L(table2[C_Temp * 32 + k]); //左屏輸入數(shù)據(jù)
- };
- C_Pagenum = C_Pagenum + 1; //下頁(yè)
- WRCommand_L(C_Pagenum);
- WRCommand_L(C_Tiernum);
- for (k = 0; k<16; k++)
- {
- WRdata_L(table2[C_Temp * 32 + k + 16]);
- }
- }
- //右屏顯示
- void C_display_R(uchar C_Pagenum, uchar C_Tiernum, uchar C_Temp)
- {
- uchar k;
- C_Pagenum = PAGEADD | C_Pagenum;
- C_Tiernum = TIERADD | C_Tiernum;
- WRCommand_R(C_Pagenum);
- WRCommand_R(C_Tiernum);
- for (k = 0; k<16; k++)
- {
- WRdata_R(table2[C_Temp * 32 + k]);
- }
- C_Pagenum = C_Pagenum + 1;
- WRCommand_R(C_Pagenum);
- WRCommand_R(C_Tiernum);
- for (k = 0; k<16; k++)
- {
- WRdata_R(table2[C_Temp * 32 + k + 16]);
- }
- }
- //清除所有顯示寄存器
- void CLR_DisplayRAM()
- {
- uchar C_page, i, k;
- for (i = 0; i<8; i++)
- {
- C_page = PAGEADD | i;//清除起始頁(yè)為0
- WRCommand_L(C_page); //清除起始頁(yè)寫(xiě)入
- WRCommand_L(TIERADD); //清除起始行地址寫(xiě)入
- WRCommand_R(C_page);
- WRCommand_R(TIERADD);
- for (k = 0; k<64; k++)
- {
- WRdata_L(0x00);
- WRdata_R(0x00); //lcm的ram自動(dòng)加1,只允許循環(huán)64次
- }
- }
- }
- //LCD初始化
- void Init_LCD(void)
- {
- CLR_DisplayRAM();// 清除所有顯示寄存器
- WRCommand_L(DIS_STARADD);
- WRCommand_R(DIS_STARADD);// 設(shè)置顯示起始列地址0xc0
- WRCommand_L(0x3f);
- WRCommand_R(0x3f);
- }
- //延遲函數(shù)
- void delay()
- {
- uchar i;
- uchar j;
- for(i = 0;i < 100;i++)
- {
- for(j = 200;j>0;j--);
- }
- }
- //鍵盤(pán)掃描
- char keyscan()
- {
- uchar cord_h,cord_l;
- uchar key=0;
- P1=0xf0;
- if(P1!=0xf0)
- {
- delay(); //消抖動(dòng)
- if(P1!=0xf0)
- {
- cord_l=P1;
- P1=0x0f;
- cord_h=P1;
- key=cord_l|cord_h; //鍵值
- }
- }
- P1=0xf0;
- return key;
- }
- //密碼輸入成功
- void Pass()
- {
- uchar a = 0, pagenum = 0,i =0;
- LED = 1;
- Init_LCD(); //lcd初始化
- //中文顯示“密碼正確”
- pagenum = 0;//從第一排開(kāi)始顯示
- for (a = 0; a<4; a++)
- {
- C_display_L(pagenum, a * 16, a);
- }
-
- //中文顯示“歡迎光臨”
- pagenum = 2;//從第二排開(kāi)始顯示
- for (a = 0; a<4; a++)
- {
- C_display_R(pagenum, a * 16, a + 4);
- }
- while(1);
- }
- //按鍵中斷(int0)
- void IntoPro() interrupt 0
- {
- uchar a = 0,pagenum = 0,i = 0,key;
- flog1++; //記錄按鍵的次數(shù)
- key=keyscan(); //掃描鍵盤(pán)是否按下
-
- CLR_DisplayRAM(); //清屏
-
- if(key == cc[0]) //判斷第一位密碼是否正確,正確flog++
- {
- flog=flog+1;} //P3_1 = 0;
- if(key == cc[1])
- {if(flog % 3 == 1)
- flog=flog+1;} //P3_1 = 1;
- if(key== cc[2])
- {if(flog % 3 == 2)
- flog=flog+1;} //P3_1 = 0;
- if(key == cc[3])
- {if(flog % 3 == 0)
- {
- P3_1 = 1;Pass(); //顯示密碼正確信 led燈亮
- }
- }
- if(flog1 % 4 == 0) //密碼錯(cuò)誤
- {
- buzzer = 1; //蜂鳴器響
- delay();
- buzzer = 0;
- Init_LCD(); //lcd初始化
- pagenum = 0;//從第一排開(kāi)始顯示
- //顯示按鍵錯(cuò)誤
- for (a = 0; a<4; a++)
- {
- C_display_L(pagenum, a * 16, a + 8);
- }
- }
- }
- void main()
- {
- LED = 0;
- buzzer = 0;//蜂鳴器關(guān)閉
- P1 = 0xf0;
-
- EA = 1; //中斷總允許
- EX0 = 1; //外部中斷0
- IT0 = 1; //下降沿觸發(fā)
-
- while(1);
-
- }
復(fù)制代碼
0.png (45.61 KB, 下載次數(shù): 95)
下載附件
2018-10-19 02:30 上傳
所有資料51hei提供下載:
實(shí)驗(yàn)七.rar
(99.17 KB, 下載次數(shù): 223)
2018-10-18 19:12 上傳
點(diǎn)擊文件名下載附件
內(nèi)含電路圖和代碼 下載積分: 黑幣 -5
|