30.JavaScript数组基础、遍历、底层实现、push、pop、at、length

0b87f80f56636c51322fa0c0cbfe49e5


数组

前面讲到的对象虽然是非常强大的工具,但是,我们在编写代码时常常需要处理一些有序数据的集合。在有序集合中,元素的排列是有前后顺序的,例如:文章的列表、章节目录。由于对象并不能提供属性的有序访问,这种情况下,就需要我们使用新的数据结构数组

数组声明

我们可以通过两种方式创建一个空的数组:

let arr1 = new Array();//方式1
let arr2 = [];//方式2

由于第二种方式不仅简单,而且直观,我们常常采用第二种方式。

在声明一个数组时,我们可以直接进行初始化:

let arr = ['Chapter01','Chapter02','Chapter03','Chapter04','Chapter05'];

以上代码创建了一个包含五个元素的数组。

元素访问

我们可以通过下标的方式访问数组元素,需要注意的是,数组的编号是从0开始的。

let arr = ['Chapter01','Chapter02','Chapter03','Chapter04','Chapter05'];
console.log(arr[0]);//访问第一个元素,注意下标是0
console.log(arr[3]);
console.log(arr[4]);

代码执行结果:

image-20220530103817298

元素替换

通过下标,我们可以直接替换一个数组元素:

let arr = ['Chapter01','Chapter02','Chapter03','Chapter04','Chapter05'];
arr[1] = 'Chapter06';//数组变成了['Chapter01','Chapter06',...]

元素添加

通过下标向数组的末尾添加一个元素:

let arr = ['Chapter01','Chapter02']
arr[2] = 'Chapter03';//数组变为['Chapter01','Chapter02','Chapter03']

数组长度

通过数组的.length属性可以获得数组中元素的个数

let arr = ['Chapter01','Chapter02']
console.log(arr.length)//2

循环添加

我们可以利用循环迅速创建一个任意长度的数组,这在我们编程中经常用到:

let arr = [];
for(let i = 0;i < 10;i++){
    arr[i] = String(i);
}

元素类型

JavaScript数组不限制元素的种类,在同一个数组中可以存储多种类型的数组:

let arr = [1, '2', { '3' : 3 }];

和对象一样,我们推荐在最后一个元素后添加,,这样在添加元素和移动元素的时候会非常容易:

let arr = [
    'chapter1',
    'chapter2',
    'chapter3',
]

at()

访问元素的方法并非一种,我们还可以通过at(idx)方法访问数组的元素:

let arr = ['Chapter01','Chapter02','Chapter03'];
console.log(arr.at(2));

代码执行效果如下:

image-20220530105722902

以上代码的执行效果和使用[idx]方式完全相同,那么使用at的意义在哪里呢?

最后一个元素

如果我们希望访问数组的最后一个元素,应该怎么办呢?

我们可以使用.length属性实现:

let arr = ['Chapter01','Chapter02','Chapter03'];
console.log(arr[arr.length-1]);

但是这么做非常的不优雅,我们需要写两次数组的名字,此时,我们可以使用at(-1)访问数组的最后一个元素。

let arr = ['Chapter01','Chapter02','Chapter03'];
console.log(arr.at(-1));

同理,访问倒数第二个元素可以使用arr.at(-2)

push、pop、shift、unshift

除了直接使用下标访问数组元素,数组还提供了四个方法用于在数组的首尾添加、删除元素:

  1. push:在数组尾部追加一个元素
let arr = ['First'];
arr.push('Second');//此时arr变成了['First','Second']
  1. pop:在数组的尾部取出一个元素,等同于at(-1)
let arr = ['First','Second','Third'];
let last = arr.pop()//等同于arr.at(-1),arr此时为['First','Second']
console.log(last);//Third
  1. shift:从数组头部取出一个元素
let arr = ['First','Second','Third'];
let first = arr.shift();//First,arr变为['First','Second','Third']
console.log(first);
  1. unshift:从数组头部插入一个元素
let arr = ['Second'];
arr.unshift('First');//arr等于['First','Second']

栈是编程中最常用的线性数据结构,我们可以使用push/pop方法,把数组当作栈使用。

let st = ['First'];
st.push('Second');//压栈
st.pop()//出栈

队列

队列是另外一个常用的线性数据结构,我们可以使用push/shift方法,把数组当作队列使用:

let que = ['First'];
que.push('Second');//入队
que.shift()//出队

清奇的脑回路

当然,我们可以使用shift/unshift实现栈,通过unshift/pop实现队列,只是通常情况下我们都不这么做~~

遍历

最简单的遍历数组的方式是for循环:

let arr = ['First','Second','Third'];
for(let i = 0;i < arr.length; i++){
    console.log(arr[i])
}

代码执行结果:

image-20220530123156573

虽然这么做毫无问题,但是为了更加优雅,我们可以使用for ... of语法:

let arr = ['First', 'Second', 'Third'];
for(let itm of arr){
    console.log(itm)
}

代码执行结果和上面并无差别:

image-20220530123400977

但是这么做也有一个缺点,就是没有办法获得元素下标,所以我们需要在合适的场景下做合适的选择。

length

.length的意义

我们可以使用数组的.length属性获得数组的长度,但是,实际上数组的.length属性并非数组里元素的个数,而是数组最大下标的值加一

let arr = [];
arr[996] = 996;
console.log(arr.length)//997

代码的执行结果是不是和想象的不太一样:

image-20220530124006126

我们通常情况下不这么使用数组,所以仍然可以使用.length获取数组的长度。

.length可写

从直观上理解,.length应该是一个可读的属性,实际上,我们是可以修改.length属性的值的:

let arr = [1,2,3,4,5,]
arr.length = 7;
console.log(arr.length)//length = 7
console.log(arr[6])//undefined

arr.length = 3;//length = 3,数组被截断
arr.length = 5;//length = 5,但是截断的数据不会回来了
console.log(arr.length)//5
console.log(arr[4])//undefined

代码执行结果如下:

image-20220530124743634

修改length会产生如下影响:

  1. 修改后大于当前长度,增长的长度使用undefined填充
  2. 修改后小于当前长度,截断字符串至新长度(截断的部分不可恢复)

Array()

我们使用Array()同样可以创建一个字符串,不过不常用,因为我们更喜欢[]语法。

let arr = new Array('First','Second','Third');

Array()还有一个不讨喜的特性:当我们使用单个数字参数时,会创建一个指定数字长度的空数组!

如果我们正好要创建一个具有单个数字的数组,就会出错。

let arr = new Array(4);
console.log(arr.length);//4
console.log(arr[3]);//undefined

为了避免出现不必要的错误,还是建议使用[],简单又方便。

多维数组

JavaScript的数组同样可以是多维的:

let arr = [
    [1,1,1,],
    [2,2,2,],
    [3,3,3,],
]

toString()

数组的toString()方法会把数组元素转为字符串,并以,相隔:

let arr = [1,2,3]
console.log(arr.toString())//1,2,3
console.log(arr.toString()+1)//1,2,31

数组比较

数组的本质是一个特殊的对象,因此我们不应该使用==比较两个数组,就像不应该使用==比较对象一样。

  1. 仅当两个数组引用的是同一个对象时,它们才相等;
  2. 如果数组和基础类型比较,将数组转为基础类型后再次比较,转换规则和对象相同对象-基础类型转换;

数组比较:

console.log([] == [])//false
console.log([1] == [1])//false

数组与基础类型比较:

console.log([] == 0)//true
console.log([] == '0')//false
console.log([1,2,3] == "1,2,3")//true

虽然其中有一定的规律,但是不建议使用==比较数组,我们可以循环逐个比较元素,亦或者使用后面会介绍到的迭代。

数组的本质

数组是一个特殊的对象,方括号加下标的访问方式arr[3]实际上就是对象的属性访问语法obj[key]

数组是对象的扩展,一个属性有序,而且具有length属性的特殊对象,但是本质上仍然是对象。

我们在最初的文章中曾介绍,JavaScript共有8中数据类型,数组属于对象范畴。

如何验证数组是一个对象的本质呢?

实验一,数组变量存储的是引用:

let arr = [1,2,3]
let arr2 = arr;
console.log(arr2 === arr);//true
arr2.push(4)
console.log(arr.toString())//1,2,3,4

实验二,给数组添加属性:

let arr = [1,2,3]
arr.name = 'arr';

代码执行效果:

image-20220530143914801

但是这么做就会破坏数组的特性,将数组变成一个普通的对象。

错误的数组使用

  1. 添加非数字属性,例如arr['name']='xiaoming'
  2. 越界存储,例如在长为3的数组上使用arr[1000]=999
  3. 倒序填充数组,例如arr[1000]=1000arr[999]=999

如果我们不能把数组当作一个有序的数据结构,可以优先考虑对象。

性能

在数组的末端插入数据比数组的头部插入数据要快,也就是push/pop速度比shift/unshift要快。

这是因为,从数组头部移除数据后,引擎会做三件事:

  1. 移除下标为0的值;
  2. 将所有元素像前移动;
  3. 更新length;

数组里面的元素越多,耗费时间越长,push/pop操作在末尾,不会移动任何元素,所以速度很快。

总结

  1. 数组是一个特殊的对象,其元素有序排列,使用下标访问数组元素

  2. 两种声明方式:[]new Array()

  3. at(-1)倒序访问元素

  4. push/pop/shift/unshift操作数组两端的元素

  5. 把数组用作栈、队列

  6. 数组元素遍历forfor offor in(不要使用这个)

  7. 不要使用==比较数组


在这里插入图片描述

  • 136
    点赞
  • 130
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 121
    评论
单片机电子时钟设计报告 实现功能:显示时、分、秒,刚打开电源时,显示的数据为12:00:00,然后电路会 自动开始计时。电路有时、分、秒各自单独的调整按钮,时间调整按钮每按一次,相 应的显示时间加1。 所需材料:89C51单片机,多位数码管,数码管显示译码器74LS48,3线8线译码器74LS13 8,3个按钮, 100Ω、22KΩ电阻若干,12MHZ晶振一个,30pf无极电容2个,10uf有极电容一个,敷铜板。 电路设计:用P1端口的P1.0~P1.3来作为数码管显示数据的输出引脚,用P1.4~P1.6引 脚作为3线8线译码器的控制输入引脚,用P0端口的P0.0~P0.2来分别作为时、分、秒的时 间调整按钮。当按下按钮时,相应的输入引脚上就会有低电平输入单片机。3线8线译码 器的控制端,Y0、Y1、Y2、Y3、Y4、Y5分别控制了数码管的显示控制线。电路如下图1- 1 图1-1 流程图: 程序设计: ORG 00H 主程序起始地址 JMP START 主程序START ORG 0BH 定时器T0断起始地址 JMP TIM0 定时器T0断子程序TIM0 START: MOV SP,#70H 设置堆栈指针 MOV 28H,#00 设置显示位数扫描指针初值为0 MOV 2AH,#12H 设置时钟显示寄存器初值为12H MOV 2BH,#00 设置分钟显示寄存器初值为00H MOV 2CH,#00 设置秒钟显示寄存器初值为00H MOV TMOD,#01H 设置定时器T0工作在方式1 MOV TH0,#0F0H 定时4ms的初值,即0F060H MOV TL0,#60H 初值的低位 MOV IE,#82H 定时器T0断允许 MOV R4,#250 保证后面实现断250次,即1秒的延时 SETB TR0 启动定时器T0 LOOP: JB P0.0,N2 若没有按键,就转去下一步检查分 CALL DELAY 延时5ms,消除抖动 MOV A,2CH 将秒寄存器的值载入累加器A ADD A,#01H A的内容加1 DA A 十进制调整 MOV 2CH,A A的 值存入秒寄存器 CJNE A,#60H,N1 看是否已经是60秒,若不是就继续检查 MOV 2CH,#00 已经是60秒,就清空秒寄存器的值 N1: JNB P0.0,$ 秒按键还没有放开就循环等待 CALL DELAY 延时5ms,消除抖动 N2: JB P0.1,N4 若分没有按键,就转去下一步检查分 CALL DELAY 延时5ms,消除抖动 MOV A,2BH 将分寄存器的值载入累加器A ADD A,#01H A的内容加1 DA A 十进制调整 MOV 2BH,A A的值存入寄存器 CJNE A,#60H,N3 看是否已经是60分,若不是就继续检查 MOV 2BH,#00H 已经是60分,就清空寄存器的值 N3: JNB P0.1,$ 分按键还没有放开就循环等待 CALL DELAY 延时5ms,消除抖动 N4: JB P0.2,LOOP 若时没有按键,就转回去继续检查看是否有按键 CALL DELAY 延时5ms,消除抖动 MOV A,2AH 将时寄存器的值载入累加器A ADD A,#01H A的内容加1 DA A 十进制调整 MOV 2AH,A A的值存入时寄存器 CJNE A,#24H,N5 看是否已经是24时,若不是就继续检查 MOV 2AH,#00H 已经是24时,就清空是寄存器的值 N5: JNB P0.2,$ 时钟按键还没有放开就循环等待 CALL DELAY 延时5ms,消除抖动 JMP LOOP 返回重新检查看是否有按键 ******定时器T0断子程序******* TIM0: MOV TH0,#0F0H 定时初值重设 MOV TL0,#60H PUSH ACC 将累加器A的值暂存于堆栈 PUSH PSW 将PSW的值暂存于堆栈 DJNZ R4,X2 计时断不满1s就退出继续断 MOV R4,#250 计时1s CALL CLOCK 调用计时器子程序CLOCK CALL DISP 调用显示子程序DISP X2: CALL SCAN 调用扫描子程序SCAN POP PSW 到堆栈取回PSW的值 POP ACC 到堆栈取回累加器ACC的值 RETI 返回主程序 ******扫描子程序******* SCAN: MOV R0,#28H INC @R0 显示位数扫描值加1 CJNE @R0,#6,X3 扫描位数不为6就准备控制输出 MOV @R0,#0 扫描位数为6,就令其置为0 X3: MOV A,@R0 扫描位数载入A ADD A,#20H A加上20H(显示寄存器地址)=各时间显示区地址 MOV R1,A 各时间显示区地址存入A MOV A,
AT89C51时钟程序 org 00h ;显示缓冲单元在70H—75H,70H—71H显示秒,72H—73H显示分,74H—75H显示时 ;时间计数单元在70H—71H(秒)、76H—77H(分)、78H—79H(时),7AH单元放熄灭符(#0AH) ;计数单元采用BCD码计数,定时器T0设置为50MS溢出断,为秒计数用,定时器T1为调整时闪烁用 ;P3.2为调整按钮,P1口为字符输出口,采用共阳显示管。 ORG 0000H LJMP START ORG 0003H RETI ORG 000BH LJMP INTT0 ORG 0013H RETI ORG 001BH LJMP INTT1 ORG 0023H RETI ORG 002BH RETI START: MOV R0, #70H MOV R7, #0BH MOV 20H, #00H CLEARDISP: MOV @R0, #00H INC R0 DJNZ R7,CLEARDISP MOV 7AH,#0AH MOV TMOD,#11H MOV TL0, #0B0H MOV TH0, #3CH MOV TL1, #0B0H MOV TH1, #3CH SETB EA SETB ET0 SETB TR0 MOV R4,#14H start1: LCALL DISPLAY JNB P3.2,SETMM1 SJMP Start1 SETMM1: LJMP SETMM INTT0: PUSH ACC PUSH PSW CLR ET0 CLR TR0 MOV A,#0B7H ;断同步修正 ADD A,TL0 MOV TL0,A MOV A,#3CH ADD A,TH0 MOV TH0,A SETB TR0 DJNZ R4, OUTT0 ADDSS: MOV R4,#14H MOV R0,#71H ACALL ADD1 ;加1程序 MOV A,R3 CLR C CJNE A,#60H,ADDMM ADDMM: JC OUTT0 ACALL CLR0 MOV R0,#77H ACALL ADD1 MOV A,R3 CLR C CJNE A,#60H,ADDHH ADDHH: JC OUTT0 ACALL CLR0 MOV R0,#79H ACALL ADD1 MOV A,R3 CLR C CJNE A,#24H,HOUR HOUR: JC OUTT0 ACALL CLR0 OUTT0: MOV 72H,76H MOV 73H,77H MOV 74H,78H MOV 75H,79H POP PSW POP ACC SETB ET0 RETI INTT1: PUSH ACC PUSH PSW MOV TL1, #0B0H MOV TH1, #3CH DJNZ R2,INTT1OUT MOV R2,#06H CPL 02H JB 02H,FLASH1 MOV 72H,76H MOV 73H,77H MOV 74H,78H MOV 75H,79H INTT1OUT: POP PSW POP ACC RETI FLASH1: JB 01H,FLASH2 MOV 72H,7AH MOV 73H,7AH MOV 74H,78H MOV 75H,79H AJMP INTT1OUT FLASH2: MOV 72H,76H MOV 73H,77H MOV 74H,7AH MOV 75H,7AH AJMP INTT1OUT ADD1: MOV A,@R0 DEC R0 SWAP A ORL A,@R0 ADD A,#01H DA A MOV R3,A ANL A,#0FH MOV @R0,A MOV A,R3 INC R0 SWAP A ANL A,#0FH MOV @R0,A RET CLR0: CLR A MOV @R0,A DEC R0 MOV @R0,A RET SETMM: cLR ET0 CLR TR0 LCALL DL1S JB P3.2,CLOSEDIS MOV R2,#06H SETB ET1 SETB TR1 SET2: JNB P3.2,SET1 SETB 00H SET4: JB P3.2,SET3 LCALL DL05S JNB P3.2,SETHH MOV R0,#77H ;加1分程序 LCALL ADD1 MOV A,R3 CLR C CJNE A,#60H,HHH HHH: JC SET4 LCALL CLR0 CLR C AJMP SET4 CLOSEDIS: SETB ET0 SETB TR0 CLOSE: JB P3.2,CLOSE LCALL DISPLAY JB P3.2,CLOSE WAITH: JNB P3.2,WAITH LJMP START1 SETHH: CLR 00H SETHH1: JNB P3.2,SET5 SETB 01H SET6: JB P3.2,SET7 LCALL DL05S JNB P3.2,SETOUT MOV R0,#79H LCALL ADD1 MOV A,R3 CLR C CJNE A,#24H,HOUU HOUU: JC SET6 LCALL CLR0 AJMP SET6 SETOUT: JNB P3.2,SETOUT1 LCALL DISPLAY JNB P3.2,SETOUT CLR 01H CLR 00H CLR 02H CLR TR1 CLR ET1 SETB TR0 SETB ET0 LJMP START1 SET1: LCALL DISPLAY AJMP SET2 SET3: LCALL DISPLAY AJMP SET4 SET5: LCALL DISPLAY AJMP SETHH1 SET7: LCALL DISPLAY AJMP SET6 SETOUT1: LCALL DISPLAY AJMP SETOUT DISPLAY: MOV R1,#70H MOV R5,#0BFH PLAY: MOV A,R5 MOV P2,A MOV A,@R1 MOV DPTR,#TAB MOVC A,@A+DPTR MOV P0,A LCALL DL1MS INC R1 MOV A,R5 JNB ACC.1,ENDOUT RR A MOV R5,A AJMP PLAY ENDOUT: SETB P2.1 MOV P0,#0FFH RET TAB: DB 28h,7eh,0a2h,62h,74h,61h,21h,7ah,20h,60h DL1MS: MOV R6,#14H DL1: MOV R7,#19H DL2: DJNZ R7,DL2 DJNZ R6,DL1 RET ; DS20MS: ACALL DISPLAY ACALL DISPLAY ACALL DISPLAY RET DL1S: LCALL DL05S LCALL DL05S RET DL05S: MOV R3,#20H DL05S1: LCALL DISPLAY DJNZ R3,DL05S1 RET END
000B: DB 02H, 00H, 1EH, 00H, 00H, 00H, 00H, 00H ;........ Q0013: DB 00H, 00H, 00H, 00H, 00H, 00H, 00H, 00H ;........ Q001B: DB 02H, 00H, 3CH, 75H, 8AH,0B6H, 75H, 8CH ;..<u..u. Q0023: DB 3CH,0C0H,0E0H,0D2H, 00H, 05H, 34H, 12H ;<.....4. Q002B: DB 02H, 7FH, 12H, 02H,0B6H,0E5H, 34H, 54H ;.....4T Q0033: DB 0FH,0B5H, 3CH, 02H,0D2H, 04H,0D0H,0E0H ;..<..... Q003B: DB 32H, 75H, 8DH,0FCH, 75H, 8BH, 3CH, 12H ;2u..u.<. Q0043: DB 00H, 89H, 32H ;..2 ;========================================================================== Q0046: MOV SP,#80H ;0046 75 81 80 ORL TMOD,#10H ;0049 43 89 10 MOV IP,#04H ;004C 75 B8 04 ORL IE,#08H ;004F 43 A8 08 MOV TH1,#0FCH ;0052 75 8D FC MOV TL1,#3CH ;0055 75 8B 3C SETB TR1 ;0058 D2 8E MOV 33H,#00H ;005A 75 33 00 MOV 30H,#00H ;005D 75 30 00 MOV 31H,#01H ;0060 75 31 01 MOV 32H,#02H ;0063 75 32 02 SETB EA ;0066 D2 AF SETB ET0 ;0068 D2 A9 ORL TMOD,#01H ;006A 43 89 01 MOV TH0,#3CH ;006D 75 8C 3C MOV TL0,#0B0H ;0070 75 8A B0 SETB TR0 ;0073 D2 8C MOV 3EH,#00H ;0075 75 3E 00 MOV 3FH,#64H ;0078 75 3F 64 MOV 40H,#50H ;007B 75 40 50 Q007E: LCALL Q0176 ;007E 12 01 76 LCALL Q038D ;0081 12 03 8D LCALL Q032A ;0084 12 03 2A AJMP Q007E ;0087 01 7E PUSH ACC ;0089 C0 E0 CLR P2.0 ;008B C2 A0 CLR P2.1 ;008D C2 A1 CLR P2.2 ;008F C2 A2 MOV P0,#0FFH ;0091 75 80 FF MOV A,33H ;0094 E5 33 INC A ;0096 04 MOV 33H,A ;0097 F5 33 CJNE A,#03H,Q009F ;0099 B4 03 03 CLR A ;009C E4 MOV 33H,A ;009D F5 33 Q009F: CJNE A,#00H,Q00A9 ;009F B4 00 07 SETB P2.0 ;00A2 D2 A0 MOV A,30H ;00A4 E5 30 LJMP Q00BA ;00A6 02 00 BA ;========================================================================== Q00A9: CJNE A,#01H,Q00B3 ;00A9 B4 01 07 SETB P2.1 ;00AC D2 A1 MOV A,31H ;00AE E5 31 LJMP Q00BA ;00B0 02 00 BA ;========================================================================== Q00B3: SETB P2.2 ;00B3 D2 A2 MOV A,32H ;00B5 E5 32 LJMP Q00BA ;00B7 02 00 BA ;========================================================================== Q00BA: MOV DPTR,#03B6H ;00BA 90 03 B6 MOVC A,@A+DPTR ;00BD 93 MOV P0,A ;00BE F5 80 POP ACC ;00C0 D0 E0 RET ;00C2 22 ;========================================================================== Q00C3: PUSH ACC ;00C3 C0 E0 PUSH PSW ;00C5 C0 D0 CLR C ;00C7 C3 MOV A,35H ;00C8 E5 35 SUBB A,#17H ;00CA 94 17 JB ACC.0,Q00D1 ;00CC 20 E0 02 AJMP Q00D5 ;00CF 01 D5 Q00D1: CLR ACC.0 ;00D1 C2 E0 NOP ;00D3 00 NOP ;00D4 00 Q00D5: RR A ;00D5 03 MOV 35H,A ;00D6 F5 35 DJNZ 35H,$ ;00D8 D5 35 FD POP PSW ;00DB D0 D0 POP ACC ;00DD D0 E0 RET ;00DF 22 ;=======================================
单片机电子时钟设计报告 实现功能:显示时、分、秒,刚打开电源时,显示的数据为12:00:00,然后电路会 自动开始计时。电路有时、分、秒各自单独的调整按钮,时间调整按钮每按一次,相 应的显示时间加1。 所需材料:89C51单片机,多位数码管,数码管显示译码器74LS48,3线8线译码器74LS13 8,3个按钮, 100Ω、22KΩ电阻若干,12MHZ晶振一个,30pf无极电容2个,10uf有极电容一个,敷铜板。 电路设计:用P1端口的P1.0~P1.3来作为数码管显示数据的输出引脚,用P1.4~P1.6引 脚作为3线8线译码器的控制输入引脚,用P0端口的P0.0~P0.2来分别作为时、分、秒的时 间调整按钮。当按下按钮时,相应的输入引脚上就会有低电平输入单片机。3线8线译码 器的控制端,Y0、Y1、Y2、Y3、Y4、Y5分别控制了数码管的显示控制线。电路如下图1- 1 图1-1 流程图: 程序设计: ORG 00H 主程序起始地址 JMP START 主程序START ORG 0BH 定时器T0断起始地址 JMP TIM0 定时器T0断子程序TIM0 START: MOV SP,#70H 设置堆栈指针 MOV 28H,#00 设置显示位数扫描指针初值为0 MOV 2AH,#12H 设置时钟显示寄存器初值为12H MOV 2BH,#00 设置分钟显示寄存器初值为00H MOV 2CH,#00 设置秒钟显示寄存器初值为00H MOV TMOD,#01H 设置定时器T0工作在方式1 MOV TH0,#0F0H 定时4ms的初值,即0F060H MOV TL0,#60H 初值的低位 MOV IE,#82H 定时器T0断允许 MOV R4,#250 保证后面实现断250次,即1秒的延时 SETB TR0 启动定时器T0 LOOP: JB P0.0,N2 若没有按键,就转去下一步检查分 CALL DELAY 延时5ms,消除抖动 MOV A,2CH 将秒寄存器的值载入累加器A ADD A,#01H A的内容加1 DA A 十进制调整 MOV 2CH,A A的 值存入秒寄存器 CJNE A,#60H,N1 看是否已经是60秒,若不是就继续检查 MOV 2CH,#00 已经是60秒,就清空秒寄存器的值 N1: JNB P0.0,$ 秒按键还没有放开就循环等待 CALL DELAY 延时5ms,消除抖动 N2: JB P0.1,N4 若分没有按键,就转去下一步检查分 CALL DELAY 延时5ms,消除抖动 MOV A,2BH 将分寄存器的值载入累加器A ADD A,#01H A的内容加1 DA A 十进制调整 MOV 2BH,A A的值存入寄存器 CJNE A,#60H,N3 看是否已经是60分,若不是就继续检查 MOV 2BH,#00H 已经是60分,就清空寄存器的值 N3: JNB P0.1,$ 分按键还没有放开就循环等待 CALL DELAY 延时5ms,消除抖动 N4: JB P0.2,LOOP 若时没有按键,就转回去继续检查看是否有按键 CALL DELAY 延时5ms,消除抖动 MOV A,2AH 将时寄存器的值载入累加器A ADD A,#01H A的内容加1 DA A 十进制调整 MOV 2AH,A A的值存入时寄存器 CJNE A,#24H,N5 看是否已经是24时,若不是就继续检查 MOV 2AH,#00H 已经是24时,就清空是寄存器的值 N5: JNB P0.2,$ 时钟按键还没有放开就循环等待 CALL DELAY 延时5ms,消除抖动 JMP LOOP 返回重新检查看是否有按键 ******定时器T0断子程序******* TIM0: MOV TH0,#0F0H 定时初值重设 MOV TL0,#60H PUSH ACC 将累加器A的值暂存于堆栈 PUSH PSW 将PSW的值暂存于堆栈 DJNZ R4,X2 计时断不满1s就退出继续断 MOV R4,#250 计时1s CALL CLOCK 调用计时器子程序CLOCK CALL DISP 调用显示子程序DISP X2: CALL SCAN 调用扫描子程序SCAN POP PSW 到堆栈取回PSW的值 POP ACC 到堆栈取回累加器ACC的值 RETI 返回主程序 ******扫描子程序******* SCAN: MOV R0,#28H INC @R0 显示位数扫描值加1 CJNE @R0,#6,X3 扫描位数不为6就准备控制输出 MOV @R0,#0 扫描位数为6,就令其置为0 X3: MOV A,@R0 扫描位数载入A ADD A,#20H A加上20H(显示寄存器地址)=各时间显示区地址 MOV R1,A 各时间显示区地址存入A MOV A,

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 121
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@魏大大

我们都没有打赏的习惯

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值