单片机期末实训---- 密码锁和交通灯
Posted guguobao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单片机期末实训---- 密码锁和交通灯相关的知识,希望对你有一定的参考价值。
交通灯汇编代码:
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
以上是关于单片机期末实训---- 密码锁和交通灯的主要内容,如果未能解决你的问题,请参考以下文章
《单片机C语言程序设计实训100例——基于8051+Proteus仿真》 第03篇源代码