📄 com.asm
字号:
/****************************************************************************/
/* */
/* Copyright (c) 2005, 老树工作室 */
/* All rights reserved. */
/* */
/* Email:laoshu0902@163.com */
/* www.laoshu0902.bokee.com */
/* */
/****************************************************************************/
;+============================================================================+
;| 8051 伪指令定义 |
;+============================================================================+
WDI EQU 085H ;定义看门狗的清除标志
REC_STAT2 EQU 03H
;+============================================================================+
;| 8051 中断处理程序入口 |
;+============================================================================+
ORG 0000H ;程序开始
LJMP main ;跳转主程序
ORG 0003H ;外部中断int0的中断入口地址
LJMP EI0_ISR ;跳转定时器INT0中断服务子程序
;通常子程序的长度要大于2个中断之间的空间
;所以放到子程序中执行
ORG 000BH ;定时器t0的中断入口地址
LJMP T0_ISR ;跳转定时器0中断服务子程序
ORG 0013H ;外部中断int1的中断入口地址
LJMP EI1_ISR ;跳转定时器INT1中断服务子程序
ORG 0023H ;串口中断的中断入口地址
LJMP INTERS ;跳转串口中断服务子程序
;+============================================================================+
;| 8051 主程序 |
;+============================================================================+
ORG 100H ;主程序从地址100H开始执行
;是为了避开以上这些中断
;当然程序可以从30H开始
;从这个地址开始主要是为了HEX文件的好阅读
;阅读HEX文件,使用ultraedit的最新中文版本
;+============================================================================+
;| 8051 定时器、外部中断、串口配置 |
;+============================================================================+
main: MOV SP,#70H ;设置堆栈,以下是单片机初始化
MOV TMOD,#21H ;设置定时器1和串行接口参数9600波特率,时钟11.0592MHz
MOV TL1,#0FDH ;定时器1参数的设置
MOV TH1,#0FDH
SETB TR1 ;启动定时器1中断
MOV SCON,#50H ;启动串口控制寄存器
SETB ES ;启动串口中断
SETB ET0 ;启动定时器t0中断
CLR IT0 ;选择外部中断0为低电平触发
CLR IT1 ;选择外部中断1为低电平触发
SETB EX0 ;启动外部中断0
;SETB EX1 ;启动外部中断1
MOV TH0,#0B1H ;设置定时器0参数,定时器0的中断周期大约为2ms
MOV TL0,#0E0H
CLR RS0 ;设置寄存器区基本参数
CLR RS1
;SETB TR0 ;启动定时器0中断
SETB IP.4 ;设置中断优先级,串口中断为最高
CLR IP.1 ;设置定时器0优先级,低于串口中断
SETB EA ;启动全部中断
CLR REC_STAT2
;+============================================================================+
;| 8051 主流程 |
;+============================================================================+
L01: CPL WDI ;对看门狗取反
JNB REC_STAT2,L01 ;判断REC_STAT2是否为1,如果为1,表示接收到数据的尾部
L02: MOV A,31H
CJNE A,#30H,L1
LJMP LL0
L1: CJNE A,#31H,L2
LJMP LL1
L2: CJNE A,#32H,L3
LJMP LL2
L3: CJNE A,#33H,L4
LJMP LL3
L4: CJNE A,#34H,L5
LJMP LL4
L5: CJNE A,#35H,L6
LJMP LL5
L6: CJNE A,#36H,L7
LJMP LL6
L7: CJNE A,#37H,L01
LJMP LL7
LL0: CLR P1.0
SETB P1.1
SETB P1.2
SETB P1.3
SETB P1.4
SETB P1.5
SETB P1.6
SETB P1.7
SETB REC_STAT2 ;重新设置串口接收完整数据的标志位
AJMP L01
LL1: SETB P1.0
CLR P1.1
SETB P1.2
SETB P1.3
SETB P1.4
SETB P1.5
SETB P1.6
SETB P1.7
SETB REC_STAT2 ;重新设置串口接收完整数据的标志位
AJMP L01
LL2: SETB P1.0
SETB P1.1
CLR P1.2
SETB P1.3
SETB P1.4
SETB P1.5
SETB P1.6
SETB P1.7
SETB REC_STAT2 ;重新设置串口接收完整数据的标志位
AJMP L01
LL3: SETB P1.0
SETB P1.1
SETB P1.2
CLR P1.3
SETB P1.4
SETB P1.5
SETB P1.6
SETB P1.7
SETB REC_STAT2 ;重新设置串口接收完整数据的标志位
AJMP L01
LL4: SETB P1.0
SETB P1.1
SETB P1.2
SETB P1.3
CLR P1.4
SETB P1.5
SETB P1.6
SETB P1.7
SETB REC_STAT2 ;重新设置串口接收完整数据的标志位
AJMP L01
LL5: SETB P1.0
SETB P1.1
SETB P1.2
SETB P1.3
SETB P1.4
CLR P1.5
SETB P1.6
SETB P1.7
SETB REC_STAT2 ;重新设置串口接收完整数据的标志位
AJMP L01
LL6: SETB P1.0
SETB P1.1
SETB P1.2
SETB P1.3
SETB P1.4
SETB P1.5
CLR P1.6
SETB P1.7
SETB REC_STAT2 ;重新设置串口接收完整数据的标志位
AJMP L01
LL7: SETB P1.0
SETB P1.1
SETB P1.2
SETB P1.3
SETB P1.4
SETB P1.5
SETB P1.6
CLR P1.7
SETB REC_STAT2 ;重新设置串口接收完整数据的标志位
AJMP L01
;+============================================================================+
;| 定时器0中断服务子程序 |
;+============================================================================+
T0_ISR: CPL P1.0 ;对P1.0取反,设置定时器中断到的标志,在示波器上可以看到方波
MOV TH0,#0B1H ;重新设置定时器0定时参数
MOV TL0,#0E0H
SETB ET0 ;允许定时器0中断
SETB TR0 ;启动定时器0
RETI ;中断服务子程序返回,RETI是中断子程序返回的命令代码
;与子程序的RET不同
;+============================================================================+
;| 串口接收中断服务子程序 |
;+============================================================================+
INTERS: CLR ES ;禁止串行中断
JBC RI,RECINT ;判断接收标志为有接收数据吗?有则将接收标志置0,准备接收下一条数据,跳转到接收程序
AJMP LOUT
RECINT: MOV A,SBUF ;发送数据
CJNE A,#02H,LOUT ;是头吗?是的话做一个做一个标志
MOV R0,#030H
MOV @R0,A
CLR RI
INC R0
L00P1: JBC RI,L00P2
CPL WDI
AJMP L00P1
L00P2: CJNE R0,#032H,L00P3
MOV A,SBUF
CJNE A,#03H,LOUT ;是尾吗?是的话做一个接收到尾的标志
MOV @R0,A
SETB REC_STAT2
AJMP LOUT
L00P3: MOV A,SBUF
MOV @R0,A
CLR RI
INC R0
AJMP L00P1
LOUT: SETB ES ;允许串口中断
RETI
;+============================================================================+
;| 外部中断0服务子程序 |
;+============================================================================+
EI0_ISR:CLR EX0 ;禁止外部中断0
CPL P1.2
LCALL DLY4MS ;延时消抖动
SETB EX0 ;启动外部中断0
RETI
;+============================================================================+
;| 外部中断1服务子程序 |
;+============================================================================+
EI1_ISR:CLR EX1 ;禁止外部中断1
CPL P1.3
LCALL DLY4MS ;延时消抖动
SETB EX1 ;启动外部中断1
RETI
;+============================================================================+
;| 串口发送数据子程序 |
;+============================================================================+
SENT: MOV SBUF,A ;发送数据
W1: JBC TI,CON1 ;判断发送成功吗? (TI=1?),成功了则清楚除TI
SJMP W1 ;没有发送成功则继续判断
CON1: CPL P1.4 ;发送一个数据,就对P1.4取反操作
CPL WDI ;发送数据成功,对看门狗取反操作
RET ;子程序返回
;+============================================================================+
;| 延时子程序 |
;+============================================================================+
DLY4MS: MOV R6,#1FH
DLAY1: MOV R7,#0FFH
SDY: NOP
DJNZ R7,SDY
DJNZ R6,DLAY1
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -