ORG 0000H AJMP MAIN1 ;转入主程序 ORG 0003H ;外部中断P3.2脚INT0入口地址 ;MOV SP,#5FH AJMP INT ;转入外部中断服务子程序(解码程序) ;**********以下为主程序进行CPU中断方式设置****************************************** MAIN1: ;MOV SP,5FH MOV P1,#0C0H;SETB P1.5; MOV P0,#00H MOV 25H,#0C0H CLR 20H.0;遥控电源键按下,置1,根据20H.1的状态进入电源开/关程序, SETB 20H.1; 设电源开关方向标志位,高打开. CLR 20H.2; 循环开关方向标志位,高打开. CLR 20H.3;遥控电源键按下,置1,根据20H.2的状态进入循环开/关程序, CLR 20H.5;设置在电源键未打开时,按下循环点亮键无效,并回到键扫描状态. CLR 20H.6 CLR 20H.7 MAIN: SETB EA ;打开CPU总中断请求 SETB IT0 ;设定INT0的触发方式为脉冲负边沿触发 SETB EX0 ;打开INT0中断请求 ;***************开始进入灯的点亮循环状态******************** SSS: ACALL K_SCAN JNB 20H.6,SSS;开循环后置1 MAIN2: CLR 20H.6 ;设置灯退出循环点亮后再从头循环点亮时不至于在无键或有键按下时无限次重复 ;执行MOV A,#01H向下到ACALL K_SCAN之间的程序使得只有第一个灯亮.CLR 20H.6 ACALL K_SCAN ;后,则在ACALL K_SCAN时进行正常的键扫描程序. MOV A,#01H MOV R4,#08H ******************************************************************************** ******************************************************************************* ; 就是以下部分出错了. LOOP3: MOV P0,A ;开始正向点亮(高打开灯) ACALL K_SCAN ACALL K_SCAN RL A DJNZ R4,LOOP3 MOV P0,#00H ACALL K_SCAN ACALL K_SCAN MOV A,#80H ;设置反向点亮初始值(高打开灯) MOV R4,#08H; LOOP4: MOV P0,A ;开始反向点亮 ACALL K_SCAN ACALL K_SCAN RR A DJNZ R4,LOOP4 MOV P0,#0FFH ;正反循环一次后开始熄灭一段时间 MOV R4,#03H AA: ACALL K_SCAN ACALL K_SCAN DJNZ R4,AA MOV P0,#0FFH ;第一次闪亮 MOV R4,#03H BB: ACALL K_SCAN ACALL K_SCAN;两次调用键扫描,既保证灯能点亮一定长时间便于观察,又减小了 DJNZ R4,BB ; 在进入点亮延时时有键按下而扫描不到的可能性. MOV P0,#00H MOV R4,#03H CC: ACALL K_SCAN ACALL K_SCAN DJNZ R4,CC MOV P0,#0FFH ;第二次闪亮 MOV R4,#03H DD: ACALL K_SCAN ACALL K_SCAN DJNZ R4,DD MOV P0,#00H MOV R4,#03H EE: ACALL K_SCAN ACALL K_SCAN DJNZ R4,EE AJMP MAIN2 ;开始新的循环正反向点亮 ;************************************************************************************ ;**********以下为进入P3.2脚外部中断子程序,也就是解码程序*************************** INT: ;PUSH ACC CLR EA ;MOV 25H,A ;暂时关闭CPU的所有中断请求 MOV R1,#10 SB: ACALL YS1 ;调用882微秒延时子程序 JNB P3.2,III ;延时882微秒后判断P3.2脚是否出现高电平如果有就退出解码程序 AJMP EXIT III: DJNZ R1, SB ;重复10次,目的是检测在8820微秒内如果出现高电平就退出解码程序 ;**********以上完成对遥控信号的9000微秒的初始低电平信号的识别************ JNB P3.2, $ ;等待高电平避开9毫秒低电平引导脉冲 ACALL YS2 ;延时4.74毫秒避开4.5毫秒的结果码 ;MOV R7,#16 ;忽略前26位系统识别码 MOV R1,#1AH ;设定1AH为起始RAM区 MOV R2,#4 ;接收从1AH到1AH的2个内存,用于存放操作码和操作反码 PP: MOV R3,#8 ;每组数据为8位 JJJJ: JNB P3.2,$ ;等待地址码第一位的高电平信号 LCALL YS1 ;高电平开始后用882微秒的时间尺去判断信号此时的高低电平状态 MOV C,P3.2 ;将P3.2引脚此时的电平状态0或1存入C中 JNC UUU ;如果为0就跳转到UUU LCALL YS3 ;检测到高电平1的话延时1毫秒等待脉冲高电平结束 UUU: MOV A,@R1 RLC A ;将C中的值0或1移入A中的最低位 MOV @R1,A ;将A中的数暂时存放在R1中 DJNZ R3,JJJJ ;接收地址码的高8位 INC R1 ;对R1中的值加1,换下一个RAM DJNZ R2,PP ;接收完16位地址码和8位数据码及其反码,存放在1AH/1BH/1CH/1DH的RAM中 MOV A,1CH CPL A CJNE A,1DH,EXIT ;解码程序结束 ;************以下进入遥控按键功能程序************************************************** BIJIAO: MOV A,1CH J1: CJNE A,#00110000B,J2;键1键值,设定为电源开\关 AJMP DYON J2: CJNE A,#00000000B,J3;键2键值,设定为启动\关闭流水灯 JNB 20H.5,EXIT AJMP LEDON J3: CJNE A,#00001000B,ZBTC;键4键值,设定为软件复位 MOV 0E7H,#01100000B;软件复位(类似上电复位).MOV 0E7H,#00100000B也用于软件复位, AJMP EXIT ;但效果不同. ZBTC: ;POP ACC;MOV A,25H AJMP EXIT DYON: SETB 20H.0 CLR 20H.3 AJMP EXIT LEDON: SETB 20H.3 CLR 20H.0 AJMP EXIT EXIT: SETB EA ;允许中断 RETI ;退出解码子程序 ;**********以下为解码用延时程序************************************************ YS1: MOV R6,#40 ;延时子程序1,精确延时882微秒 D1: MOV R7,#20 DJNZ R7,$ DJNZ R6,D1 RET YS2: MOV R6,#20 ;延时子程序2,精确延时4740微秒 D2: MOV R7,#235 DJNZ R7,$ DJNZ R6,D2 RET YS3: MOV R6,#4 ;延时程序3,精确延时1000微秒 D3: MOV R7,#248 DJNZ R7,$ DJNZ R6,D3 RET ;**************进入按键查询************** K_SCAN: ;键扫描子程序 JB 20H.6,TT ;使关循环后再开灯的循环时不返回关灯的位置,而是从第一位灯(P0.0)亮起. JB 20H.0,KK JB 20H.3,LL ;若要使关循环后再开循环时要求灯从关掉的位置继续亮下去,则去掉该指令及 ;JB 20H.6,TT, TT:AJMP MAIN2, CLR 20H.6共四条指令. MOV 30H,P1 ANL 30H,#0C0H ;键扫描 MOV R0,30H CJNE R0 ,#0C0H,MAIN4 JB 20H.7,ZZZ;开循环后置1,无键按下时进入灯的点亮延时程序.其他情况下置0,无键按下时返回 AJMP K_SCAN; 键扫描. MAIN4: CALL DELAY ;延时示去抖动 ;MOV R0,30H CJNE R0,#0C0H,MAIN5;再次判断键是否按下 JB 20H.7,ZZZ AJMP K_SCAN TT: AJMP MAIN2;作跳转接力 ZZZ: AJMP DELAY1 ;*********判断键有无按下及何键按下************ MAIN5: ;MOV A,#01H;MOV A,32H;MOV A,26H JNB P1.6,LOOP1 ;电源键K1按下 JNB 20H.5,K_SCAN JNB P1.7,LOOP2 ;K2按下 RET ;*********进入按键及遥控按键处理程序********************** ;*********接下来为遥控控制的电源开/关,开循环/关循环******* KK: CLR 20H.0 JNB 20H.1,KKA SETB P1.5 ;开LED5V MOV P0,#0FH CLR 20H.1 ;置关LED5V标志位 SETB 20H.2 SETB 20H.5 CLR 20H.6 CLR 20H.7;设置电源开后,使该位为0则在无键按下时返回键扫描. AJMP K_SCAN KKA: CLR P1.5 ;关LED5V MOV P0,#00H SETB 20H.1 ;置开LED5V标志位 CLR 20H.2;关循环点亮标志位 CLR 20H.5 CLR 20H.6 CLR 20H.7;设置在关电源后,使该位为0则在无键按下时返回键扫描. AJMP K_SCAN LL: CLR 20H.3 JNB 20H.2,LLA;若20H.2为1则开始进入循环点亮 CLR 20H.1 CLR 20H.2 SETB 20H.5 SETB 20H.6 SETB 20H.7;设置进入灯循环亮的状态后,使该位为1,则无键按下时直接进入灯的点亮延时程序. AJMP K_SCAN LLA: MOV P0,#00H CLR 20H.1 SETB 20H.2 SETB 20H.5 CLR 20H.6 CLR 20H.7;设置退出循环灯亮后,使该位为0则在无键按下时返回键扫描. AJMP K_SCAN ;********以下为按键控制的电源开/关,开循环/关循环***************** LOOP1: JNB 20H.1,LOOP1A SETB P1.5 ;开LED5V MOV P0,#0FH ACALL DELAY JNB P1.6,$ ; 判断键是否释放(相当重要) CLR 20H.1 ;置关LED5V标志位 SETB 20H.2 SETB 20H.5 CLR 20H.6 CLR 20H.7;设置电源开后,使该位为0则在无键按下时返回键扫描. AJMP K_SCAN LOOP1A: CLR P1.5 ;关LED5V MOV P0,#00H ACALL DELAY JNB P1.6,$ ;判断键是否释放(相当重要) SETB 20H.1 ;置开LED5V标志位 CLR 20H.2;关循环点亮标志位 CLR 20H.5 CLR 20H.6 CLR 20H.7;设置在关电源后,使该位为0则在无键按下时返回键扫描. AJMP K_SCAN LOOP2: JNB 20H.2,OFFLED;若20H.2为1则开始进入循环点亮 ACALL DELAY JNB P1.7,$ CLR 20H.1 CLR 20H.2 SETB 20H.5 SETB 20H.6;开循环后, SETB 20H.7;设置进入灯循环亮的状态后,使该位为1,则无键按下时直接进入灯的点亮延时程序. AJMP K_SCAN OFFLED: MOV P0,#00H ACALL DELAY JNB P1.7,$ CLR 20H.1 SETB 20H.2 SETB 20H.5 CLR 20H.6 CLR 20H.7;设置退出循环灯亮后,使该位为0则在无键按下时返回键扫描. AJMP K_SCAN DELAY: MOV R6,#100 ;用于按键延时 DEL: MOV R7,#0FFH DJNZ R7,$ DJNZ R6,DEL RET DELAY1: MOV R5,#5;设置灯的点亮时间为100个周期延时时间 D4: MOV R6,#75 D5: MOV R7,#0FFH DJNZ R7,$ DJNZ R6,D5 DJNZ R5,D4 RET END