DS18B20转换后不加延时也可以正常12位读数,不正常啊
本帖最后由 dz20062008 于 2012-7-18 17:03 编辑用DS18B20做了个数码管显示的温度计,12位精度,显示四位小数,有正负温度指示,也有DS18B20应答否报警。
DS18B20转换后不加延时也可以正常12位读数,不正常啊!!为什么啊!加延时反而转换的速度变慢了这货的转换速度到底多块啊~
还有就是显示最左边有最右边的残影,不知道怎么解决,是不是用累加器A加左移控制扫描这方法不行啊?怎么解决LED扫描显示与DS18B20的时序问题~
AT89S51 12M
DS_BUS BIT P3.6 ;温度传感器数据总线
BEEP_BUS BIT P3.5 ;蜂鸣器接口
DS_FLAG BIT 20H.0 ;温度传感器存在标志位
LED_DATA EQU P0
LED_DUAN EQU P1.0
LED_WEI EQU P1.1
TEMP_H EQU 33H ;存放温度整数位
TEMP_L EQU 32H ;存放温度小数位
TEMP_MSB EQU 31H ;存放MSB
TEMP_LSB EQU 30H ;存放LSB
TEMP_ZF EQU 17H ;温度正负标志位A为正B为负
ORG 0000H
SJMP START
ORG 0030H
START:MOV SP ,#07H
CLR DS_FLAG
MOV TEMP_H,#00H
MOV TEMP_L,#00H
MOV TEMP_MSB,#00H
MOV TEMP_LSB,#00H
MOV 10H,#00H ;计数缓存清零
MOV 11H,#00H
MOV 12H,#00H
MOV 13H,#00H
MOV 14H,#00H
MOV 15H,#00H
MOV 16H,#00H
MOV TEMP_ZF,#00H
MOV 18H,#0C0H ;显示缓存清零
MOV 19H,#0C0H
MOV 1AH,#0C0H
MOV 1BH,#0C0H
MOV 1CH,#0C0H
MOV 1DH,#0C0H
MOV 1EH,#0C0H
MOV 1FH,#0C0H
LCALL DS_RESET
JNB DS_FLAG,ERR
LCALL BEEP
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MAIN:LCALL DISPLAY
LCALL TEMP_COV1
LCALL TEMP_COV2
LCALL HEXtoBCD
LCALL XIAOSHUtoBCD
LCALL BCDtoLED
LCALL DISPLAY
LJMP MAIN
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BEEP:SETB BEEP_BUS
NOP
CLR BEEP_BUS
LCALL DELAY500MS
SETB BEEP_BUS
RET
ERR:LCALL BEEP
LCALL DELAY500MS
LCALL BEEP
LCALL DELAY500MS
LCALL BEEP
LCALL DELAY500MS
LJMP START
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TEMP_COV1:LCALL DS_RESET
JNB DS_FLAG,ERR
MOV A,#0CCH
LCALL WR_BYTE
MOV A,#44H
LCALL WR_BYTE
LCALL DS_RESET
JNB DS_FLAG,ERR
MOV A,#0CCH
LCALL WR_BYTE
MOV A,#0BEH
LCALL WR_BYTE
LCALL RD_BYTE
MOV TEMP_LSB,A
LCALL RD_BYTE
MOV TEMP_MSB,A
LCALL DS_RESET
RET
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TEMP_COV2:PUSH TEMP_LSB
PUSH TEMP_MSB
MOV TEMP_ZF,#0AH
MOVA,TEMP_MSB
ANLA,#11111000B
CJNE A,#00000000B,TEMP_COV3
POPTEMP_MSB
POPTEMP_LSB
MOVR0,#31H
MOVA ,TEMP_LSB
XCHD A ,@R0
SWAP A
MOV TEMP_H,A
MOV TEMP_L,TEMP_MSB
RET
TEMP_COV3:POPTEMP_MSB
POPTEMP_LSB
MOV TEMP_ZF,#0BH
MOV A,TEMP_MSB
CPL A
MOV TEMP_MSB,A
MOV A,TEMP_LSB
CPL A
ADD A,#01H
MOV TEMP_LSB,A
MOV A,TEMP_MSB
ADDC A,#00H
MOV TEMP_MSB,A
MOV R0,#31H
MOV A,TEMP_LSB
XCHD A,@R0
SWAP A
MOV TEMP_H,A
MOV TEMP_L,TEMP_MSB
RET
DELAY500MS:MOV R7,#17H
DL1:MOV R6,#98H
DL0:MOV R5,#46H
DJNZ R5,$
DJNZ R6,DL0
DJNZ R7,DL1
RET
HEXtoBCD:PUSH ACC
PUSH B
MOV A,TEMP_H
MOV B,#100D
DIV AB
MOV 16H,A
MOV A,#10D
XCH A,B
DIV AB
MOV 15H,A
MOV 14H,B
POP B
POP ACC
RET
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
XIAOSHUtoBCD:
MOV A,TEMP_L
CJNE A,#00H,L100
MOV 10H,#00H
MOV 11H,#00H
MOV 12H,#00H
MOV 13H,#00H
RET
L100:CJNE A,#01H,L101
MOV 10H,#05H
MOV 11H,#02H
MOV 12H,#06H
MOV 13H,#00H
RET
L101:CJNE A,#02H,L102
MOV 10H,#00H
MOV 11H,#05H
MOV 12H,#02H
MOV 13H,#01H
RET
L102:CJNE A,#03H,L103
MOV 10H,#05H
MOV 11H,#07H
MOV 12H,#08H
MOV 13H,#01H
RET
L103:CJNE A,#04H,L104
MOV 10H,#00H
MOV 11H,#00H
MOV 12H,#05H
MOV 13H,#02H
RET
L104:CJNE A,#05H,L105
MOV 10H,#05H
MOV 11H,#02H
MOV 12H,#01H
MOV 13H,#03H
RET
L105:CJNE A,#06H,L106
MOV 10H,#00H
MOV 11H,#05H
MOV 12H,#07H
MOV 13H,#03H
RET
L106:CJNE A,#07H,L107
MOV 10H,#05H
MOV 11H,#07H
MOV 12H,#03H
MOV 13H,#04H
RET
L107:CJNE A,#08H,L108
MOV 10H,#00H
MOV 11H,#00H
MOV 12H,#00H
MOV 13H,#05H
RET
L108:CJNE A,#09H,L109
MOV 10H,#05H
MOV 11H,#02H
MOV 12H,#06H
MOV 13H,#05H
RET
L109:CJNE A,#0AH,L110
MOV 10H,#00H
MOV 11H,#05H
MOV 12H,#02H
MOV 13H,#06H
RET
L110:CJNE A,#0BH,L111
MOV 10H,#05H
MOV 11H,#07H
MOV 12H,#08H
MOV 13H,#06H
RET
L111:CJNE A,#0CH,L112
MOV 10H,#00H
MOV 11H,#00H
MOV 12H,#05H
MOV 13H,#07H
RET
L112:CJNE A,#0DH,L113
MOV 10H,#05H
MOV 11H,#02H
MOV 12H,#01H
MOV 13H,#08H
RET
L113:CJNE A,#0EH,L114
MOV 10H,#00H
MOV 11H,#05H
MOV 12H,#07H
MOV 13H,#08H
RET
L114:CJNE A,#0FH,L115
MOV 10H,#05H
MOV 11H,#07H
MOV 12H,#03H
MOV 13H,#09H
RET
L115:MOV 10H,#00H
MOV 11H,#00H
MOV 12H,#00H
MOV 13H,#00H
RET
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BCDtoLED:PUSH ACC
PUSH DPL
PUSH DPH
MOV DPTR,#LED_TAB
MOV A,10H
MOVC A,@A+DPTR
MOV 18H,A
MOV DPTR,#LED_TAB
MOV A,11H
MOVC A,@A+DPTR
MOV 19H,A
MOV DPTR,#LED_TAB
MOV A,12H
MOVC A,@A+DPTR
MOV 1AH,A
MOV DPTR,#LED_TAB
MOV A,13H
MOVC A,@A+DPTR
MOV 1BH,A
MOV DPTR,#LED_TAB
MOV A,14H
MOVC A,@A+DPTR
ANL A,#7FH
MOV 1CH,A
MOV DPTR,#LED_TAB
MOV A,15H
MOVC A,@A+DPTR
MOV 1DH,A
MOV DPTR,#LED_TAB
MOV A,16H
MOVC A,@A+DPTR
MOV 1EH,A
MOV DPTR,#LED_TAB
MOV A,17H
MOVC A,@A+DPTR
MOV 1FH,A
POP DPH
POP DPL
POP ACC
RET
/*DS18B20初始化子程序,复位低电平维持500US,检测应答信号维持200US,等待总线释放维持300US*/
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DS_RESET:PUSH ACC
PUSH B
SETB DS_BUS
NOP
CLRDS_BUS
MOV R1,#47H
L1:MOV R0,#02H
DJNZ R0,$
DJNZ R1,L1
NOP
SETB DS_BUS
NOP
NOP
NOP
MOV R0,#48D
L2:JNB DS_BUS,L3
DJNZ R0,L2
SJMP L4
L3:SETB DS_FLAG
MOV R0,#150D
DJNZ R0,$
SETB DS_BUS
POP B
POP ACC
RET
L4:CLR DS_FLAG
MOV R0,#150D
DJNZ R0,$
SETB DS_BUS
POP B
POP ACC
RET
/*DS18B20写一字节子程序。写一BYTE入口为累加器A,写一BIT入口为C */
WR_BYTE:PUSH B
MOV B,#8D
L6:RRC A
ACALL WR_BIT
DJNZ B,L6
POP B
RET
WR_BIT:PUSH B
PUSH ACC
CLR DS_BUS
MOV B,#8D
DJNZ B,$
MOV DS_BUS,C
MOV B,#60D
DJNZ B,$
SETB DS_BUS
POP ACC
POP B
RET
/*DS18B20读一字节子程序,读一BYTE的出口为A累加器,读一BIT的出口参数为C寄存器 */
RD_BYTE:PUSH B
MOV B,#8D
L7:ACALL RD_BIT
RRC A
DJNZ B,L7
POP B
RET
RD_BIT:PUSH ACC
PUSH B
CLR CY
SETB DS_BUS
NOP
NOP
CLR DS_BUS
NOP
NOP
NOP
SETB DS_BUS
MOV B,#09D
DJNZ B,$
MOV C,DS_BUS
MOV B,#60D
DJNZ B,$
POP B
POP ACC
RET
;显示子程序
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DISPLAY:PUSH ACC
MOV R1,#18H ;逐位把显示缓存的LED代码显示出来
MOV R4,#00H ;清零刷新位数计数值
MOV A,#00000001B ;控制逐位显示刷新的刷新方向
LEDLOOP:MOV LED_DATA,@R1 ;LED段码送LED屏
SETB LED_DUAN ;送LED段码值到74HC373-A缓存
CLR LED_DUAN ;缓存LED段码
MOV LED_DATA,A ;LED位码送LED屏
SETB LED_WEI ;送LED位码值到74HC373-B缓存
CLR LED_WEI ;缓存LED位码
LCALL LED_DELAY ;位与位显示之间的显示延时
RL A ;更新LED位码值
INC R1 ;LED段码指针增一
INC R4 ;LED显示位数计数
CJNE R4,#8D,LEDLOOP ;显示完了吗?
POP ACC
RET ;显示完了,返回主程序
LED_DELAY:PUSH ACC
MOV R7,#04D ;装入显示延时循环的外圈值
D1:MOV R6,#100D ;装入显示延时循环的内圈值
D2:DJNZ R6,D2 ;内圈循环
DJNZ R7,D1 ;外圈循环
POP ACC
RET
LED_TAB: ;七段数码管十六进制显示码表
DB 0C0H,0F9H,0A4H,0B0H,99H ,92H
DB 82H ,0F8H,80H ,90H ,0FFH,0BFH
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
END
只有单个器件时,不用延时也可以 表是对会变不感冒 汇编吐血啊~什么逗得自己操心,还容易出错,但是有掌控感些~
我也要学 C 啊,以前学过点Turbe C 虽然不陌生也不会用
楼主不容易用全用汇编写。顶!! 没办法,C 还不会用~ zkf0100007 发表于 2012-7-18 17:36 static/image/common/back.gif
只有单个器件时,不用延时也可以
有么有具体的资料文献?谢谢! 本帖最后由 dz20062008 于 2013-8-23 23:26 编辑
今天看了坛友的一个问读转换状态字的问题,突然全身一抖。以前的疑问顿时无有了
因为单总线的操作方式是初始化,rom操作命令,ds功能命令。所以发送了转换指令后的下一个操作是读暂存器指令,但DS的指令的每一次操作都需要初始化一次,还有ROM操作指令。由于没有进行转换状态读取所以第一次读出来的是85度这个初始值,经过多次循环后当时间累计到内部所需要的转换时间后读出的才是实际的温度,后面的不出现85是因为DS没有断电所以里面储存的是上一次转换的结果,实际很多次读的是旧的值。所以实际的DS的速度并不是比手册上标的快。
消隐的问题也解决了,加了一次写关代码就好了。新的代码贴上来分享。
学汇编的坛友可以看看 以前用C写的sbit DQ=P3^2;
bit flag_init;//DS18B20是否存在标志
sbit Point=P0^0;//小数点
/****DS18B20初始化**************************************/
void reset()
{
flag_init=1;
DQ=1;
NOP3();
DQ=0;
delay_us(60);//480~960us
DQ=1;
delay_us(5);//60us
flag_init=DQ;
delay_us(25);//241us
}
/****写一个字节函数*************************************/
void Write_Byte(uchar dat)
{
uchar i;
DQ=1;
EA=0;
for(i=8;i>0;i--)
{
DQ=0;
DQ=(bit)(dat&0x01);
delay_us(5);//61us
DQ=1;
dat>>=1;
}
EA=1;
}
/*****读数据函数*****************************/
uchar Read_Byte()
{
uchar i,date;
DQ=1;
EA=0;//关中断
for(i=8;i>0;i--)
{
DQ=0;
date>>=1;
DQ=1;
NOP3();
if(DQ)
{
date|=0x80;
}
delay_us(5);//61us
}
EA=1;//开中断
return(date);
}
void get_tem()
{
uchar teml,temh;
reset();
Write_Byte(0xcc);//跳过读序列号的操作
Write_Byte(0x44);//启动温度转换
delay_ms(750);//750ms
reset();
Write_Byte(0xcc);
Write_Byte(0xbe);//读取温度转换结果
teml=Read_Byte();
temh=Read_Byte();
if((temh&0xf0)==0xf0)//如果是负温度
{
flag_low=1;
temper=(~((temh)*256+(teml))+1)*6.25;
}
else
temper=(temh*256+teml)*6.25;//放大100倍
}
页:
[1]