为什么我写的串口中断接受程序,烧到51里就一直执行中断服务程序,而我根本没有产生中断,然后我把串口线拔下问题还是如此,代码如下:
;单片机内存分配申明!
TEMPER_L EQU 29H;用于保存读出温度的低8位
TEMPER_H EQU 28H;用于保存读出温度的高8位
BYT_DLY EQU 39H
DQ EQU p2.7
FLAG1 EQU 38H;是否检测到DS18B20标志位
COUNT EQU 3BH;是否检测到DS18B20标志位
ORG 0000H
AJMP START
ORG 0023H
AJMP RECE
ORG 0030H
START:
MOV SP,#60H
MOV IE, #00H ;禁止cpu中断,禁止串口中断
MOV SCON,#50H ;设置成串口1方式,SM2=1,REN=1
MOV TMOD,#20H ;波特率发生器T1工作在模式2上
MOV PCON,#80H
MOV TH1,#0faH ;预置初值(按照波特率9600BPS预置初值)
SETB TR1 ;启动定时器T1
MOV IE, #90H;允许cpu中断,允许串口中断
CLR RI
MAIN:
LCALL GET_TEMPER;调用读温度子程序
MOV SBUF,#7EH
JNB TI,$
CLR TI
MOV SBUF,#7EH
JNB TI,$
CLR TI
MOV SBUF,28H
JNB TI,$
CLR TI
MOV SBUF,29H
JNB TI,$
CLR TI
AJMP MAIN
;这是DS18B20复位初始化子程序
INIT_1820:
SETB DQ
NOP
CLR DQ
MOV BYT_DLY,#220
LCALL DELAY1;480us
SETB DQ ;然后拉高数据线
MOV BYT_DLY,#15
LCALL DELAY1;36us
MOV R0,#10
TSR2: JNB DQ,TSR3 ;等待DS18B20回应
DJNZ R0,TSR2
LJMP TSR4 ;延时
TSR3: SETB FLAG1 ;置标志位,表示DS1820存在
;CLR P1.7;检查到DS18B20就点亮P1.7LED
LJMP TSR5
TSR4: CLR FLAG1 ;清标志位,表示DS1820不存在
;CLR P1.2
LJMP TSR7
TSR5: MOV BYT_DLY,#192
LCALL DELAY1;420us
TSR7: SETB DQ
RET
; 读出转换后的温度值
GET_TEMPER:
SETB DQ
LCALL INIT_1820;先复位DS18B20
JB FLAG1,TSS2
;CLR P1.2
RET ;判断DS1820是否存在?若DS18B20不存在则返回
TSS2: ;CLR P1.3;DS18B20已经被检测到!!!!!!!!!!!!!!!!!
MOV A,#0CCH ;跳过ROM匹配
LCALL WRITE_1820
MOV A,#44H ;发出温度转换命令
LCALL WRITE_1820
;等待AD转换结束,12位的话750微秒
MOV BYT_DLY,#130
LCALL DELAY3;118ms
LCALL INIT_1820;准备读温度前先复位
MOV A,#0CCH ;跳过ROM匹配
LCALL WRITE_1820
MOV A,#0BEH ;发出读温度命令
LCALL WRITE_1820
LCALL READ_18200;将读出的温度数据保存到35H/36H
RET
;写DS18B20的子程序(有具体的时序要求)
WRITE_1820:
MOV R2,#8;一共8位数据
CLR C
WR1: CLR DQ
MOV BYT_DLY,#5
LCALL DELAY1;15us
RRC A
MOV DQ,C
MOV BYT_DLY,#19
LCALL DELAY1;45us
SETB DQ
NOP
DJNZ R2,WR1
SETB DQ
RET
;读DS18B20的程序,从DS18B20中读出两个字节的温度数据
READ_18200:
MOV R4,#2 ;将温度高位和低位从DS18B20中读出
MOV R1,#29H ;低位存入29H(TEMPER_L),
;高位存入28H(TEMPER_H)
RE00: MOV R2,#8;数据一共有8位
RE01: CLR C
CLR DQ
NOP
NOP
NOP
SETB DQ
MOV BYT_DLY,#5
LCALL DELAY1;15us
MOV C,DQ
MOV BYT_DLY,#19
LCALL DELAY1;45us
RRC A
DJNZ R2,RE01
MOV @R1,A
DEC R1
SETB DQ
NOP
NOP
NOP
DJNZ R4,RE00
RET
DELAY1: DJNZ BYT_DLY,DELAY1
RET
DELAY2: PUSH BYT_DLY
DELM1: DJNZ BYT_DLY,DELM1
POP BYT_DLY
DJNZ BYT_DLY,DELAY2
RET
DELAY3: PUSH BYT_DLY
DEL31: PUSH BYT_DLY
DEL32: DJNZ BYT_DLY,DEL32
POP BYT_DLY
DJNZ BYT_DLY,DEL31
POP BYT_DLY
DJNZ BYT_DLY,DELAY3
RET
DELAY: MOV R5,#20
D1: MOV R6,#20
D2: MOV R7,#248
DJNZ R7,$
DJNZ R6,D2
DJNZ R5,D1
RET
RECE:
MOV IE, #00h ;禁止cpu中断,禁止串口中断
CLR RI
MOV a, SBUF
MOV COUNT,100
ALARM:
CLR P2.0
LCALL DELAY
SETB P2.0
LCALL DELAY
DJNZ COUNT ,ALARM
MOV IE, #90h;允许cpu中断,允许串口中断
RETI
END
可能是你发的时候跳进中断里了
在你的串口服务里加入,识别确认是收的中断
JNB RI,XX
;你的接收处理
XX:RETI
我按你的做法做了
不过又有新问题了,现在程序一烧到里面不会产生中断,但我在PC上向51发一个数据产生中断后,又会死在中断服务程序里,出不来!
先这样:你把发送相关的全都去了,看看还有没有中断触发,如果还有那就看一下硬件的连接了...
串口相关部分,独立的调一下串口
可我用c写的串口收发程序是正常的,所以硬件应该没有问题!
串行中断的执行时间太长了,一般中断程序的设计原则是快进快出,复杂事务在中断外出理。
你在中断中总共循环了100*(2*(20*20*248)))次,假定每次循环时间是3uS,总共执行时间需要59.52s,问题可能就是出在这儿。