OpenVINOTM,给你看得见的未来!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » 51,18B20 谁有用51的18B20测温和控制汇编程序?最近要用

共2条 1/1 1 跳转至

,51,18B20 谁有用51的18B20测温和控制汇编程序?最近要用

院士
2006-12-22 22:43:00    评分
,51,18B20 谁有用51的18B20测温和控制汇编程序?最近要用



关键词: 18B20     有用     温和     控制     汇编程序     最近     要用    

院士
2006-12-22 22:43:00    评分
2楼
问 如题,不要C写的,要汇编的,主要是想学习一下.谢了. 1: c+asm#include <Reg51.h>
#include <intrins.h>

static unsigned char bdata StateREG;    //可位寻址的状态寄存器
sbit DS1820ON = StateREG^0;              //DS1820是否存在

#define TMPort            P1_7      //DS1820 DataPort

static unsigned char bdata TLV _at_ 0x0029;         //温度变量高低位
static unsigned char bdata THV _at_ 0x0028;
static signed char TMV;       //转换后的温度值

void InitDS1820(void);  //初始化DS1820
void ROMDS1820(void);    //跳过ROM匹配
void TMVDS1820(void);    //温度转换指令
void TMRDS1820(void);    //读出温度指令
void TMWDS1820(void);    //写入温度限制指令
void TMREDS1820(void);    //COPY RAM to E2PRAM
void TMERDS1820(void);    //COPY E2PRAM to RAM
void ReadDS1820(void);    //读出温度值
void WriteDS1820(void);    //写入温度限制值
void Delay_510(void);    //延时510微秒
void Delay_110(void);    //延时110微秒
void Delay_10ms(void);    //延时10ms


void InitDS1820(void)        //初始化DS1820
{
    TMPort = 1;        //拉高TMPort
    _nop_();      //保持一个周期
    TMPort = 0;        //拉低TMPort
    Delay_510();  //延时  DS1820复位时间要500us的低电平
      TMPort = 1;   //拉高TMPort
    _nop_();      //保持  
    _nop_();
    _nop_();
      Delay_110();  //延时110us 等待DS1820回应
      if (!TMPort)  //回应信号为低电平
        DS1820ON = 1;
     else
        DS1820ON = 0;
      Delay_110();  //延时
      Delay_110();
      TMPort = 1;   //拉高TMPort
}

void ROMDS1820(void)  //跳过ROM匹配
{
#pragma asm
          MOV A,#0CCH
          MOV R2,#8
          CLR C
WR1:    CLR P3_7
          MOV R3,#6
          DJNZ R3,$
          RRC A
          MOV P3_7,C
          MOV R3,#23
          DJNZ R3,$
          SETB P3_7
          NOP
         DJNZ R2,WR1
          SETB P3_7
#pragma endasm
}

void TMVDS1820(void)  //温度转换指令
{
#pragma asm
          MOV A,#44H
          MOV R2,#8
          CLR C
WR2:    CLR P3_7
          MOV R3,#6
          DJNZ R3,$
          RRC A
          MOV P3_7,C
          MOV R3,#23
          DJNZ R3,$
          SETB P3_7
          NOP
          DJNZ R2,WR2
          SETB P3_7
#pragma endasm
}

void TMRDS1820(void)  //读出温度指令
{
#pragma asm
          MOV A,#0BEH
          MOV R2,#8
          CLR C
WR3:    CLR P3_7
          MOV R3,#6
          DJNZ R3,$
          RRC A
          MOV P3_7,C
          MOV R3,#23
          DJNZ R3,$
          SETB P3_7
          NOP
          DJNZ R2,WR3
          SETB P3_7
#pragma endasm
}

void TMWDS1820(void)  //写入温度限制指令
{
#pragma asm
          MOV A,#04EH
         MOV R2,#8
          CLR C
WR13:  CLR P3_7
          MOV R3,#6
          DJNZ R3,$
          RRC A
          MOV P3_7,C
          MOV R3,#23
          DJNZ R3,$
          SETB P3_7
          NOP
          DJNZ R2,WR13
          SETB P3_7
#pragma endasm
}

void TMREDS1820(void)        //COPY RAM to E2PRAM
{
#pragma asm
          MOV A,#48H
          MOV R2,#8
          CLR C
WR33:    CLR P3_7
          MOV R3,#6
          DJNZ R3,$
          RRC A
          MOV P3_7,C
          MOV R3,#23
          DJNZ R3,$
          SETB P3_7
          NOP
          DJNZ R2,WR33
          SETB P3_7
#pragma endasm
}

void TMERDS1820(void)        //COPY E2PRAM to RAM
{
#pragma asm
        MOV A,#0B8H
        MOV R2,#8
          CLR C
WR43:    CLR P3_7
          MOV R3,#6
          DJNZ R3,$
          RRC A
          MOV P3_7,C
          MOV R3,#23
          DJNZ R3,$
          SETB P3_7
          NOP
          DJNZ R2,WR43
          SETB P3_7
#pragma endasm
}

void WriteDS1820(void)    //写入温度限制值
{
#pragma asm
        MOV A,26H                    //发出4EH写ROM指令后连发两个字节分别为上下限
          MOV R2,#8
          CLR C
WR23:    CLR P3_7
          MOV R3,#6
          DJNZ R3,$
          RRC A
          MOV P3_7,C
          MOV R3,#23
          DJNZ R3,$
          SETB P3_7
          NOP
          DJNZ R2,WR23
          SETB P3_7       
#pragma endasm
}

void ReadDS1820(void) //读出温度值
{
#pragma asm
          MOV R4,#3 ; 将温度高位和低位,高温限制位从DS18B20中读出
          MOV R1,#29H ; 低位存入29H(TEMPER_L),高位存入28H(TEMPER_H),高温限制位存入27H(TMRomV)
RE00:    MOV R2,#8
RE01:    CLR C
          SETB P3_7
          NOP
          NOP
          CLR P3_7
          NOP
          NOP
          NOP
          SETB P3_7
          MOV R3,#09
RE10:    DJNZ R3,RE10
          MOV C,P3_7
          MOV R3,#23
RE20:    DJNZ R3,RE20
          RRC A
          DJNZ R2,RE01
          MOV @R1,A
          DEC R1
          DJNZ R4,RE00
#pragma endasm
}

void Delay_510(void)    //延时510微秒
{
#pragma asm
        MOV R0,#7DH
        MOV R1,#02H
TSR1:    DJNZ R0,TSR1
        MOV R0,#7DH
        DJNZ R1,TSR1
#pragma endasm
}

void Delay_110(void)    //延时110微秒
{
#pragma asm
        MOV R0,#19H
        MOV R1,#02H
TSR2:    DJNZ R0,TSR2
        MOV R0,#19H
        DJNZ R1,TSR2
#pragma endasm
}

void Delay_10ms(void)    //延时10ms
{
#pragma asm
        MOV R0,#19H
        MOV R1,#0C8H
TSR3:    DJNZ R0,TSR3
        MOV R0,#19H
        DJNZ R1,TSR3
#pragma endasm
}

void Delay_4s(void)    //延时4s
{
#pragma asm
        MOV R2,#28H
TSR5:    MOV R0,#0FAH
        MOV R1,#0C8H
TSR4:    DJNZ R0,TSR4
        MOV R0,#0FAH
        DJNZ R1,TSR4
          DJNZ R2,TSR5
#pragma endasm
} 2: 供您参考以下程序转载自恒坚电器(http://shop.hejoin.com/)


; DS18B20 温度传感器读数接口
; 正确下载了程序以后,系统会利用数码管的后3位显示当前的温度值,最后一位是小数。
; 如果要移植这个程序中读取DS18B20的相关函数,您需要修改以下几个内容
; 根据您所选择晶振和我们板子上的晶振6M的关系,重新计算
; 初始化和读取,写入三个函数延时相关部分系数,用*标出

; 这个温度测试程序的温度精度是0.5C。


beep equ p3.7

segdata equ p0      ;数据 输出
sege    equ p2.7    ;显示 选中
segb    equ p2.6    ;位 选
segd    equ p2.5    ;段 选

tmp0   equ 40h
tmp1   equ 41h
tmp2   equ 42h
tmp3   equ 43h
tmp    equ 44h
buf    equ 45h

dstmp   bit p3.2     ;DS18B20在外部中断T0口,连器件的时候注意了
;我们活动式设计,您只要把DS18B20三只脚分开,准确识别三只脚的含义
;(这在我们光盘中提供了说明文件),然后分别对应,插入面板下主芯片下
;方的扩展座对应的引脚即可

        ORG 0000H
        AJMP MAIN
        
        ORG 0030H
MAIN:
        MOV SP,#30H
        clr beep
        
        LCALL GET_TEMP   ;首先获得温度值
        
        mov tmp,r7       ; R7是温度的低位
        
        clr c
        mov a,r6         ; R6是温度的高位
        rrc a
        mov r6,a
        
        mov a,r7
        rrc a
        mov r7,a         ;完成一次移位
        
        mov a,r6
        rrc a
        mov r6,a
        
        mov a,r7
        rrc a
        mov r7,a         ;完成2次移位
        
        mov a,r6
        rrc a
        mov r6,a
        
        mov a,r7
        rrc a
        mov r7,a         ;完成3次移位,这样以后便与计算        
        
        mov a,r7
        mov b,#2
        div ab
        
        mov r0,a   ;高位商
        mov r1,b   ;余数
        
        mov b,#10
        div ab
        mov tmp1,b   ;个位        
        
        mov b,#10
        div ab
        mov tmp2,b   ;十位
        mov tmp3,a   ;百位
        
        clr c  
              
        mov a,tmp
        rlc a
        mov tmp,a
        mov a,r1
        rlc a
        mov r1,a         ;小数操作
        
        mov a,tmp
        rlc a
        mov tmp,a
        mov a,r1
        rlc a
        mov r1,a         ;小数  
        
        mov a,tmp
        rlc a
        mov tmp,a
        mov a,r1
        rlc a
        mov r1,a         ;小数扩大16倍
        
        mov dptr,#ft
        movc a,@a+dptr
        mov tmp0,a
        
        mov a,tmp3
        jz noe        ;0消隐
        mov b,#3
        acall display ;显示百位  
        
noe:   mov a,tmp2
        mov b,#2
        acall display ;在第二位显示十位          
        
        mov a,tmp1
        add a,#16
        mov b,#1      ;第1位显示个位,带小数点
        acall display                            
        
        mov a,tmp0
        mov b,#0      ;显示小数
        acall display  
                
        SJMP main





GET_TEMP:
        CLR PSW.4
        SETB PSW.3      ;设置工作寄存器当前所在的区域
        CLR EA          ;使用ds1820一定要禁止任何中断产生
        LCALL INT       ;调用初使化子程序
        MOV A,#0CCH
        LCALL WRITE     ;送入跳过ROM命令
        MOV A, #44H
        LCALL WRITE     ;送入温度转换命令
        
        LCALL INT       ;温度转换完全,再次初使化ds1820
        MOV A,#0CCH
        LCALL WRITE     ;送入跳过ROM命令
        MOV A,#0BEH
        LCALL WRITE     ;送入读温度暂存器命令
        LCALL READ
        MOV R7,A        ;读出温度值低字节存入R7
        LCALL READ
        MOV R6,A        ;读出谩度值高字节存入R6
        SETB EA
        RET

INT:                    ;初始化ds1820子程序
        CLR EA
     L0:CLR dstmp        ;ds1820总线为低复位电平
        MOV R2,#100      ;****** <== 移植需要修改参数,下同
     L1:CLR dstmp
        DJNZ R2,L1      ;总线复位电平保持400us
        SETB dstmp       ;释放ds1820总线
        MOV R2,#15      ;*********************
     L4:DJNZ R2,L4      ;释放ds1820总线保持60us
        CLR C           ;清存在信号(存在C=0,不存在C=1)
        ORL C,dstmp
        JC L0           ;存在吗?不存在则重新来
        MOV R6,#40      ;*********************
     L5:ORL C,dstmp
        JC L3
        DJNZ R6,L5
        SJMP L0
     L3:MOV R2,#120     ;**********************
     L2:DJNZ R2,L2      
        RET

WRITE:                  ;向ds1820写操作命令子程序
        CLR EA
        MOV R3,#8       ;写入ds1820的bit数,一个字节8个bit
    WR1:SETB dstmp
        MOV R4,#4       ;**********************
        RRC A           ;把一个字节data(A)分成8个bit环移给 C
        CLR dstmp        ;开始写入ds1820总线要处于复位(低)状态
    WR2:DJNZ R4,WR2     ;ds1820总线复位保持16us
        MOV dstmp,C      ;写入一个bit
        MOV R4,#10       ;**********************
    WR3:DJNZ R4,WR3     ;等待40us
        DJNZ R3,WR1     ;写入下一个bit
        SETB dstmp       ;重新释放ds1820总线
        RET

READ:
        CLR EA
        MOV R6,#8       ;连续读8个bit
    RE1:CLR dstmp        ;读前总线保持为低
        MOV R4,#2        ;**********************
        NOP
        SETB dstmp       ;开始读,总线释放
    RE2:DJNZ R4,RE2     ;持续8us
        MOV C,dstmp      ;从ds1820总线读得一个bit
        RRC A           ;把读得的位值环移给 A
        MOV R5,#15
    RE3:DJNZ R5,RE3     ;持续60us
        DJNZ R6,RE1     ;读下一个bit
        SETB dstmp       ;重新释放ds1820总线
        RET


;================定义一组小数表示码表
ft:    db 0,0,1,1,2,3,4,4,5,6,6,7,7,8,9,9
;===================================================================================

;***  显示参数说明  *********************
;     A里面存放需要显示的数字
;     B里面存放需要显示的数码管位数
;     如果B大于8,那么消隐所有数码显示内容
;     另外使用了一个临时存储单元,segtmp
;     
display:
     clr sege

     mov dptr,#tab_nu
     movc a,@a+dptr
     mov segdata,a
     setb segd
     nop
     clr segd
         
     mov a,#1
lp: rl a
     djnz  b,lp    
     mov segdata,a
     setb segb
     nop
     clr segb
     acall delayds
     
     mov segdata,#0
     setb segb
     nop
     clr segb     
     
     
ret
;************* 和显示配套的延时子程序  *********************************************
;*********** 延时 5ms ****************
delayds:
      push psw
      clr  psw.3
      setb  psw.4
      mov r0,#250
  d5: djnz r0,d5
      pop psw
    ret
;************************************************************************************
;这是数字显示表格,其中 带小数点的数字比不带小数点的数字大16
; 比如 0 的显示代码为 0;那么 0.的显示代码为 16;如此类推
tab_nu:
             db 0c0h, 0f9h, 0a4h, 0b0h, 99h ,  92h ,  82h, 0f8h ; 数字0-7 不带小数点代码
             db 80h ,  90h,  88h ,  83h ,  0c6h, 0a1h, 86h, 8eh  ; 数字8-f   不带小数点代码
             db 40h ,  79h,  24h ,  30h ,  19h ,  12h ,  02h, 78h  ; 数字0-7  带小数点代码
             db 00h ,  10h,  08h ,  03h ,  46h ,  21h ,  06h, 0eh  ; 数字8-f   带小数点代码
;=======================================================================================================
        END
3: 谢了.谢谢楼上两位了.不知还有没有人有程序?最好带电路图的.谢了. 4: 你说的是C51吗?请问C51是什么东西呀?我这里有uvision2 和C51。请问怎么使用啊?

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]