;************************************************************************** ; HD7279A 测试演示程序 ; ; 测试内容包括: 测试指令,复位指令,段寻址指令,下载数据且译码指令(2种), ; 下载数据且不译码指令,左/右移指令,循环左/右移指令,闪烁指令,消隐指令, ; 键盘输入测试 ;************************************************************************** $ title (HD7279A 演示程序, AT89C2051 @ 12MHz) $ DB ;****************************************** ; 变量定义 ;****************************************** BIT_COUNT DATA 03FH TIMER DATA 03EH TIMER1 DATA 03DH TIMER2 DATA 03CH TIMER3 DATA 03BH TIMER4 DATA 03AH SEG_NUM DATA 039H SEG_CNT DATA 038H LAST_SEG DATA 037H DATA_IN DATA 020H DATA_OUT DATA 021H ;****************************************** ; 输入输出引脚定义 ;****************************************** CS BIT P1.4 ; CLK BIT P1.5 ; DAT BIT P1.2 ; KEY BIT P1.3 ; ORG 000H JMP START ORG 080H ;****************************************** ; 主程序 ;****************************************** START: MOV SP,#2FH MOV P1,#11011011B MOV TIMER3,#25 ;开机延时25MS START_DELAY: MOV TIMER4,#255 START_DELAY1: NOP NOP DJNZ TIMER4,START_DELAY1 DJNZ TIMER3,START_DELAY START_DEMO: ;****************************************** ; 测试指令演示 ;****************************************** MOV DATA_OUT,#10111111B ;发送测试指令 CALL SEND SETB CS MOV TIMER1,#10 ;延时约3秒 TEST_DELAY: MOV TIMER2,#255 TEST_DELAY1: MOV TIMER3,#255 TEST_DELAY2: NOP NOP DJNZ TIMER3,TEST_DELAY2 DJNZ TIMER2,TEST_DELAY1 DJNZ TIMER1,TEST_DELAY ;****************************************** ; 复位指令测试 ;****************************************** MOV DATA_OUT,#10100100B ;发送复位指令 CALL SEND SETB CS ;****************************************** ; 段寻址指令测试 ; 点亮的显示段在8只数码管间左往复8字运动3次 ;****************************************** MOV TIMER4,#3 ;设定循环次数 MOV LAST_SEG,#0FFH SEG_DEMO: MOV SEG_CNT,#28 ;循环一次共用28个显示段 SEG_LOOP: MOV A,SEG_CNT MOV DPTR,#SEG_TABLE-1 ;查表得显示段地址 MOVC A,@A+DPTR MOV SEG_NUM,A MOV DATA_OUT,#11100000B ;发段点亮指令点亮当前段 CALL SEND MOV DATA_OUT,SEG_NUM ;发段地址 CALL SEND SETB CS CALL DEMO_DELAY ;延时 MOV DATA_OUT,#11000000B ;发段熄灭指令关闭上一显示段 CALL SEND MOV DATA_OUT,LAST_SEG ;上一显示段的段地址 CALL SEND MOV LAST_SEG,SEG_NUM ;保存当前段地址 DJNZ SEG_CNT,SEG_LOOP ;显示下一显示段 DJNZ TIMER4,SEG_DEMO ;循环3次 ;************************************************* ; 下载数据但不译码指令测试 ;************************************************* MOV DATA_OUT,#10100100B ;发送复位指令 CALL SEND SETB CS CALL DEMO_DELAY CALL DEMO_DELAY CALL DEMO_DELAY CALL DEMO_DELAY MOV DATA_OUT,#10010111B ;在第8位按不译码方式显示一字符 CALL SEND MOV DATA_OUT,#01001001B ;显示一"三"字 CALL SEND SETB CS CALL DEMO_DELAY CALL DEMO_DELAY CALL DEMO_DELAY CALL DEMO_DELAY ;************************************************* ; 循环左/右移测试 ; "三"字向右运动3次,再向左运动3次,重复2遍 ;************************************************* MOV TIMER3,#2 ;重复2遍 CYCLED_ROTATE: MOV TIMER4,#23 ;循环右移23次 CR_R: MOV DATA_OUT,#10100010B ;循环右移指令 CALL SEND SETB CS CALL DEMO_DELAY CALL DEMO_DELAY DJNZ TIMER4,CR_R CALL DEMO_DELAY CALL DEMO_DELAY CALL DEMO_DELAY CALL DEMO_DELAY MOV TIMER4,#23 ;循环左移23次 CR_L: MOV DATA_OUT,#10100011B ;循环左移指令 CALL SEND SETB CS CALL DEMO_DELAY CALL DEMO_DELAY DJNZ TIMER4,CR_L CALL DEMO_DELAY CALL DEMO_DELAY CALL DEMO_DELAY CALL DEMO_DELAY DJNZ TIMER3,CYCLED_ROTATE ;********************************************* ; 译码方式0及左移指令测试 ;********************************************* MOV DATA_OUT,#10100100B ;发送复位指令 CALL SEND MOV TIMER4,#0 DECODE_0: MOV DATA_OUT,#10100001B ;左移指令 CALL SEND MOV DATA_OUT,#10000000B ;方式0译码指令,显示于第1位 CALL SEND MOV DATA_OUT,TIMER4 ;显示数据为0-F CALL SEND SETB CS CALL DELAY_500MS INC TIMER4 MOV A,TIMER4 CJNE A,#10H,DECODE_0 CALL DELAY_500MS CALL DELAY_500MS CALL DELAY_500MS CALL DELAY_500MS ;********************************************* ; 译码方式1及右移指令测试 ;********************************************* MOV DATA_OUT,#10100100B ;发送复位指令 CALL SEND MOV TIMER4,#0 DECODE_1: MOV DATA_OUT,#10100000B ;右移指令 CALL SEND MOV DATA_OUT,#11001111B ;方式1译码指令,显示于第8位 CALL SEND MOV DATA_OUT,TIMER4 ;发送显示数据(0-F) CALL SEND SETB CS CALL DELAY_500MS INC TIMER4 MOV A,TIMER4 CJNE A,#10H,DECODE_1 CALL DELAY_500MS CALL DELAY_500MS CALL DELAY_500MS CALL DELAY_500MS ;********************************************* ; 消隐指令测试 ;********************************************* CALL DELAY_500MS MOV DATA_OUT,#10011000B ;消隐控制指令 CALL SEND MOV DATA_OUT,#11110111B ;将第4位设为消隐 CALL SEND SETB CS CALL DELAY_500MS CALL DELAY_500MS MOV DATA_OUT,#10011000B ;消隐控制指令 CALL SEND MOV DATA_OUT,#11100111B ;增加第5位为消隐 CALL SEND SETB CS CALL DELAY_500MS CALL DELAY_500MS MOV DATA_OUT,#10011000B ;消隐控制指令 CALL SEND MOV DATA_OUT,#11100011B ;增加第3位为消隐 CALL SEND SETB CS CALL DELAY_500MS CALL DELAY_500MS MOV DATA_OUT,#10011000B ;消隐控制指令 CALL SEND MOV DATA_OUT,#11000011B ;增加第6位为消隐 CALL SEND SETB CS CALL DELAY_500MS CALL DELAY_500MS MOV DATA_OUT,#10011000B ;消隐控制指令 CALL SEND MOV DATA_OUT,#11000001B ;增加第2位为消隐 CALL SEND SETB CS CALL DELAY_500MS CALL DELAY_500MS MOV DATA_OUT,#10011000B ;消隐控制指令 CALL SEND MOV DATA_OUT,#10000001B ;增加第7位为消隐 CALL SEND SETB CS CALL DELAY_500MS CALL DELAY_500MS MOV DATA_OUT,#10011000B ;消隐控制指令 CALL SEND MOV DATA_OUT,#10000000B ;增加第1位为消隐 CALL SEND SETB CS CALL DELAY_500MS CALL DELAY_500MS CALL DELAY_500MS CALL DELAY_500MS MOV DATA_OUT,#10011000B ;消隐控制指令 CALL SEND MOV DATA_OUT,#10000001B ;将第1位恢复显示 CALL SEND SETB CS CALL DELAY_500MS CALL DELAY_500MS CALL DELAY_500MS MOV DATA_OUT,#10011000B ;消隐控制指令 CALL SEND MOV DATA_OUT,#10011001B ;将中间2位恢复显示 CALL SEND SETB CS CALL DELAY_500MS CALL DELAY_500MS CALL DELAY_500MS MOV DATA_OUT,#10011000B ;消隐控制指令 CALL SEND MOV DATA_OUT,#10111101B ;将中间4位恢复显示 CALL SEND SETB CS CALL DELAY_500MS CALL DELAY_500MS CALL DELAY_500MS MOV DATA_OUT,#10011000B ;消隐控制指令 CALL SEND MOV DATA_OUT,#11111111B ;全部恢复显示 CALL SEND SETB CS CALL DELAY_500MS CALL DELAY_500MS CALL DELAY_500MS ;********************************************** ; 闪烁指令及键盘接口测试 ; 接受用户输入0-9的数字并依次显示出来, 如果 ; 20秒内无按键或按S15键即重新开始演示 ;********************************************** MOV DATA_OUT,#10100100B ;发送复位指令 CALL SEND MOV DATA_OUT,#10001000B ;闪烁控制指令 CALL SEND MOV DATA_OUT,#11111110B ;第一位闪烁 CALL SEND MOV DATA_OUT,#10010000B ;下载数据但不译码指令 CALL SEND MOV DATA_OUT,#00001000B ;显示下画线"_" CALL SEND SETB CS MOV TIMER4,#0 MOV TIMER3,#0 MOV TIMER2,#0 WAIT_KEY: MOV A,TIMER4 ;计时 ADD A,#1 MOV TIMER4,A MOV A,TIMER3 ADDC A,#0 MOV TIMER3,A MOV A,TIMER2 ADDC A,#0 MOV TIMER2,A MOV A,TIMER4 ;检查是否到20秒 CJNE A,#0,CHECK_KEY MOV A,TIMER3 CJNE A,#0,CHECK_KEY MOV A,TIMER2 CJNE A,#20,CHECK_KEY JMP START_DEMO ;20秒内无键按下,从头开始 CHECK_KEY: JB KEY,WAIT_KEY ;未到时,检查按键,如无键则继续计时 MOV DATA_OUT,#00010101B ;有键按下,读键码 CALL SEND CALL RECEIVE SETB CS MOV TIMER4,#0 ;清计时器 MOV TIMER3,#0 MOV TIMER2,#0 MOV A,DATA_IN CJNE A,#15,NOT_S_15 ;检查是否是S15 JMP START_DEMO ;S15被按下,重新开始演示 NOT_S_15: MOV DATA_OUT,#10100001B ;左移指令 CALL SEND MOV DATA_OUT,#11001000B ;在第一位显示键码低8位 CALL SEND MOV DATA_OUT,DATA_IN CALL SEND SETB CS WAIT_RELEASE2: JNB KEY,WAIT_RELEASE2 JMP WAIT_KEY DELAY_500MS: MOV TIMER3,#10 DELAY_500MS_1: CALL DEMO_DELAY DJNZ TIMER3,DELAY_500MS_1 RET DEMO_DELAY: MOV TIMER1,#50 ;延时约50MS DEMO_DELAY_1: MOV TIMER,#250 DEMO_DELAY_2: NOP NOP DJNZ TIMER,DEMO_DELAY_2 DJNZ TIMER1,DEMO_DELAY_1 RET SEND: MOV BIT_COUNT,#8 CLR CS CALL LONG_DELAY SEND_LOOP: MOV C,DATA_OUT.7 MOV DAT,C SETB CLK MOV A,DATA_OUT RL A MOV DATA_OUT,A CALL SHORT_DELAY CLR CLK CALL SHORT_DELAY DJNZ BIT_COUNT,SEND_LOOP CLR DAT RET RECEIVE: MOV BIT_COUNT,#8 SETB DAT CALL LONG_DELAY RECEIVE_LOOP: SETB CLK CALL SHORT_DELAY MOV A,DATA_IN RL A MOV DATA_IN,A MOV C,DAT MOV DATA_IN.0,C CLR CLK CALL SHORT_DELAY DJNZ BIT_COUNT,RECEIVE_LOOP CLR DAT RET LONG_DELAY: MOV TIMER,#25 DELAY_LOOP: DJNZ TIMER,DELAY_LOOP RET SHORT_DELAY: MOV TIMER,#4 DELAY_LOOP_S: DJNZ TIMER,DELAY_LOOP_S RET ;************************************************* ; 循环显示段地址表 ;************************************************* SEG_TABLE: DB 59, 51, 43, 35 DB 36, 32, 33, 38 DB 30, 22, 14, 6 DB 5, 4, 3, 11 DB 19, 27, 26, 24 DB 29, 30, 38, 46 DB 54, 62, 57, 58 END