一、实验任务
1. 深入了解汇编指令和常用程序结构,以周期性点亮LED灯的延时函数为例,掌握 1)通过软件多重循环软件计数的定时方法 ;2)通过 循环+ nop 指令的方法;
2. 掌握汇编语言用查表法完成 求平方数的程序;
3. 掌握普中单片机实验开发板的开发使用方法,在板子上完成LED周期性点灯的C程序实验。
二、 具体过程
1)请查阅汇编指令 “MOV R6,#250”和“DJNZ R6,D2”的指令周期数,计算其对应的时钟周期 us值;然后计算 Delay函数的总的循环次数和对应的时钟周期总数us, 说明这个LED灯大约每隔多少毫秒(ms)或秒(s)才变化一次亮灭状态;
指令周期数都为1,时钟周期us值都约为1us;总循环次数为250250=62500次,时钟周期总数为6250024=1500000个时钟周期,总的时钟周期us值为150000083.33ns=125000us即125ms,LED灯每125ms亮灭一次*
2)如果要求你实现准确的LED 每隔1s亮灭的周期性变化,上面程序如何修改?请给出完整代码。请在edsim51中进行实践练习。
完整代码:
SETB 90H ;假设90H是LED的控制位
LCALL DELAY ;调用延时程序
CLR 90H ;清除LED的控制位
LCALL DELAY ;再次调用延时程序
AJMP LOOP ;跳转到LOOP,继续循环
MOV R7, #23438 ;修改R7的初始值
MOV R6, #255 ;设置R6的初始值
DJNZ R6, D2 ;内层循环
DJNZ R7, D1 ;外层循环
RET ;返回
2. 请参考网上资料(如B站哈工大单片机课程)完成一个 查找平方数的汇编程序。对程序进行学习和理解。在Edsim51、proteus中进行验证。
完整代码:
ORG 0000H ;程序起始地址
MOV R0,#01H ;初始化寄存器R0为1
MOV R7, #0AH ;设置上限值为10(这里用R7,因为CJNE不影响R1)
LOOP: MOV A, R0 ;将R0的值移入累加器A
SUBB A, R7 ;从A中减去R7的值,结果存放在A中,并影响标志位
JC ENDLOOP ;如果减法产生了进位(即A中的原值小于R7),则跳转到ENDLOOP
MOV B, A ;如果需要,可以将A的值移到B中保存(这一步在这里可能不必要)
MUL AB ;A中的值(R0)与B中的值(也是R0)相乘,结果存储在BA中
;假设我们只想保存低8位的结果
MOV R2, A ;将结果的低8位存储在R2中(或者可以使用其他方式显示或保存结果)
INC R0 ;增加寄存器R0
CJNE R0, #11H, LOOP ;如果R0不等于11H(16进制的11,即十进制的17,但是我们需要循环应该到10,这里有误),继续循环
;注意这里有一个错误:我们应该与上限加1比较以决定是否继续循环
;但是实际上我们不应该在R0达到11时才停止,因为我们的范围是1到10
SJMP $ ;无限循环,等待中断或复位
ENDLOOP: SJMP $ ;另一种情况的无限循环(可选:取决于你程序的其余部分)
END ;程序结束
3. 在普中单片机开发板上重新完成上述实验。