微控制器期末實訓---- 密碼鎖和交通燈
阿新 • • 發佈:2018-11-03
交通燈彙編程式碼:
ORG 0000H LJMP MAIN A_BIT EQU 20H B_BIT EQU 21H C_BIT EQU 22H D_BIT EQU 23H TEMP1 EQU 24H TEMP2 EQU 25H TEMP3 EQU 26H TEMP4 EQU 27H ORG 0003H LJMP INTER0 ORG 0013H LJMP INTER1 ORG 0050H MAIN: ;定義中斷 MOV SP,#60H SETB IT0 ;邊沿觸發 SETB EX0;允許外部中斷0 SETB EX1;允許外部中斷1 SETB EA;允許總中斷 START: MOV R4,#00;初始自由模式還是控制模式 MOV P1,#0FFH MOV P2,#0FFH MOV TEMP1,#10 MOV TEMP2,#15 MOV TEMP3,#15;南北顯示 MOV TEMP4,#10;東西顯示 MOV R3,#20;定時50ms迴圈次數 MOV TMOD,#01H;定時器0方式一 MOV TH0,#3CH MOV TL0,#0B0H SETB TR0;啟動T1 ;南北通行20s SETB P1.5 CLR P1.4 CLR P1.3 SETB P1.0 CLR P1.1 CLR P1.2 SETB P1.7;控制蜂鳴器 ;顯示時間 STL0P0: ;軟體查詢中斷 ACALL TEST ACALL DISPLAY ;呼叫顯示 DEC TEMP1 DEC TEMP2 MOV A,TEMP1 CJNE A,#0,STL0P0 ;南北黃燈通行5s CLR P1.5 SETB P1.4 CLR P1.3 SETB P1.0 CLR P1.1 CLR P1.2 CLR P1.7;控制蜂鳴器 MOV TEMP1,#05 MOV TEMP2,#05 ;顯示時間 STL0P1: ;軟體查詢中斷 ACALL TEST ACALL DISPLAY ;呼叫顯示 DEC TEMP1 DEC TEMP2 MOV A,TEMP1 CJNE A,#0,STL0P1 ;東西向通行5s CLR P1.5 CLR P1.4 SETB P1.3 CLR P1.0 CLR P1.1 SETB P1.2 SETB P1.7 ;顯示時間 STL0P2: ;軟體查詢中斷 ACALL TEST ACALL DISPLAY1 ;呼叫顯示 DEC TEMP3 DEC TEMP4 MOV A,TEMP4 CJNE A,#0,STL0P2 ;東西向黃燈 CLR P1.5 CLR P1.4 SETB P1.3 CLR P1.0 SETB P1.1 CLR P1.2 CLR P1.7;控制蜂鳴器 MOV TEMP3,#05 MOV TEMP4,#05 ;顯示時間 STL0P3: ;軟體查詢中斷 ACALL TEST ACALL DISPLAY1 ;呼叫顯示 DEC TEMP3 DEC TEMP4 MOV A,TEMP4 CJNE A,#0,STL0P3 LJMP MAIN DISPLAY: MOV A,TEMP1; TEMP1,#20H MOV B,#10 DIV AB MOV A_BIT,B MOV B_BIT,A ;B_BIT是十位 MOV A,TEMP2 ; TEMP2,#20H MOV B,#10 DIV AB MOV C_BIT,A MOV D_BIT,B MOV DPTR,#NUMT LP1: ;顯示南北個十位 MOV A,A_BIT MOVC A,@A+DPTR MOV P0,A SETB P2.4 ACALL D1MS CLR P2.4 MOV A,B_BIT MOVC A,@A+DPTR MOV P0,A SETB P2.5 ACALL D1MS CLR P2.5 ;顯示東西個十位 MOV A,D_BIT MOVC A,@A+DPTR MOV P0,A SETB P2.6 ACALL D1MS CLR P2.6 MOV A,C_BIT MOVC A,@A+DPTR MOV P0,A SETB P2.7 ACALL D1MS CLR P2.7 ;查詢計數溢位 JBC TF0,LP2 SJMP LP1 LP2: MOV TH0,#03CH MOV TL0,#0B0H ;軟體查詢中斷 ACALL TEST DJNZ R3,LP1 ;未到1S,繼續迴圈,20*50MS=1000MS=1S MOV R3,#20 RET DISPLAY1: MOV A,TEMP3 MOV B,#10 DIV AB MOV A_BIT,B MOV B_BIT,A MOV A,TEMP4 MOV B,#10 DIV AB MOV C_BIT,A MOV D_BIT,B MOV DPTR,#NUMT LP3: ;顯示南北個十位 MOV A,A_BIT MOVC A,@A+DPTR MOV P0,A SETB P2.4 ACALL D1MS CLR P2.4 MOV A,B_BIT MOVC A,@A+DPTR MOV P0,A SETB P2.5 ACALL D1MS CLR P2.5 ;顯示東西個十位 MOV A,D_BIT MOVC A,@A+DPTR MOV P0,A SETB P2.6 ACALL D1MS CLR P2.6 MOV A,C_BIT MOVC A,@A+DPTR MOV P0,A SETB P2.7 ACALL D1MS CLR P2.7 ;查詢計數溢位 JBC TF0,LP4 SJMP LP3 LP4: MOV TH0,#03CH MOV TL0,#0B0H ;軟體查詢中斷 ACALL TEST DJNZ R3,LP3 ;未到1S,繼續迴圈,20*50MS=1000MS=1S MOV R3,#20 RET INTER0: MOV R4,#01 RETI ;中斷返回 INTER1: MOV R4,#00 RETI START1: ;南北通行 SETB P1.5 CLR P1.4 CLR P1.3 SETB P1.0 CLR P1.1 CLR P1.2 RET START2: ;東北通行 CLR P1.5 CLR P1.4 SETB P1.3 CLR P1.0 CLR P1.1 SETB P1.2 RET K1K: ACALL START2 SJMP KEY1 ;選擇模式 KEY0: CJNE R4,#01,K1K;當R4=00或02是東西通行 ACALL START1;當01是南北通行 KEY1: ACALL DELAY1 ;軟體查詢中斷 MOV P3,#0FFH MOV A,P3 CJNE A,#0FFH,PL1 SJMP KEY0 PL1: ACALL DELAY1 MOV P3,#0FFH MOV A,P3 CJNE A,#0FFH,PL2 SJMP KEY0 PL2: JNB ACC.4,K8K;定義多一個k8k,目的要遠距離地址呼叫,如果直接跳到START,會出現address out range SJMP KEY0 K8K: LJMP START ;K0軟體查詢 TEST: MOV P3,#0FFH MOV A,P3 CJNE A,#0FFH,L2P1 RET L2P1: ACALL DELAY1 MOV P3,#0FFH MOV A,P3 CJNE A,#0FFH,L2P2 RET L2P2: JNB ACC.4,KEY0 RET D1MS: MOV R7,#250 DJNZ R7,$ RET DELAY1: MOV R5,#255 D1: MOV R6,#255 DJNZ R6,$ DJNZ R5,D1 RET NUMT: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH NUMT1: DB 0C0H,0f9H,0a4H,0b0H,99H,92H,82H,0f8H,80H,90H END
C語言版:
/************************************************************************************** * 交通燈實驗 * 實現現象:下載程式後,按照視訊操作正確接線,呈現交通燈現象 注意事項: ***************************************************************************************/ #include "reg52.h" //此檔案中定義了微控制器的一些特殊功能暫存器 typedef unsigned int u16; //對資料型別進行宣告定義 typedef unsigned char u8; static u16 R4=0; // static u16 flag=0; //模式切換標誌位 //--定義使用的IO口--// #define GPIO_DIG P0 #define GPIO_TRAFFIC P1 sbit P25 = P2^5; sbit P24 = P2^4; sbit P10 = P1^0; sbit P11 = P1^1; sbit P12 = P1^2; sbit P13 = P1^3; sbit P14 = P1^4; sbit P15 = P1^5; sbit P17 = P1^7; //中斷 sbit P32 = P3^2; sbit P33 = P3^3; sbit P34 = P3^4; u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//顯示0~F的值 u8 DisplayData[8]; u8 Second; int interr_P33(); void _mode(); void west_east(); void north_th(); /******************************************************************************* * 函 數 名 : delay * 函式功能 : 延時函式,i=1時,大約延時10us *******************************************************************************/ void delay(u16 i) { while(i--); } /******************************************************************************* * 函 數 名 : DigDisplay * 函式功能 : 數碼管動態掃描函式,迴圈掃描8個數碼管顯示 *******************************************************************************/ void DigDisplay() { u8 i; for(i=0;i<2;i++) { switch(i) //位選,選擇點亮的數碼管, { case(0): P25=1; P24=0 ; break;//顯示第0位 case(1): P24=1; P25=0; break;//顯示第1位 } GPIO_DIG=DisplayData[i];//傳送段碼 delay(100); //間隔一段時間掃描 GPIO_DIG=0x00;//消隱 } } /******************************************************************************* * 函 數 名 : Timer0Init * 函式功能 : 定時器0初始化 * 輸 入 : 無 * 輸 出 : 無 *******************************************************************************/ void Timer0Init() { TMOD|=0X01;//選擇為定時器0模式,工作方式1,僅用TR0開啟啟動。 TH0=0X3C; //給定時器賦初值,定時1ms TL0=0X0B0; ET0=1;//開啟定時器0中斷允許 IT0=1;//邊沿觸發 EX0=1;//允許外部中斷0 EX1=1;//允許外部中斷1 EA=1;//開啟總中斷 TR0=1;//開啟定時器 } /******************************************************************************* * 函 數 名 : main * 函式功能 : 主函式 * 輸 入 : 無 * 輸 出 : 無 *******************************************************************************/ void main() { Second = 1; Timer0Init(); while(1) { if(Second == 78) { Second = 1; } //--東西通行,10秒--// if(flag==0) { if(Second < 35) { DisplayData[1] = smgduan[( 34- Second) % 100 / 10]; DisplayData[0] = smgduan[(34 - Second) %10]; DigDisplay(); //--東西通行--// GPIO_TRAFFIC = 0x00; //將所有的燈熄滅 P12 = 1; P11 = 0; P10 = 0; //南北紅燈 P13= 1; // P14= 0; // P15 = 0; // P17 = 1;//蜂鳴器關閉 } //--黃燈等待切換狀態,5秒--// else if( Second < 40) { DisplayData[1] = smgduan[( 39- Second) % 100 / 10]; DisplayData[0] = smgduan[(39 - Second) %10]; DigDisplay(); //--黃燈階段--// GPIO_TRAFFIC = 0x00; //將所有的燈熄滅 P12 = 0; P11 = 1; P10 = 0; //南北紅燈 P13= 1; // P14= 0; // P15 = 0; // P17 = 0;//蜂鳴器開啟 } //--南北通行--// else if( Second < 74) { DisplayData[1] = smgduan[( 73- Second) % 100 / 10]; DisplayData[0] = smgduan[( 73 - Second) %10]; DigDisplay(); //--東西紅燈階段--// GPIO_TRAFFIC = 0x00; //將所有的燈熄滅 P12 = 0; P11 = 0; P10 = 1; //南北綠燈 P13= 0; // P14= 0; // P15= 1; // P17 = 1;//蜂鳴器關閉 } //--黃燈等待切換狀態,5秒--// else if( Second < 79) { DisplayData[1] = smgduan[( 78- Second) % 100 / 10]; DisplayData[0] = smgduan[(78 - Second) %10]; DigDisplay(); //--東西紅燈--// GPIO_TRAFFIC = 0x00; //將所有的燈熄滅 P12 = 0; P11 = 0; P10 = 1; //南北黃燈 P13= 0; // P14= 1; // P15= 0; // P17 = 0;//蜂鳴器開啟 } } else if(flag==1) { _mode(); P17 = 1;//蜂鳴器關閉 } interr_P33(); //每50ms掃描P3^4 } } /******************************************************************************* * 函 數 名 : Int0() interrupt 0 * 函式功能 : 外部中斷0的中斷函式 * 輸 入 : 無 * 輸 出 : 無 *******************************************************************************/ void Int0() interrupt 0 { delay(1000); if(P32==0) { R4=1;//東西通行 } } /******************************************************************************* * 函 數 名 : Int1() interrupt 0 * 函式功能 : 外部中斷1的中斷函式 * 輸 入 : 無 * 輸 出 : 無 *******************************************************************************/ void Int2() interrupt 2 { delay(1000); if(P33==0) { R4=0;//南北通行 } } //程式掃描埠中斷 int interr_P33() { if(P34==0) { delay(1000); if(P34==1) { return 0; } else { TR0 = !TR0; flag=!flag; while(P34==0) ; return 0 ; } } return 0 ; } //自由模式 void _mode() { if(R4==0) west_east(); else if(R4==1) north_th(); } /******************************************************************************* * 函 數 名 : void Timer0() interrupt 1 * 函式功能 : 定時器0中斷函式 * 輸 入 : 無 * 輸 出 : 無 *******************************************************************************/ void Timer0() interrupt 1 { static u16 i; TH0=0X3C; //給定時器賦初值,定時50ms TL0=0X0B0; i++; if(i==20) { i=0; Second ++; } } //東西通行 void west_east() { //--東西通行--// P12 = 1; P11 = 0; P10 = 0; //南北紅燈 P13= 1; // P14= 0; // P15 = 0; // } //南北通行 void north_th() { //--東西紅燈階段--// P12 = 0; P11 = 0; P10 = 1; //南北綠燈 P13= 0; // P14= 0; // P15= 1; // }
密碼鎖彙編程式碼:
ORG 0000H LJMP MAIN ;定義EEPROM特殊功能暫存器 ISP_DATA DATA 0E2H ISP_ADDRH DATA 0E3H ISP_ADDRL DATA 0E4H ISP_CMD DATA 0E5H ISP_TRIG DATA 0E6H ISP_CONTR DATA 0E7H ;定義ISP/IAP命令及等待時間 ISP_IAP_BYTE_READ EQU 1 ISP_IAP_BYTE_PROGRAM EQU 2 ISP_IAP_SECTOR_ERASE EQU 3 WAIT_TIME EQU 0 ;----89c51引腳定義----- TEMP EQU 20H RS EQU P3.7 RW EQU P3.6 E EQU P3.5 TIME EQU 23H PASSWORD EQU 2000H;EEROM起始地址 ORG 0070H MAIN: ACALL LCD MOV TEMP,#0AH MOV R4,#0;初始8位密碼輸入 MOV P2,#00H SETB P2.2 MOV 25H,#50H;初始儲存密碼起始地址 MOV 26H,#0 MOV R6,#0;修改密碼標誌位 ;時鐘定時初始 MOV TMOD,#01H MOV TH0,#3CH MOV TL0,#0B0H ACALL DISPLAYINPUT MOV 40H,#0 KEYSCAN: MOV P1,#0FFH MOV P1,#0F0H;設定高位為行線,低位為列線 MOV A,P1 CJNE A,#0F0H,M;判斷是否有鍵按下,有延時去抖動 SJMP KEYSCAN M: ;去抖動 ACALL DELAY MOV P1,#0F0H MOV A,P1 CJNE A,#0F0H,MM;判斷是否有鍵還在按下, SJMP KEYSCAN MM: MOV 21H,A;行為輸入,並記錄 MOV P1,#0FH;設定列線為輸入 MOV 31H,P1 ;等按鍵鬆開 MMM: MOV P1,#0F0H MOV A,P1 CJNE A,#0F0H,MMM ;查詢行號 MOV A,21H JNB ACC.4,E1 JNB ACC.5,E2 JNB ACC.6,E3 JNB ACC.7,E4 ;設定行號初值 E1: MOV 22H,#0 LJMP KEYH E2: MOV 22H,#4 LJMP KEYH E3: MOV 22H,#8 LJMP KEYH E4: MOV 22H,#0CH LJMP KEYRESET ;查詢列好 KEYH: MOV A,31H JNB ACC.0,D0 JNB ACC.1,D1 JNB ACC.2,D2 JNB ACC.3,D3 ;計算鍵值 D0: CJNE R4,#8,CONTINUE;不等繼續輸,每輸入一位,減一 LJMP PASS CONTINUE: MOV A,25H ADD A,R4 ;R2儲存密碼的地址 MOV R0,A MOV A,#0 ADD A,22H MOV @R0,A ;儲存當前輸入值 MOV TEMP,A ACALL DISPLAYNUM;顯示當前輸入值 INC R4 CJNE R4,#8,RETURN LJMP PASS D1: CJNE R4,#8,CONTINUE1;不等繼續輸,每輸入一位,減一 LJMP PASS CONTINUE1: MOV A,25H ADD A,R4 ;R2儲存密碼的地址 MOV R0,A MOV A,#1 ADD A,22H MOV @R0,A ;儲存當前輸入值 MOV TEMP,A ACALL DISPLAYNUM;顯示當前輸入值 INC R4 CJNE R4,#8,RETURN LJMP PASS D2: MOV A,#2 ADD A,22H CJNE A,#0AH,DD2;符合第三行 SJMP DELETE DD2: CJNE R4,#8,CONTINUE2;不等繼續輸,每輸入一位,減一 LJMP PASS CONTINUE2: MOV A,25H ADD A,R4 ;R2儲存密碼的地址 MOV R0,A MOV A,#2 ADD A,22H MOV @R0,A ;儲存當前輸入值 MOV TEMP,A ACALL DISPLAYNUM;顯示當前輸入值 INC R4 CJNE R4,#8,RETURN LJMP PASS D3: MOV A,#3 ADD A,22H CJNE A,#0BH,DD3;符合第三行 LJMP ENTER DD3: CJNE R4,#8,CONTINUE3;不等繼續輸,每輸入一位,減一 LJMP PASS CONTINUE3: MOV A,25H ADD A,R4 ;R2儲存密碼的地址 MOV R0,A MOV A,#3 ADD A,22H MOV @R0,A ;儲存當前輸入值 MOV TEMP,A ACALL DISPLAYNUM;顯示當前輸入值 INC R4 CJNE R4,#8,RETURN LJMP PASS RETURN: ACALL DISPLAYINPUT LJMP KEYSCAN KEYRESET: MOV A,31H JNB ACC.0,SET0 JNB ACC.1,NOSET SET0:;修改密碼 MOV A,26H JNZ SET2;判斷是否進入密碼確定狀態 LJMP KEYSCAN SET2: ACALL DISPASSWORDRESET ACALL DELAYTIME MOV R4,#0;使能鍵盤能正常輸入 MOV 25H,#60H; MOV R6,#1;進入密碼修改狀態 ACALL DISPLAYCLL LJMP KEYSCAN NOSET: MOV A,40H CJNE A,#1,NOSET2 MOV A,26H JNZ NOSET1;判斷是否進入密碼確定狀態 NOSET2: LJMP KEYSCAN NOSET1: LJMP MAIN ;按了delete DELETE: CJNE R4,#0,DELETE2 LJMP KEYSCAN DELETE2: CJNE R4,#8,DELETE3 LJMP KEYSCAN;如果等於8,就是沒有輸入任何密碼來 DELETE3: MOV TEMP,#0AH ACALL DISPLAYNUM DEC R4 MOV R0,25H MOV A,R4 ADD A,R0 ;R2儲存密碼的地址 MOV R0,A MOV @R0,#0 ;刪了密碼,需要顯示器重新顯示 ACALL DISPLAYNUM ACALL BUSY MOV A,#83H ADD A,R4 MOV P0,A;第一韓第三個位置 ACALL ENABLE LJMP KEYSCAN ;密碼修改 PASSRESETOK: ACALL DISPLAYRESETOK MOV 25H,#50H;恢復儲存地址 MOV R6,#0;退出密碼修改狀態 ACALL PASSSAVE ACALL DELAYTIME;延時3s MOV 26H,#0;退出密碼修改狀態 LJMP MAIN ;使用者按了enter ENTER: CJNE R4,#8,RETURN;不等於8,跳轉 CJNE R6,#0,PASSRESETOK ;按了確認鍵就會跳轉到這裡 PASSMATCH: MOV R3,#0 ACALL ISP_READ MOV R0,#50H MOV R1,#60H MATCH: MOV A,@R0 MOV B,@R1 CLR C SUBB A,B JNZ MATCHNO INC R0 INC R1 CJNE R0,#59H,MATCH SJMP MATCHYES PASSSAVE: ACALL ISP_ERASE ACALL ISP_WRITE RET MATCHYES: ACALL DISPLAYTRUE MOV TIME,#0 SETB P2.0 CLR P2.1 MOV 26H,#1;密碼輸入正確狀態 ACALL DELAYTIME ACALL DOYOUSET MOV 40H,#1 ACALL YESORNO LJMP KEYSCAN MATCHNO: ACALL DISPLAYFALSE SETB P2.1 CLR P2.0 CLR P2.2 ACALL DELAYTIME CLR TR0 SETB P2.2 LJMP MAIN ;使用者輸入了8個密碼,繼續按其他數字按鍵無效 PASS: MOV A,26H JNZ LPL ACALL DISPLAYENTER LJMP KEYSCAN LPL: CJNE R6,#1,LPL2 ACALL DISPLAYENTER LJMP KEYSCAN LPL2: ACALL DISPLAYTRUE LJMP KEYSCAN DELAYTIME: ;顯示3s,開定時中斷 MOV R5,#60 SETB TR0 MOV TH0,#03CH MOV TL0,#0B0H SECOND: JBC TF0,SECOND1 SJMP SECOND SECOND1: MOV TH0,#03CH MOV TL0,#0B0H DJNZ R5,SECOND RET DISPLAYENTER:;顯示please enter MOV R7,#10H MOV DPTR,#PLEASEENTER ACALL BUSY MOV A,#0C0H MOV P0,A;第一韓第三個位置 ACALL ENABLE LOOP4: MOV A,#00H MOVC A,@A+DPTR ACALL BUSY MOV P0,A ACALL DATAS;顯示資料 INC DPTR DJNZ R7,LOOP4;顯示完之後就跳轉 RET DISPLAYNUM:;顯示數字的 ACALL BUSY MOV A,#84H ADD A,R4 MOV P0,A;第一韓第三個位置 ACALL ENABLE MOV DPTR,#NUMBER ACALL BUSY MOV A,TEMP MOVC A,@A+DPTR MOV P0,A ACALL DATAS;顯示資料 RET DISPLAYCLL: ACALL BUSY MOV A,#80H CLL: INC A MOV P0,A;第一韓第三個位置 ACALL ENABLE ACALL BUSY MOV P0,#20H ACALL DATAS;顯示資料 CJNE A,#90H,CLL ACALL BUSY MOV A,#84H ADD A,R4 MOV P0,A;第一韓第三個位置 ACALL ENABLE RET DISPLAYINPUT:;顯示input password MOV R7,#10H MOV DPTR,#INPUTPASSWORD ACALL BUSY MOV A,#0C0H MOV P0,A;第一韓第三個位置 ACALL ENABLE LOOP1: MOV A,#00H MOVC A,@A+DPTR ACALL BUSY MOV P0,A ACALL DATAS;顯示資料 INC DPTR DJNZ R7,LOOP1;顯示完之後就跳轉 RET DISPLAYTRUE:;password TRUE MOV R7,#10H MOV DPTR,#PASSWORDTRUE ACALL BUSY MOV A,#0C0H MOV P0,A;第一韓第三個位置 ACALL ENABLE LOOP2: MOV A,#00H MOVC A,@A+DPTR ACALL BUSY MOV P0,A ACALL DATAS;顯示資料 INC DPTR DJNZ R7,LOOP2;顯示完之後就跳轉 RET DISPLAYFALSE:;password FALSE MOV R7,#10H MOV DPTR,#PASSWORDFALSE ACALL BUSY MOV A,#0C0H MOV P0,A;第一韓第三個位置 ACALL ENABLE LOOP3: MOV A,#00H MOVC A,@A+DPTR ACALL BUSY MOV P0,A ACALL DATAS;顯示資料 INC DPTR CJNE R7,#01H,RELOOP3 SJMP DISFALSETIME RELOOP3: DJNZ R7,LOOP3;顯示完之後就跳轉 RET DISFALSETIME: ACALL BUSY MOV A,#0CFH MOV P0,A;第一韓第三個位置 ACALL ENABLE INC TIME;輸入錯誤一次,加一 MOV DPTR,#NUMBER MOV A,TIME MOVC A,@A+DPTR ACALL BUSY MOV P0,A ACALL DATAS;顯示資料 SJMP RELOOP3 DISPASSWORDRESET:;顯示修改密碼 MOV R7,#10H MOV DPTR,#PASSWORDRESET ACALL BUSY MOV A,#0C0H MOV P0,A;第一韓第三個位置 ACALL ENABLE LOOP6: MOV A,#00H MOVC A,@A+DPTR ACALL BUSY MOV P0,A ACALL DATAS;顯示資料 INC DPTR DJNZ R7,LOOP6;顯示完之後就跳轉 RET DISPLAYRESETOK: MOV R7,#10H MOV DPTR,#PLAYRESETOK ACALL BUSY MOV A,#0C0H MOV P0,A;第一韓第三個位置 ACALL ENABLE LOOP9: MOV A,#00H MOVC A,@A+DPTR ACALL BUSY MOV P0,A ACALL DATAS;顯示資料 INC DPTR DJNZ R7,LOOP9;顯示完之後就跳轉 RET LCD: MOV R0,#8 ACALL BUSY MOV P0,#00000001B ACALL ENABLE ACALL BUSY MOV P0,#00111100B ACALL ENABLE ACALL BUSY MOV P0,#00001111B ACALL ENABLE ACALL BUSY MOV P0,#00000110B ACALL ENABLE RET DOYOUSET: MOV R7,#10H MOV DPTR,#DOYOUSETTAB ACALL BUSY MOV A,#080H MOV P0,A;第一韓第三個位置 ACALL ENABLE LOOP22: MOV A,#00H MOVC A,@A+DPTR ACALL BUSY MOV P0,A ACALL DATAS;顯示資料 INC DPTR DJNZ R7,LOOP22;顯示完之後就跳轉 RET YESORNO: MOV R7,#10H MOV DPTR,#YESORNOTAB ACALL BUSY MOV A,#0C0H MOV P0,A;第一韓第三個位置 ACALL ENABLE LOOP11: MOV A,#00H MOVC A,@A+DPTR ACALL BUSY MOV P0,A ACALL DATAS;顯示資料 INC DPTR DJNZ R7,LOOP11;顯示完之後就跳轉 RET ENABLE: SETB E;E端為使能端,當E端由高電平跳變成低電平時,液晶模組執行命令。 CLR RS;RS和RW都為0,就是對應那些指令執行 CLR RW;RW為1就是讀,為0就是寫 CLR E RET BUSY: CLR E MOV P0,#0FFH; CLR RS;RS為0和RW為1,就是讀取忙標誌AC地址內容的指令執行,RW為1就是讀,為0就是寫 SETB RW SETB E;E從0到1變化,看時序圖就能明白 JB P0.7,BUSY;如果p1.7為高電平表示忙綠就迴圈等待,忙標誌位,高電平表示忙,此時模組不能接收命令或資料,如果為低電平表示不忙。 RET DATAS: SETB E SETB RS CLR RW CLR E RET DELAY: MOV R2,#3 DE: MOV R3,#255 DJNZ R3,$ DJNZ R2,DE RET ;位元組讀 ISP_READ: MOV 29H,#9 MOV 27H,#60H MOV 28h,#00H READLP: MOV ISP_ADDRH,#20h ;地址高位元組 MOV ISP_ADDRL,28H ;地址低位元組 CLR EA MOV ISP_CONTR,#WAIT_TIME MOV ISP_CONTR,#10000000B MOV ISP_CMD,#ISP_IAP_BYTE_READ MOV ISP_TRIG,#46H MOV ISP_TRIG,#0B9H NOP MOV A,ISP_DATA SUBB A,#10 JC READLP2 MOV A,#00 MOV ISP_DATA,A READLP2: MOV R0,27H MOV @R0,ISP_DATA INC 27H INC 28h ;以下語句可不用,只是出於安全考慮而已 SETB EA DJNZ 29H,READLP RET ;位元組程式設計 ISP_WRITE: MOV 29H,#9 MOV 27H,#60H MOV 28H,#00H WRITELP: MOV R0,27H MOV A,@R0 MOV ISP_DATA,A MOV ISP_ADDRH,#20h ;地址高位元組 MOV ISP_ADDRL,28H ;地址低位元組 CLR EA MOV ISP_CONTR,#WAIT_TIME MOV ISP_CONTR,#10000000B MOV ISP_CMD,#ISP_IAP_BYTE_PROGRAM MOV ISP_TRIG,#46H MOV ISP_TRIG,#0B9H NOP INC 27H INC 28H ;以下語句可不用,只是出於安全考慮而已 SETB EA DJNZ 29H,WRITELP RET ;扇區擦除 ISP_ERASE: MOV ISP_ADDRH,#20h ;扇區起始地址高位元組 MOV ISP_ADDRL,#00h ;扇區起始地址低位元組 ;第1扇區:2000h-21ffh 第2扇區:2200h-23ffh ;第3扇區:2400h-25ffh 第4扇區:2600h-27ffh ;第5扇區:2800h-29ffh 第6扇區:2a00h-2bffh ;第7扇區:2c00h-2dffh 第8扇區:2e00h-2fffh CLR EA MOV ISP_CONTR,#WAIT_TIME MOV ISP_CONTR,#10000000B MOV ISP_CMD,#ISP_IAP_SECTOR_ERASE MOV ISP_TRIG,#46H MOV ISP_TRIG,#0B9H NOP ;以下語句可不用,只是出於安全考慮而已 SETB EA RET KEYIN: DB 01H,02H,03H,04H,05H,06H,07H,08H NUMBER: DB 030H,31H,32H,33H,34H,35H,36H,37H,38H,39H,20H PASSWORDTRUE: DB 20H,50H,61H,73H,73H,77H,6FH,72H,64H,20H,74H,72H,75H,65H,20H,20H PASSWORDFALSE: DB 50H,61H,73H,73H,77H,6FH,72H,64H,20H,66H,61H,6CH,73H,65H,30H INPUTPASSWORD: DB 20H,67H,75H,67H,75H,6FH,62H,61H,6FH,20H,49H,6EH,0F0H,75H,74H,20H PLEASEENTER: DB 20H,20H,50H,6CH,65H,61H,73H,65H,20H,45H,6EH,74H,65H,72H,20H,20H PASSWORDRESET: DB 20H,50H,61H,73H,73H,77H,6FH,72H,64H,20H,72H,65H,73H,65H,74H,20H PLAYRESETOK: DB 20H,72H,65H,73H,65H,74H,20H,20H,73H,75H,63H,63H,65H,73H,73H,20H DOYOUSETTAB: DB 20H,20H,44H,6FH,20H,79H,6FH,75H,20H,72H,65H,73H,65H,74H,20H,20H YESORNOTAB: DB 20H,20H,20H,59H,65H,73H,20H,20H,20H,20H,20H,4EH,6FH,20H,20H,20H END
微控制器EEROM斷電儲存密碼:
EEROM在寫資料到EEROM時(我使用的是STC-AT89C52RC),需要進行擦寫,起始擦寫就是往扇區寫入1,必須擦寫後才能寫入資料,其實內部就是與門結構。寫入的資料有0,就與,為1就不變。
;跳線設定:預設
;晶振11.0592
;STC89C52微控制器內部EEPROM測試
;按一下51hei學習板上的S4鍵,LED燈D1點亮,再按一下熄滅,關機撤掉電源後下次開機可狀態儲存.
;注意本程式只儲存D1燈的狀態,其他的幾個燈初始為何值就是何值.
;定義EEPROM特殊功能暫存器
ISP_DATA DATA 0E2H
ISP_ADDRH DATA 0E3H
ISP_ADDRL DATA 0E4H
ISP_CMD DATA 0E5H
ISP_TRIG DATA 0E6H
ISP_CONTR DATA 0E7H
;定義ISP/IAP命令及等待時間
ISP_IAP_BYTE_READ EQU 1
ISP_IAP_BYTE_PROGRAM EQU 2
ISP_IAP_SECTOR_ERASE EQU 3
WAIT_TIME EQU 0
K1 BIT P3.6
LED BIT P0.7
ORG 0000H
AJMP MAIN
ORG 0030H
MAIN:
clr P1.4
ACALL ISP_READ
MOV P0,A
LOOP:
A1:
ACALL DELAY
JNB K1,A1
CPL LED
MOV A,P0
ACALL ISP_ERASE
ACALL ISP_WRITE
NEXT:
AJMP LOOP
;位元組讀
ISP_READ:
MOV ISP_ADDRH,#20h ;地址高位元組
MOV ISP_ADDRL,#00h ;地址低位元組
CLR EA
MOV ISP_CONTR,#WAIT_TIME
MOV ISP_CONTR,#10000000B
MOV ISP_CMD,#ISP_IAP_BYTE_READ
MOV ISP_TRIG,#46H
MOV ISP_TRIG,#0B9H
NOP
MOV A,ISP_DATA
;以下語句可不用,只是出於安全考慮而已
MOV ISP_CONTR,#00000000B
MOV ISP_CMD,#00000000B
MOV ISP_TRIG,#00000000B
MOV ISP_ADDRH,#0
MOV ISP_ADDRL,#0
SETB EA
RET
;位元組程式設計
ISP_WRITE:
MOV ISP_DATA,A
MOV ISP_ADDRH,#20h ;地址高位元組
MOV ISP_ADDRL,#00h ;地址低位元組
CLR EA
MOV ISP_CONTR,#WAIT_TIME
MOV ISP_CONTR,#10000000B
MOV ISP_CMD,#ISP_IAP_BYTE_PROGRAM
MOV ISP_TRIG,#46H
MOV ISP_TRIG,#0B9H
NOP
;以下語句可不用,只是出於安全考慮而已
MOV ISP_CONTR,#00000000B
MOV ISP_CMD,#00000000B
MOV ISP_TRIG,#00000000B
MOV ISP_ADDRH,#0
MOV ISP_ADDRL,#0
SETB EA
RET
;扇區擦除
ISP_ERASE:
MOV ISP_ADDRH,#20h ;扇區起始地址高位元組
MOV ISP_ADDRL,#00h ;扇區起始地址低位元組
;第1扇區:2000h-21ffh 第2扇區:2200h-23ffh
;第3扇區:2400h-25ffh 第4扇區:2600h-27ffh
;第5扇區:2800h-29ffh 第6扇區:2a00h-2bffh
;第7扇區:2c00h-2dffh 第8扇區:2e00h-2fffh
CLR EA
MOV ISP_CONTR,#WAIT_TIME
MOV ISP_CONTR,#10000000B
MOV ISP_CMD,#ISP_IAP_SECTOR_ERASE
MOV ISP_TRIG,#46H
MOV ISP_TRIG,#0B9H
NOP
;以下語句可不用,只是出於安全考慮而已
MOV ISP_CONTR,#00000000B
MOV ISP_CMD,#00000000B
MOV ISP_TRIG,#00000000B
MOV ISP_ADDRH,#0
MOV ISP_ADDRL,#0
SETB EA
RET
DELAY:
MOV R6,#14H
DL1:MOV R7,#19H
DJNZ R7,$
DJNZ R6,DL1
RET
END