2024年2月24日发(作者:謇梅风)
word
;此程序为在两个数码管上实现00-99的循环显示
;设置ram
DATA_IN DATA 20H;接收数据缓冲存放器
DATA_OUT DATA 21H;发送数据缓冲存放器
BIT_COUNT DATA 22H;数据位数存放器
//HOUR DATA 23H
//MINITE DATA 24H
//SECOND DATA 25H
//MSECOND DATA 26H
ORG0000H
LJMPINIT
ORG000BH
LJMPTIME0;定时器0中断入口
ORG 0013H
LJMP KBHIT
;初始化
ORG0030H
INIT:MOVDPTR,#4000H;HD7279A的地址
MOVA,#10011111B;HD7279A初始化CS、CLK、DATA
1 / 13
word
MOVXDPTR,A
LCALLDELAY25MS;延时后进入工作状态
MOVDATA_OUT,#10100100B;HD7279A复位指令
LCALLSEND;发送指令
MOVA,#10011111B;设回CS为高电平
MOVX DPTR,A
//MOVR4,#20;定时器一个周期内的中断数
MOV R2,#0
MOV R3,#0
MOV R4,#0
MOV R5,#0
//MOVMSECOND,#0
//MOVSECOND,#0
//MOVMINITE,#0
//MOVHOUR,#0 ;数字计数器
MOVR6,#0;个位存放器
MOVR7,#0;十位存放器
MOVTMOD,#1;设置定时器0工作模式为方式1
//MOVTH0,#3CH;设置定时器定时值
//MOVTL0,#0B0H
MOVTH0,#0FCH;设置定时器定时值
MOVTL0,#18H
2 / 13
word
SETBEA;开总中断
SETBET0;开定时器0中断
SETB EX1
SETBTR0;开始计时
;主程序
MAIN:MOVA,R2;把数字转换为2个BCD码
MOVB,#10
DIVAB
MOVR6,B;个位放在R6
MOVR7,A;十位放在R7
MOVDATA_OUT,#11001000B;下载数据且按方式1译码,找到了第1个数码管
LCALLSEND
LCALLDELAY25;T4,指令与数据时间间隔
MOVDATA_OUT,R1;指令的数据局部,显示个位
LCALLSEND
MOVA,#10011111B
MOVXDPTR,A
MOVDATA_OUT,#11001001B;下载数据且按方式1译码,找到了第2个数码管
LCALLSEND
LCALLDELAY25;T4,指令与数据时间间隔
MOVDATA_OUT,R2;指令的数据局部,显示个位
LCALLSEND
MOVA,#10011111B
3 / 13
word
MOVXDPTR,A
MOVDATA_OUT,#11001010B;下载数据且按方式1译码,找到了第3个数码管
LCALLSEND
LCALLDELAY25;T4,指令与数据时间间隔
MOVDATA_OUT,R3;指令的数据局部,显示个位
LCALLSEND
MOVA,#10011111B
MOVXDPTR,A
//LCALLDELAY1MS;显示延时
MOVA,R4;把数字转换为2个BCD码
MOVB,#10
DIVAB
MOVR6,B;个位放在R6
MOVR7,A;十位放在R7
MOVDATA_OUT,#11001011B;下载数据且按方式1译码,找到了第4个数码管
LCALLSEND
LCALLDELAY25;T4,指令与数据时间间隔
MOVDATA_OUT,R6;指令的数据局部,显示个位
LCALLSEND
MOVA,#10011111B
MOVXDPTR,A
//LCALLDELAY1MS;显示延时
4 / 13
word
MOVDATA_OUT,#11001100B;下载数据且按方式1译码,找到了第5个数码管
LCALLSEND
LCALLDELAY25;T4,指令与数据时间间隔
MOVDATA_OUT,R7;指令的数据局部,显示十位
LCALLSEND
MOVA,#10011111B
MOVXDPTR,A
//LCALLDELAY1MS;显示延时
MOVA,R5;把数字转换为2个BCD码
MOVB,#10
DIVAB
MOVR6,B;个位放在R6
MOVR7,A;十位放在R7
MOVDATA_OUT,#11001101B;下载数据且按方式1译码,找到了第6个数码管
LCALLSEND
LCALLDELAY25;T4,指令与数据时间间隔
MOVDATA_OUT,R6;指令的数据局部,显示个位
LCALLSEND
MOVA,#10011111B
MOVXDPTR,A
//LCALLDELAY1MS;显示延时
5 / 13
word
MOVDATA_OUT,#11001110B;下载数据且按方式1译码,找到了第7个数码管
LCALLSEND
LCALLDELAY25;T4,指令与数据时间间隔
MOVDATA_OUT,R7;指令的数据局部,显示十位
LCALLSEND
MOVA,#10011111B
MOVXDPTR,A
//LCALLDELAY1MS;显示延时
LJMPMAIN;下一循环
SJMP$
;发送子程序
SEND:CLRET0;加锁
MOVBIT_COUNT,#8;无论指令还是数据,一次只发送8位
MOVA,#00011111B;设CS为低电平
MOVXDPTR,A
LCALLDELAY50;T1,从CS下降沿至CLK脉冲时间
;发送循环,HD7279A采用串行方式与微处理器通讯,一次发送一位
SENDLOOP:MOVA,DATA_OUT;取出发送的指令或数据
MOV C,ACC.7;串行发送从高位到低位发送,故先取最高位
MOV A,#00011111B;输出到DAT位
MOV ACC.5,C
MOVX DPTR,A
6 / 13
word
SETB C;设CLK为高电平
MOV ACC.6,C
MOVX DPTR,A
LCALL DELAY8;T2,传送指令时CLK脉冲宽度
CLR C;设CLK为低电平
MOV ACC.6,C
MOVX DPTR,A
LCALL DELAY8;T3,字节传送中CLK脉冲时间
MOV A,DATA_OUT;移位待发送的指令或数据,为下一位的发送作准备
RL A
MOV DATA_OUT,A
DJNZ BIT_COUNT,SENDLOOP;发送不到8位,继续循环
MOVA,#00011111B;发送完毕,恢复DAT
MOVX DPTR,A
SETBET0;释放锁
RET
;接收子程序(本程序中用不到,但在添加按键操作的时候用于读取键值)
RECEIVE:CLRET0;加锁
MOVBIT_COUNT,#8;接收8位数据
MOVDATA_IN,#0;清空接收数据缓冲存放器
MOVA,#00111111B;设CS为低电平,同时保证DAT为高电平(输入状态)
MOVXDPTR,A
LCALLDELAY25;T5,读键盘指令中指令与数据时间间隔
7 / 13
word
;接收循环,HD7279A采用串行方式与微处理器通讯,一次接收一位
RECEIVELOOP:SETBACC.6;设CS为高电平
MOVXDPTR,A
LCALLDELAY8;T6,输出键盘数据建立时间
MOV A,DATA_IN;接收数据缓冲存放器向左移位,准备接收一位数据,数据的高位会先发送
RL A
MOV DATA_IN,A
MOVXA,DPTR;读取数据
MOVC,ACC.5;取出数据位DAT
MOVA,DATA_IN
MOVACC.0,C
MOVDATA_IN,A;数据放进接收数据缓冲存放器
MOVA,#00111111B;设CS为低电平,同时保证DAT为高电平(输入状态)
MOVXDPTR,A
LCALLDELAY8;T7,读键盘数据是CLK脉冲宽
DJNZBIT_COUNT,RECEIVELOOP;接收不到8位,继续循环
MOVA,#00011111B;接收完毕,恢复DAT
MOVX DPTR,A
SETBET0;释放锁
RET
;定时器0中断程序
TIME0:
8 / 13
word
// DJNZR4,NEXT;定时器一个周期内中断数不够就继续计时
INCR2;数字加1
//MOVR4,#20;重置定时器一个周期内中断数
CJNER2,#100,NEXT;数字不够100继续加1
MOVR2,#0;数字到达100就清零
INC R3
CJNER3,#10,NEXT
MOVR3,#0
INC R4
CJNER4,#60,NEXT
MOVR4,#0
INC R5
CJNER5,#60,NEXT
MOVR5,#0
NEXT:MOVTH0,#0FCH;定时器方式1中断后需要重新设置定时器定时值
MOVTL0,#18H
RETI
KBHIT: PUSHPSW
PUSH ACC
PUSH DPH
PUSH DPL
PUSH DATA_OUT
PUSH BIT_COUNT
9 / 13
word
MOV A,R0
PUSH ACC
MOV A,R1
PUSH ACC
MOV DATA_OUT,#00010101B
LCALL SEND
LCALL DELAY25
LCALL RECEIVE
MOV A,DATA_IN
JZ START
DEC A
DEC A
JZ STOP
DEC A
JZ CLEAR
SJMP OUT
START: SETB TR0
SJMP OUT
STOP: CLR TR0
SJMP OUT
CLEAR: MOVR2,#0
10 / 13
word
MOVR3,#0
MOVR4,#0
MOVR5,#0
OUT: POP ACC
MOV R1,A
POP ACC
MOV R0,A
POP BIT_COUNT
POP DATA_OUT
POP DPL
POP DPH
POP ACC
POPPSW
RETI
;延时25ms子程序
DELAY25MS:MOVR0,#49
D11:MOVR1,#253
NOP
D12:DJNZR1,D12
11 / 13
word
DJNZR0,D11
RET
;延时50μs子程序
DELAY50:MOVR0,#23
NOP
D21:DJNZR0,D21
RET
;延时25μs子程序
DELAY25:MOVR0,#11
D31:DJNZR0,D31
RET
;延时8μs子程序
DELAY8:MOVR0,#2
NOP
D41:DJNZR0,D41
RET
;延时1ms子程序
DELAY1MS:MOVR0,#2
NOP
D51:MOVR1,#247
NOP
12 / 13
word
D52:DJNZR1,D52
DJNZR0,D51
RET
END
13 / 13
2024年2月24日发(作者:謇梅风)
word
;此程序为在两个数码管上实现00-99的循环显示
;设置ram
DATA_IN DATA 20H;接收数据缓冲存放器
DATA_OUT DATA 21H;发送数据缓冲存放器
BIT_COUNT DATA 22H;数据位数存放器
//HOUR DATA 23H
//MINITE DATA 24H
//SECOND DATA 25H
//MSECOND DATA 26H
ORG0000H
LJMPINIT
ORG000BH
LJMPTIME0;定时器0中断入口
ORG 0013H
LJMP KBHIT
;初始化
ORG0030H
INIT:MOVDPTR,#4000H;HD7279A的地址
MOVA,#10011111B;HD7279A初始化CS、CLK、DATA
1 / 13
word
MOVXDPTR,A
LCALLDELAY25MS;延时后进入工作状态
MOVDATA_OUT,#10100100B;HD7279A复位指令
LCALLSEND;发送指令
MOVA,#10011111B;设回CS为高电平
MOVX DPTR,A
//MOVR4,#20;定时器一个周期内的中断数
MOV R2,#0
MOV R3,#0
MOV R4,#0
MOV R5,#0
//MOVMSECOND,#0
//MOVSECOND,#0
//MOVMINITE,#0
//MOVHOUR,#0 ;数字计数器
MOVR6,#0;个位存放器
MOVR7,#0;十位存放器
MOVTMOD,#1;设置定时器0工作模式为方式1
//MOVTH0,#3CH;设置定时器定时值
//MOVTL0,#0B0H
MOVTH0,#0FCH;设置定时器定时值
MOVTL0,#18H
2 / 13
word
SETBEA;开总中断
SETBET0;开定时器0中断
SETB EX1
SETBTR0;开始计时
;主程序
MAIN:MOVA,R2;把数字转换为2个BCD码
MOVB,#10
DIVAB
MOVR6,B;个位放在R6
MOVR7,A;十位放在R7
MOVDATA_OUT,#11001000B;下载数据且按方式1译码,找到了第1个数码管
LCALLSEND
LCALLDELAY25;T4,指令与数据时间间隔
MOVDATA_OUT,R1;指令的数据局部,显示个位
LCALLSEND
MOVA,#10011111B
MOVXDPTR,A
MOVDATA_OUT,#11001001B;下载数据且按方式1译码,找到了第2个数码管
LCALLSEND
LCALLDELAY25;T4,指令与数据时间间隔
MOVDATA_OUT,R2;指令的数据局部,显示个位
LCALLSEND
MOVA,#10011111B
3 / 13
word
MOVXDPTR,A
MOVDATA_OUT,#11001010B;下载数据且按方式1译码,找到了第3个数码管
LCALLSEND
LCALLDELAY25;T4,指令与数据时间间隔
MOVDATA_OUT,R3;指令的数据局部,显示个位
LCALLSEND
MOVA,#10011111B
MOVXDPTR,A
//LCALLDELAY1MS;显示延时
MOVA,R4;把数字转换为2个BCD码
MOVB,#10
DIVAB
MOVR6,B;个位放在R6
MOVR7,A;十位放在R7
MOVDATA_OUT,#11001011B;下载数据且按方式1译码,找到了第4个数码管
LCALLSEND
LCALLDELAY25;T4,指令与数据时间间隔
MOVDATA_OUT,R6;指令的数据局部,显示个位
LCALLSEND
MOVA,#10011111B
MOVXDPTR,A
//LCALLDELAY1MS;显示延时
4 / 13
word
MOVDATA_OUT,#11001100B;下载数据且按方式1译码,找到了第5个数码管
LCALLSEND
LCALLDELAY25;T4,指令与数据时间间隔
MOVDATA_OUT,R7;指令的数据局部,显示十位
LCALLSEND
MOVA,#10011111B
MOVXDPTR,A
//LCALLDELAY1MS;显示延时
MOVA,R5;把数字转换为2个BCD码
MOVB,#10
DIVAB
MOVR6,B;个位放在R6
MOVR7,A;十位放在R7
MOVDATA_OUT,#11001101B;下载数据且按方式1译码,找到了第6个数码管
LCALLSEND
LCALLDELAY25;T4,指令与数据时间间隔
MOVDATA_OUT,R6;指令的数据局部,显示个位
LCALLSEND
MOVA,#10011111B
MOVXDPTR,A
//LCALLDELAY1MS;显示延时
5 / 13
word
MOVDATA_OUT,#11001110B;下载数据且按方式1译码,找到了第7个数码管
LCALLSEND
LCALLDELAY25;T4,指令与数据时间间隔
MOVDATA_OUT,R7;指令的数据局部,显示十位
LCALLSEND
MOVA,#10011111B
MOVXDPTR,A
//LCALLDELAY1MS;显示延时
LJMPMAIN;下一循环
SJMP$
;发送子程序
SEND:CLRET0;加锁
MOVBIT_COUNT,#8;无论指令还是数据,一次只发送8位
MOVA,#00011111B;设CS为低电平
MOVXDPTR,A
LCALLDELAY50;T1,从CS下降沿至CLK脉冲时间
;发送循环,HD7279A采用串行方式与微处理器通讯,一次发送一位
SENDLOOP:MOVA,DATA_OUT;取出发送的指令或数据
MOV C,ACC.7;串行发送从高位到低位发送,故先取最高位
MOV A,#00011111B;输出到DAT位
MOV ACC.5,C
MOVX DPTR,A
6 / 13
word
SETB C;设CLK为高电平
MOV ACC.6,C
MOVX DPTR,A
LCALL DELAY8;T2,传送指令时CLK脉冲宽度
CLR C;设CLK为低电平
MOV ACC.6,C
MOVX DPTR,A
LCALL DELAY8;T3,字节传送中CLK脉冲时间
MOV A,DATA_OUT;移位待发送的指令或数据,为下一位的发送作准备
RL A
MOV DATA_OUT,A
DJNZ BIT_COUNT,SENDLOOP;发送不到8位,继续循环
MOVA,#00011111B;发送完毕,恢复DAT
MOVX DPTR,A
SETBET0;释放锁
RET
;接收子程序(本程序中用不到,但在添加按键操作的时候用于读取键值)
RECEIVE:CLRET0;加锁
MOVBIT_COUNT,#8;接收8位数据
MOVDATA_IN,#0;清空接收数据缓冲存放器
MOVA,#00111111B;设CS为低电平,同时保证DAT为高电平(输入状态)
MOVXDPTR,A
LCALLDELAY25;T5,读键盘指令中指令与数据时间间隔
7 / 13
word
;接收循环,HD7279A采用串行方式与微处理器通讯,一次接收一位
RECEIVELOOP:SETBACC.6;设CS为高电平
MOVXDPTR,A
LCALLDELAY8;T6,输出键盘数据建立时间
MOV A,DATA_IN;接收数据缓冲存放器向左移位,准备接收一位数据,数据的高位会先发送
RL A
MOV DATA_IN,A
MOVXA,DPTR;读取数据
MOVC,ACC.5;取出数据位DAT
MOVA,DATA_IN
MOVACC.0,C
MOVDATA_IN,A;数据放进接收数据缓冲存放器
MOVA,#00111111B;设CS为低电平,同时保证DAT为高电平(输入状态)
MOVXDPTR,A
LCALLDELAY8;T7,读键盘数据是CLK脉冲宽
DJNZBIT_COUNT,RECEIVELOOP;接收不到8位,继续循环
MOVA,#00011111B;接收完毕,恢复DAT
MOVX DPTR,A
SETBET0;释放锁
RET
;定时器0中断程序
TIME0:
8 / 13
word
// DJNZR4,NEXT;定时器一个周期内中断数不够就继续计时
INCR2;数字加1
//MOVR4,#20;重置定时器一个周期内中断数
CJNER2,#100,NEXT;数字不够100继续加1
MOVR2,#0;数字到达100就清零
INC R3
CJNER3,#10,NEXT
MOVR3,#0
INC R4
CJNER4,#60,NEXT
MOVR4,#0
INC R5
CJNER5,#60,NEXT
MOVR5,#0
NEXT:MOVTH0,#0FCH;定时器方式1中断后需要重新设置定时器定时值
MOVTL0,#18H
RETI
KBHIT: PUSHPSW
PUSH ACC
PUSH DPH
PUSH DPL
PUSH DATA_OUT
PUSH BIT_COUNT
9 / 13
word
MOV A,R0
PUSH ACC
MOV A,R1
PUSH ACC
MOV DATA_OUT,#00010101B
LCALL SEND
LCALL DELAY25
LCALL RECEIVE
MOV A,DATA_IN
JZ START
DEC A
DEC A
JZ STOP
DEC A
JZ CLEAR
SJMP OUT
START: SETB TR0
SJMP OUT
STOP: CLR TR0
SJMP OUT
CLEAR: MOVR2,#0
10 / 13
word
MOVR3,#0
MOVR4,#0
MOVR5,#0
OUT: POP ACC
MOV R1,A
POP ACC
MOV R0,A
POP BIT_COUNT
POP DATA_OUT
POP DPL
POP DPH
POP ACC
POPPSW
RETI
;延时25ms子程序
DELAY25MS:MOVR0,#49
D11:MOVR1,#253
NOP
D12:DJNZR1,D12
11 / 13
word
DJNZR0,D11
RET
;延时50μs子程序
DELAY50:MOVR0,#23
NOP
D21:DJNZR0,D21
RET
;延时25μs子程序
DELAY25:MOVR0,#11
D31:DJNZR0,D31
RET
;延时8μs子程序
DELAY8:MOVR0,#2
NOP
D41:DJNZR0,D41
RET
;延时1ms子程序
DELAY1MS:MOVR0,#2
NOP
D51:MOVR1,#247
NOP
12 / 13
word
D52:DJNZR1,D52
DJNZR0,D51
RET
END
13 / 13