1、/*实验名 :LED灯控制器(基础部分) */$include (C8051F310.inc) ORG 001BH LJMP TIME1 ORG 00BH LJMP TIME0 ORG 002BH LJMP TIME2 ORG 0000H LJMP MAIN ORG 1000HMAIN: LCALL Init_Device ;初始化配置 LED BIT P0.0 BEEP BIT P3.1 CLR P0.6 ;选末位数码管 CLR P0.7 CLR BEEP ;关闭蜂鸣器 MOV P1,#0FCH ;初始数码管显示 MOV DPTR,#TAB ;存数码表表头 MOV R0,#00H ;亮度等级
2、初始 MOV R3,#08H ;LED亮度持续循环八次0.25*8 MOV R4,#02H ;蜂鸣器定时循环两次0.25s*2 MOV A,#00START: CJNE R0,#00H,A1 LCALL VOICE ;最暗蜂鸣器打开A1: CJNE R0,#0FH,A2最亮蜂鸣器打开A2: SETB TR1 SETB TR0LOOP: JB PSW.5,NEXT CJNE A,00H,CCCC: JC OPEN ;判断是熄灭还是点亮LED SETB LED SJMP LOOPOPEN: CLR LEDNEXT: CLR PSW.5 DJNZ R3,LOOP ;T0定时器定时循环8次0.25*8
3、=2s CLR TR1 ;调整亮度等级模块 CLR TR0 CLR A MOV R3,#08H CJNE R0,#0FH,L1 ;达到亮度等级上限开始递增模式 SETB (20H).0 L1: CJNE R0,#00H,L2 ;达到亮度等级下限开始递增模式 CLR (20H).0L2: JNB (20H).0,L3 DEC R0 SJMP XIAN L3: INC R0XIAN: PUSH ACC ;调整数码管显示模块 MOV A,R0 MOVC A,A+DPTR MOV P1,A POP ACC SJMP START;*蜂鸣器VOICE: SETB BEEP ;开蜂鸣 SETB TR2 ;开
4、定时器2 RETTAB: DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0H DB 0FEH,0E6H,0EEH,3EH,1AH,7AH,9EH,8EH定时器模块TIME0: MOV TH0,#06H MOV TL0,#0C6H SETB PSW.5 ;用于0.25s中断标志 RETITIME1: MOV (20H).1,C ;保护判断位 JC UP INC A MOV TH1,#0FCH MOV TL1,#018H CJNE A,#0FH,L MOV A,#0HL: MOV C,(20H).1TIME2: CLR TF2H DJNZ R4,LOOP1 ;循环2次
5、0.25*2=0.5s MOV R4,#02H关蜂鸣 CLR TR2LOOP1: RETI Peripheral specific initialization functions, Called from the Init_Device labelPCA_Init: anl PCA0MD, #0BFh mov PCA0MD, #000h retPort_IO_Init: mov XBR1, #040h mov P1MDOUT, #0FFhTimer_Init: mov TMOD, #021h mov TL0, #0C6h mov TL1, #081h mov TH0, #06h mov TH
6、1, #081h mov TMR2L, #0C6h mov TMR2H, #006hInterrupts_Init: mov IE, #0AAh Initialization function for device, Call Init_Device from your main programInit_Device: lcall PCA_Init lcall Port_IO_Init lcall Timer_Init lcall Interrupts_InitEnd/* 实验名 :LED灯控制器(提高部分)* 注 意 :系统时钟为内部振荡器8分频,T1,T0时钟为系统时钟12分频 ORG 0
7、000H LJMP MAIN ORG 0003H ;外部中断0入口 LJMP KINT ORG 001BH ;T1中断入口 LJMP TIME1 ORG 002BH ;T2中断入口 LJMP TIME2 ORG 0100H CLR P3.1 ;关蜂鸣器 ACALL Init_Device ;调用初始化配置 MOV R0,#0 ;记录led等级 MOV R1,#1 ;R1=0亮度在递减,R1=1亮度在递增 MOV R2,#0 ;记录数码管位选 MOV R3,#0 ;赋值PCA0CPL0,PCA0CPH0 CLR 0H ;位寻址0h判断是暂停LED还是恢复LED MOV 30H,#0 ;用于判断输
8、入的是第几位数主程序 GO: SETB TR1 ;打开定时器t1 MOV R4,#8 ;定时0.25s*8=2s ACALL AA ;数码管,蜂鸣器,led灯模块 AJMP GO AA: MOV PCA0CPL0,R3 ;输入脉冲占空比 MOV PCA0CPH0,R3 MOV PCA0CN,#040H ;允许PCA计数器/定时器 CJNE R0,#0,CHMAX ACALL VOICE ;r0=0H,蜂鸣器响 SETB P0.0 MOV PCA0CN,#0 CHMAX: CJNE R0,#31H,LED r0=31H,蜂鸣器响 LED: CJNE R2,#2,FINE ;r2可取值为0或1,为
9、0时末位数码管亮,为1时第三个数码管亮 MOV R2,#0H FINE: CJNE R2,#0,ONE MOV A,R0 ANL A,#0FH ;保留低位 CLR P0.6 AJMP LOOK ONE: MOV A,R0 ANL A,#0F0H ;保留高位 SWAP A SETB P0.6 LOOK: MOV DPTR,#SHUMA ;数码表存于dptr MOVC A,A+DPTR ;查表显示亮度等级 MOV P1,A ;送数码管段控 MOV R5,#28H DL1: MOV R6,#0FFH ;循环定时DL10: DJNZ R6,DL10 DJNZ R5,DL1 INC R2 ;改变位选 S
10、JMP LED RET 蜂鸣器模块* SETB TR2 ; SETB P3.1 ;打开蜂鸣器 MOV R7,#2 ;用于定时器2,0.25秒*2=0.5秒 RET 键盘输入模块BB: ACALL D10MS ;消抖 ACALL KEXAM ;检查是否有按键按下 JZ BB ACALL CHAXUN ;转入键盘扫描 MOV R0,30H ;判断现在是输入第几个数 CJNE R0,#0,SECOND ;30h=0表示第一个数,1表示第二个数 MOV 45H,A ;取第一个数暂存45h中 CLR C SUBB A,#4 JC OK ;判断第一个数是否小于4,大于等于4时无效 MOV 45H,#0 ;
11、无效数清零 AJMP BB ;继续查询OK: MOV A,45H ACALL LED1 ;显示按下的数字 INC 30H ;进入第二个数的查询 AJMP BB SECOND: MOV 46H,A ;取第二个数暂存46h中 MOV R6,45H CJNE R6,#3,FF1 SUBB A,#2 ;当第一个数是3时第二个数大于1无效 JNC UNLG MOV A,46H CJNE A,#1,FF0 ;当第一个数是3第二个数是1时,改为递减模式 MOV R1,#0 ;下降 AJMP FF0FF1: MOV A,45H CJNE A,#00H,FF0 MOV A,46H ;当输入第一个数为0第二个数也
12、为0时,改为递增模式上升FF0: MOV A,46H 显示按下的数字 MOV 30H,#0 AJMP OVER UNLG: MOV 46H,#0 OVER: MOV A,45H ;装载亮度等级,以及对应的pwm值 MOV B,#10H MUL AB ADD A,46H MOV R0,A MOV A,45H MOV B,#0AH MUL AB ADD A,46H MOV B,#08 MOV R3,A装载结束,准备进入缓冲阶段 CLR 0H MOV P1,#0 ;关闭数码管 SETB P3.3 ;开始启动LED阵列功能 MOV R7,#10HP20S: CPL P3.4 ;取反CLK用于产生时钟信
13、号 MOV A,#6P21S: LCALL D10MS DJNZ ACC,P21S DJNZ R7,P20S ;移位8次,led阵列依次熄灭 SETB EX0 ;允许外部0中断 LJMP GO ;缓冲阶段结束,跳转回主程序键盘扫描模块CHAXUN: MOV 39H,#0FFH MOV R5,#0FFH CLR C SKAN: MOV A,39H RLC A ;逐行扫描 INC R5 MOV 39H,A MOV P2,A MOV A,P2 ANL A,#0F0H CJNE A,#0F0H,YES ;列检查有低电平时转列扫描 AJMP SKAN YES: SETB C MOV R6,#4 PAND
14、UAN:RLC A ;逐列扫描 DEC R6 JC PANDUAN MOV A,R5 ;r6为列值,r5为行值,两者相加为键值 MOV B,#4 ADD A,R6 MOV DPTR,#JIANPAN MOVC A,A+DPTR RET 判断是否有按键按下KEXAM: MOV P2,#0F0H CJNE A,#0F0H,YES1 MOV A,#0 ;没有按键按下 RET YES1: MOV A,#1 ;有按键按下用于显示键盘的输入值LED1: MOV R7,30H ;30H单元记录按下的是第几个数 MOV DPTR,#SHUMA CJNE R7,#0,DSP10 AJMP THERE DSP10
15、: CLR P0.6 THERE: MOVC A,A+DPTR MOV P1,A DD5S: MOV A,P2 CJNE A,#0F0H,DD5S 延时子程序用于消抖D10MS: MOV R5,#25H ;6ms延时用于消抖Dl: MOV R6,#0FFH ;Dl0: DJNZ R6,Dl0 DJNZ R5,Dl RET SHUMA: DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0H,0FEH,0F6H,0EEH,03EH,09CH,07AH,09EH,08EH,0CEH JIANPAN:DB 0,4,8,0FFH,1,5,9,0FFH,2,6,0FFH,0FF
16、H,3,7,0FFH,0FFH外部0中断服务程序用于处理KINT键KINT: LCALL D10MS ;延时10ms消抖关掉led阵列D21S: CPL P3.4 DJNZ R7,D21S ;移位8次全关 CLR EX0 ;禁止外部0中断 CLR TR1 ;关闭T1定时器关掉数码管 MOV PCA0CPL0,#0 ;关闭LED灯 MOV PCA0CPH0,#0 CLR P3.3 ;打开LED阵列,全部点亮则进入键盘模式D22S: MOV A,#7D23S: MOV C,P0.1 JC LOOP705 ;长按才能进入键盘输入模块 DJNZ ACC,D23S DJNZ R7,D22S ;循环16次
17、,产生8个周期的时钟信号,移位8次全亮 MOV 34H,#01H MOV 35H,#5DH ;015DH为BB入口地址 PUSH 35H ;将键盘输入模块地址入栈,使中断返回后进入 PUSH 34HLOOP702:RETI ;跳转到键盘输入模块LOOP705:MOV C,0H JC START CPL C ;暂停并关闭LED中断返回后进入踏步 MOV 0H,C MOV 32H,#02H MOV 33H,#0BAH ;02BAH为sjmp $地址入口 PUSH 33H ;将sjmp $地址存入堆栈使中断返回后能进入 PUSH 32H AJMP LOOP70start: CPL C ;恢复LED
18、POP 32H ;把sjmp $地址从堆栈中移除使中断返回进入主程序 POP 33HD31S: DJNZ R7,D31S ; SETB TR1 LOOP70: SETB EX0 ;允许外部0中断 SJMP $ T1中断服务程序用于调整PWM DJNZ R4,YY6 ;先循环8次中断定时2s CJNE R1,#0,YY0 ;判断R1的状态 DEC R0 ;亮度等级在递减 ANL A,#0FH CJNE A,#0FH,YY00 ;当低位从0减到F时将F转化为9 MOV A,R0 CLR C SUBB A,#06H MOV R0,A ;得到正确的亮度等级 YY00: MOV A,R3 CLR C SUBB A,#8 CJNE R0,#0,YY2 ;到最暗后开始上升 MOV R1,#1 AJMP YY2 YY0: INC R0 ;亮度等级在递增 CJNE A,#0AH,YY02 ;当低位从9加到A时将A转化为0 ADD A,#6 YY02: MOV A,R3 CJNE R
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1