XUE BIT 22H
EP EQU 40H
BUF EQU 43H
MP EQU 50H
ORG 0000H ;主程序跳转
SJMP START
ORG 0003H ;外中断0服务程序
LJMP INT0S
ORG 0013H ;外中断1服务程序
LJMP SAODI
ORG 0023H
LJMP JIESHOU
ORG 0030H
START: MOV IE,#9DH ;外部中断,低电平触发
MOV IP,#05H ;设定优先等级
MOV TMOD,#20H ;设定定时器1,方式2
MOV PCON,#00H
MOV SCON,#50H ;设定串行口方式1,REN=1
MOV R0,#40H ;数据的首地址
MOV BUF,#06H ;循环次数为6-2=4次
MOV R1,BUF
ZHIXIANG: CLR C
MOV EP,#01H
MOV EP+1,#01H ;直线运行2325个脉冲
DJNZ R1,NEXT
OK: MOV P2,#0FFH ;停止运动
SJMP $ ;等待
NEXT: CLR P2.0
CLR P2.2
ACALL DELAY
SETB P2.0
SETB P2.2
ACALL DELAY
MOV A,EP+1
SUBB A,#1
MOV EP+1,A
MOV A,EP
SUBB A,#0
MOV EP,A
CJNE A,#0, NEXT
MOV A,EP+1
CJNE A,#0, NEXT
JBC XUE,TURN2
;*************************************
;右转P2.2端口保持高电位,P2.0输出方波
;*************************************
TRUN1: ACALL YOU
SETB XUE
SJMP ZHIXIANG ;接着返回直走
YOU: CLR C
MOV MP,#01H
MOV MP+1,#1DH ;弯运行1314个脉冲
NEXT1: CLR P2.0
SETB P2.2
ACALL DELAY
SETB P2.0
SETB P2.2
ACALL DELAY
MOV A,MP+1
SUBB A,#1
MOV MP+1,A
MOV A,MP
SUBB A,#0
MOV MP,A
CJNE A,#0, NEXT1
MOV A,MP+1
CJNE A,#0, NEXT1
RET
;********************************************
;右转P2.0端口保持高电位,P2.2输出方波
;********************************************
TURN2: ACALL ZUO
CLR XUE
LJMP ZHIXIANG ;接着返回直走
ZUO: CLR C
MOV MP,#01H
MOV MP+1,#1DH ;转弯运行1314个脉冲
NEXT2: SETB P2.0
CLR P2.2
ACALL DELAY
SETB P2.0
SETB P2.2
ACALL DELAY
MOV A,MP+1
SUBB A,#1
MOV MP+1,A
MOV A,MP
SUBB A,#0
MOV MP,A
CJNE A,#0, NEXT2
MOV A,MP+1
CJNE A,#0, NEXT2
RET
;*******************************************************************************
;延时10ms子程序
;*******************************************************************************
DELAY: MOV R3, #14
XUEA: MOV R4, #100
XUEA1: NOP
NOP
DJNZ R4, XUEA1
DJNZ R3, XUEA
RET
;**************************************************************************
;外部中断0服务子程序
;用于处理障碍
;**************************************************************************
INT0S: PUSH ACC
PUSH PSW
SETB P2.0
SETB P2.2
HERE: JNB P3.2,HERE ;等待障碍物离开
POP PSW
POP ACC
RETI
;***************************************************************************
;外部中断1服务子程序
;扫垃圾并清理完自动机器运行
;***************************************************************************
SAODI: PUSH ACC
PUSH PSW
QUAN: MOV R4,#05H ;设定圈数5圈
SETB P2.0
SETB P2.2
CLR P2.4 ;直流电机开始运行即扫垃圾
LOOP1: JB P1.0,LOOP1
JNB P1.0,$
DJNZ R4,LOOP1 ;转完5圈后扫地结束
SETB P2.4 ;直流电机停止运行
POP PSW
POP ACC
RETI
JIESHOU: PUSH ACC
PUSH PSW
MOV TH1,#0FDH ;9600波特率,计数初值
MOV TL1,#0FDH
SETB TR1 ;启动定时
XUE1: JNB RI,$
CLR RI
MOV A,SBUF ;接收第一个数据
MOVX @R0,A
INC R0
XUE2: JNB RI,$
CLR RI
MOV A,SBUF ;接收第二个数据
MOVX @R0,A
INC R0
XUE3: JNB RI,$
CLR RI
MOV A,SBUF ;接收第三个数据
MOVX @R0,A
POP PSW
POP ACC
RETI
END
家用防盗报警器源程序
家用防盗报警器源程序清单 ;采用89C2051无P3.6引脚!正常时P3口输入低电平,报警时P3.0~P3.5输入高电平,从P3.7引脚输出高低电平间隔1秒的报警脉冲信号。
ORG 0000H ;开机复位PC指向0000H地址
AJMP MAIN ;转入主程序
ORG 001BH ;定时器T1入口
LJMP WT0 ;转入定时器T1中断程序
ORG 30H ;这条语句有何作用?指定下一条程序的地址为30H
MAIN: MOV SP,#50H ;堆栈从50H开始
MOV 20H,#0 ;20H清零
MOV 24H,#0 ;24H清零
MOV P3,#0 ;P3口输出低电平
MOV P1,#0 ;P1口输出低电平(红外线发射二极管工作)
MOV TH0,#6 ;此处不懂,预置数为多少?如何计算?答×初值为6,那么256-6=250,当T0计数250个脉冲后发生中断,如果时钟频率为6M那么机器周期为2us,T0的定时时间为500us。
MOV TL0,#6 ;不懂!!
MOV TMOD,#02H ;TO工作方式为2
SETB EA ;打开总中断
SETB ET0 ;开T0中断
SETB TR0 ;T0开始计数
M: MOV P1,#00H ;P1口输出低电平(以上程序所做的是开机初始化,程序进行基本设置)
MOV A,P3 ;将P3口的值赋予A
ANL A,#7FH ;将A的值和01111111作与运算,并且结果保留在A中
CJNE A,#7FH,W37 ;如果A不等于01111111那么跳转到W37(也就是说当P3口输入高电平时报警
AJMP M ;返回到M处(处于监控等待状态)
WT0: PUSH ACC ;将累加器A中的数值压入堆栈
PUSH PSW ;将程序状态字PSW压入堆栈(保护现场)
INC 22H ;将22H中的值加1
MOV A,22H ;将22H中的值赋予A
CJNE A,#200,TORETI ;如果A中的值不等于200那么跳转到TORETI(退出中断)(也就是说中断200次后往下执行)
MOV 22H,#0 ;将22H中的数值清零
INC 23H ;将23H中的值加1
MOV A,23H ;将23H中的值赋予A
CJNE A,#10,TORETI ;1s 如果A中的值不等于10那么跳转到TORETI(退出中断)(在中断10次,那么只有中断200x10=2000次以后程序才能往下执行)
MOV 23H,#0 ;将23H中的数值清零
JNB 00H,WBJ;00H应该是位地址20H.0 如果20H.0的值为0那么跳转到WBJ
TORETI: POP PSW ;恢复PSW中的数值
POP ACC ;恢复A中的数值(恢复现场)
RETI;退出中断
WBJ: CPL P3.7 ;对引脚P3.7状态取反
AJMP TORETI ;跳转到TORETI (退出中断)
W37: INC 24H ;将24H中的值加1
MOV A,24H ;将24H中的值赋予A
CJNE A,#10,M ;如果A中的值不等于10那么跳转到M(增加检测时间,如果重复10次检测到P3口输入高电平时程序往下执行)
SETB 00H ;对位地址20H.0置1
AJMP M ;跳转到M
END ;结束
网上的高手解答
一.功能描述 简易光电报警器,六个光电对管构成六路检测,如发生遮挡事件则输出脉冲报警.
1.硬件 电路比较简单也很典型,其中CD4069可换成40106施密特六路非门,效果会更好;P3.7也可利用起来;P1口要串入限流电阻或接三极管放大.
2.软件 由主程序和中断服务程序组成,主程序负责检测外部触发,由中断程序输出报警脉冲.
二.问题回答
1. "ORG 30H" ORG,END等都为伪指令,在此指出MAIN段程序的程存地址从30H开始,在本程序中也可省略,这只是一般写程序的风格习惯而已.因为串口中断服务入口地址是23H,从30H开始主程序就避免了对五个中断服务程序的干扰,并为以后其他中断的使用留下程存空间.在此程序中由于只用了T0中断,所以紧接"LJMP WT0" 后面写MAIN段也是可以的.
2. "MOV TH0, #6" 设TH0初值为6,计算很简单,方式2时为8位计数器,256-6=250,故6M时500微秒溢出.你的说明是正确的.
3. "MOV TL0, #6" 因为方式2为8位自动装填,每个机器周期只是对TL0加一,加满后再将TH0的值赋给TL0重新计数,TH0值一直保持不变.设TL0初值为6意味着只要一打开TR0,则从6开始计数.实际上此句也可省略,因为不管TL0初值为何,最长256周期后TH0值6必然要赋给TL0.
三.错误及更正
1. "JNB 00H, WBJ"应为"JB 00H,WBJ"!! 程序开始时,"MOV 20H, #0