你的程序逻辑,有风格,哈哈哈。一把的逻辑,不是在主程序里建立循环,在循环里,根据开关的状态值,来决定调用哪个显示处理吗?假设P1采样开关值,P2口显示流水灯, "0"亮, “1”灭 MAIN: MOV A, P1 JNZ MODE1 ;开关状态是0吗? LCALL DISP_MODE0 ;是0, 按照方式0显示 LJMP MAIN MODE1: XRL A, #1 ;开关状态是1吗? JNZ MODE2 LCALL DISP_MODE1 ;是1, 按照方式1显示 LJMP MAIN MODE2: MOV A, P1 XRL A, #2 ;开关状态是2吗? JNZ MODE3 LCALL DISP_MODE3 ;是2, 按照方式2显示 LJMP MAIN MODE3: MOV A, P1 XRL A, #3 ;开关状态是3吗? JNZ MAIN LCALL DISP_MODE3 ;是3, 按照方式3显示 LJMP MAIN DIMSP_MODE0: 按照方式0显示流水灯,每次只亮一个,从Bit0->Bit7 MOV A, #0FEH MOV P2, A ;点亮P20对应的灯 LCALL DELAY500MS MOV R7, 7 MODE0_LOOP: SETB C RLC A ;带进位1做循环,使0依次从Bit0->Bit7 MOV P2, A ;输出到P2口,点亮“0”对应的Bit口位 LCALL DELAY500MS ;延迟显示一段时间 DJNZ R7, MODE0_LOOP ;是否已经完成所有循环 RET DIMSP_MODE1: 按照方式1显示流水灯,逐个点亮所有LED ;0FFH + 进位标志C=0, RLC A,保证P2从0FEH,0FCH,0F8H, ... 到00H ;一次是P2的Bit0到Bit7全部输出0,从而逐个点亮所有LED ... RET DIMSP_MODE2: 按照方式2显示流水灯 ... RET DIMSP_MODE3: 按照方式3显示流水灯 ... RET DELAY500MS: ;循环R6,R5,R4等,保证实现接近500ms ... RET 具体显示,我只写了处理逻辑,具体代码,需要你自己发挥了。 还有一个比较简单的处理方式,你预先把要显示的模式中,对应P2的变化值,写到一个数组中,然后在 显示处理中,循环取得这些值并输出到P2口。 ;利用MOVC A,@A+DPTR指令,从预设的显示数据区取得输出数据 ;方式0显示流水灯,每次只亮一个,从Bit0->Bit7 TAB_MODE0: DB 11111110B, 11111101B, 11111011B, 11110111B, 11101111B, 11011111B, 10111111B, 01111111B ;依次全部点亮 TAB_MODE1: DB 11111110B, 11111100B, 11111000B, 11110000B, 11100000B, 11000000B, 10000000B,00000000B ;先全亮,从外向中间转移灭灯 TAB_MODE2: DB 00000000B, 10000001B , 11000011B, 11100111B, 11111111B 为了更直观,数据区的定义,我都是用2进制表示的数据。0对应亮,1对应灭 自定义显示流水灯,你可以在内存开辟一段区域,运行时动态指定这些区域的数据,然后利用循环,把这数据依次输出到P2口,就完成了自定义显示模式。 |
Y_G_G 发表于 2020-12-8 08:23 学校里的实验,开发板,可以仿真,也可以去实验室下到硬件里验证。好,谢谢 |