单片机期末实训---- 密码锁和交通灯

交通灯汇编代码:

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

原文地址:https://www.cnblogs.com/guguobao/p/9901142.html

时间: 2024-10-12 16:18:33

单片机期末实训---- 密码锁和交通灯的相关文章

期末实训学习认识SSH

SSH 为 struts+spring+hibernate的一个集成框架,是目前较流行的一种Web应用程序开源框架.集成SSH框架的系统从职责上分为四层:表示层.业务逻辑层.数据持久层和域模块层,以帮助开发人员在短期内搭建结构清晰.可复用性好.维护方便的Web应用程序. 其中使用Struts作为系统的整体基础架构,负责MVC的分离,在Struts框架的模型部分,控制业务跳转,利用Hibernate框架对持久层提供支持,Spring做管理,管理struts和hibernate. 传输层协议 [SS

单片机第16课:简易交通灯

JP3接PO口. JP1接P2口,J22接P3.0和P3.1口. #include<reg51.h> #define uint unsigned int #define uchar unsigned char uchar smg = 0; uchar code table[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e}; int flag_t

(十)单片机扩展 8255 芯片 控制 交通灯

目的: 单片机扩展82C55 芯片 用作 输出口,控制 12只 发光二极管亮灭, 模拟对交通灯的管理. // 执行程序,初始化状态, 4个红灯全亮后, 东西路口的绿灯亮,南北路口的红灯亮,东西方向通车// 延迟一段时间后, 东西路口绿灯熄灭, 黄灯开始闪烁,闪烁几次后,东西路口红灯亮,同时南北路口绿灯亮,南北通车.// 延迟一段时间,南北路口的绿灯熄灭, 黄灯开始闪烁,再切换到东西路口绿灯亮,重复上述过程 仿真电路图: 参考代码: 1 2 3 #include<reg52.h> 4 #incl

Lesson01:W-A_51单片机实训板介绍(旧博客迁移)

一.开发板介绍 单片机实训板是以Atmel公司的AT89S52单片机为核心的实验板,主要资源包括以下部分: 1.输入单元--四个独立按键/十六个矩阵按键(通过短路帽跳线选择),一个PS2键盘/鼠标接口 2.输出单元--八位LED发光管/四位动态扫描数码管/1602液晶(共用P0口),蜂鸣器,继电器 3.存储单元--SPI串行存储器AT93C46,I2C串行存储器AT24C02 4.实时时钟--DS1302(SPI接口) 5.数字温度传感器--DS18B20(单总线接口) 6.串行ADC--TLC

奶爸业余单片机学习之:用数码管及LED实现交通灯(初版)

/* * 人行道交通灯程序:LED2(红灯).LED3(黄灯).LED4(绿灯)* 红灯30秒,绿灯3秒,绿灯15秒,倒计时 灯亮时间显示在数码管上* 晶振11.0592MHz,LED.数码管由三八译码器控制,T0中断 *程序思路:由于三八译码器每次只能输出一个低电平,因此必须用动态扫描方式点亮数码管及LED,中断间隔1ms *亮灯时间倒数,红灯60秒,绿灯20秒,黄灯3秒,顺序:红 - 绿 -黄 -红循环,因此每经历1000次中断,实现数字递减. */ #include<reg52.h>un

VHDL交通灯

转载请注明出处. 很讨厌码迷这种爬虫网站爬取整篇程序,所以还是加些字会好一点: 做的期末EDA实训关于交通灯:题目要求的是要做一个东西南北向的交通灯:有数码管倒计时,LED定时换颜色:复位和交通管制等功能: LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY JTD IS PORT (CLK1KHZ : IN STD_LOGIC; --1KHZ输入 KEY : IN STD_LOGI

BeagleBone Black项目实训手册(大学霸内部资料)

BeagleBone Black项目实训手册(大学霸内部资料) 介绍:本教程是<BeagleBone Black快速入门教程>的后续教程.本教程以项目操作为主,讲解LED项目.声音项目.传感器项目以及显示项目,并对Beaglebone Black的GPIO.PWM以及I2C等特殊的接口进行详细讲解. 试读下载地址:http://pan.baidu.com/s/1eQozxnG BeagleBone Black项目实训手册 目  录 第1章  准备开始 1 1.1  启动你的Beaglebone

【CC2530入门教程-增强版】基础技能综合实训案例(基础版)-终端源码

[CC2530入门教程-增强版]基础技能综合实训案例(基础版)-终端源码 广东职业技术学院 欧浩源 一.关于硬件电路 关于这个综合实训案例,具体需求详见<[CC2530入门教程-增强版]基础技能综合实训案例(基础版)-题目需求>. 我自己实在"全国职业院校技能大赛--物联网技术应用赛项"的Zigbee模块上实现的.该模块的电路应该和TI公司官方评估板的推荐电路差不多,我想现在市面上很多开发板也是参考这样的电路设计,只要您使用的开发板上有LED灯.按键输入.串口输出和一路A/

记中兴软件园一个月实训(一)

马上大四了,在学期末学校一年一度的企业实训体验开始了. 其实现在已经接近尾声,只是把学到的东西整理一下,供各位君闲聊查看. /**********这个是第一天的笔记*************************/ /*一:程序的结构工程 sln文件 .c 文件包括:函数的定义 变量的定义 .h 文件包括:存放声明 类型的定义 宏定义 函数: 主函数 子函数 语句 单词 字母数字下划线 开头不能是数字二:数据类型 --->size 范围分类:1.基本类型整形 有符号 无符号实型 字符型 :un