加入收藏 | 设为首页 | 会员中心 | 我要投稿 | RSSRSS-巴斯仪表网
您当前的位置:首页 > 电子发烧 > 单片机学习

PIC16F877A控制DS18B20汇编程序

时间:2013-09-08  来源:123485.com  作者:9stone

;*******

;功能实现:通过DS18B20来读取温度,显示在2位LED上,精确到1度
;硬件连接:(1)RC0-RC7接共阳数码管的段码A-H
;             RA0-RA3接共阳数码管的位码DIG0-DIG3
;*****

;*************

;定义单片机型号为PIC16F877A
;程序包含文件:P16F877A.INC
;定义配置字
;***********
LIST   P=16F877A                  ;定义本程序所使用的芯片为PIC16F877A
#INCLUDE "P16F877A.INC"            ;定义本程序包含该文件

__CONFIG  3F72H                   ;晶振配置HS,看门狗禁止,上电延时使能,掉电复位使能
                                  ;低电压编程禁止,代码不保护

#DEFINE   DQ         PORTB,2
#DEFINE   DIR        TRISB,2
        
CBLOCK    20H
      Y1
      Y2
      COUNT1
      COUNT2
      COMD
      DATE
      BIN_L                       ;要进行转换的字节
      GE                          ;转换后的个位
      SHI                         ;转换后的十位
      DATE_L
      DATE_H
      ENDC

;**********

;复位矢量定义(对于16F877A)
;**********
          ORG     0000H           ;复位矢量地址
          GOTO   MAIN             ;程序跳转到MAIN主程序
;-----------

;*******

;主程序区
;************
         ORG        0005H
MAIN 
         NOP
         CALL      INTIAL      
START    BTFSS     DQ             ;数据线空闲状态为高电平
         GOTO      $-1
         CALL      RESET          ;复位DS18B20
         MOVLW     0CCH           ;跳过读ROM命令
         CALL      WR18B20      
         MOVLW     44H            ;温度转换
         CALL      WR18B20
         CALL      DELAY_750US     ;延时750us
         CALL      RESET          ;复位DS18B20
         MOVLW     0CCH           ;跳过读ROM命令
         CALL      WR18B20   
         MOVLW     0BEH           ;读内部RAM中的9字节内容
         CALL      WR18B20
         NOP
         CALL      RE18B20        ;读数据  
         MOVF      DATE,W       
         MOVWF     DATE_L         ;读低8位
         CALL      RE18B20        ;读数据  
         MOVF      DATE,W       
         MOVWF     DATE_H         ;读高8位
         MOVF      DATE_L,W
;-------显示处理-----------------

         RRF       DATE_H,F
         RRF       DATE_L,F
         RRF       DATE_H,F
         RRF       DATE_L,F
         RRF       DATE_H,F
         RRF       DATE_L,F
         RRF       DATE_H,F
         RRF       DATE_L,F
         MOVF      DATE_L,W
         MOVWF     BIN_L          ;把高8位的低4位和低8位的高4位组合起来
         CALL      DISPLAY        ;调用数码管显示程序
         GOTO      START
       
;===========

;*******************

;初始化和消影
;*****************
INTIAL   BSF       STATUS,RP0     ;定义当前体为体1,对方向寄存器进行修改
         MOVLW     07H
         MOVWF     ADCON1         ;关闭A口的模拟通道  
         MOVLW     00H
         MOVWF     TRISC          ;段码显示口为输出口
         MOVLW     0F0H
         ANDWF     TRISA,1        ;使位码(RA0-RA3)为输出口    
         BSF       DIR             ;使数据线为输入
         BCF       STATUS,RP0     ;使当前体为体0
         MOVLW     0FFH           ;关闭段码
         MOVWF     PORTC
         MOVLW     0FFH           ;关闭位码
         MOVWF     PORTA
         BTFSS     DQ             ;数据线空闲状态为高电平
         GOTO      $-1
         CALL      RESET          ;复位DS18B20
         MOVLW     0CCH           ;跳过读ROM命令
         CALL      WR18B20      
         MOVLW     44H            ;温度转换
         CALL      WR18B20
         CALL      DELAY_750US     ;延时750us
         CALL      RESET          ;复位DS18B20
         MOVLW     0CCH           ;跳过读ROM命令
         CALL      WR18B20   
         MOVLW     0BEH           ;读内部RAM中的9字节内容
         CALL      WR18B20
         NOP
         NOP
         CALL      RE18B20        ;读数据  
         CALL      RE18B20        ;读数据  
         CALL      DELAY_MAX      ;延时600ms
         CALL      DELAY_MAX
         CALL      DELAY_MAX
         RETLW     00H
;========

;************

;显示所测得的温度子程序
;**************

DISPLAY
         CALL      _BCD
         MOVF      SHI,W
         ANDLW     0FH
         CALL      TABLE          ;调用查表指令
         MOVWF     PORTC          ;显示十位段码
         BCF       PORTA,0         ;选通十位显示位码
         CALL      DELAY
         BSF       PORTA,0        ;关闭十位显示位码
         MOVF      GE,W
         ANDLW     0FH
         CALL      TABLE          ;调用查表指令
         MOVWF     PORTC          ;显示个位段码
         BCF       PORTA,1         ;选通个位显示位码
         CALL      DELAY
         BSF       PORTA,1        ;关闭个位显示位码
         RETLW     00H
;=====================
      
;*******************
;二进制转BCD码
;*******************

_BCD     CLRF      SHI            ;保存地址清零
         CLRF      GE           
         MOVF      BIN_L,F        ;组合码自己给自己赋值,测试是否为0
         SKPNZ                    ;不为0则跳到下一步
         RETLW     00H
SHI_     MOVLW     D'10'
         SUBWF     BIN_L,W        ;BIN_L减10,结果存到W寄存器
         BTFSS     STATUS,C       ;执行减法后,如果无借位
         GOTO      GE_
         MOVWF     BIN_L
         INCF      SHI
         GOTO      SHI_
GE_      MOVF      BIN_L,W
         MOVWF     GE
         RETLW     00H            
;==========

;**************
;延时200ms
;***************
DELAY_MAX
         MOVLW    0FFH
         MOVWF    Y1
         MOVLW    0FFH
         MOVWF    Y2
         DECFSZ   Y2
         GOTO     $-1
         DECFSZ   Y1
         GOTO     $-5
         RETLW    00H
;================

;****************

;延时6ms
;*****************
DELAY
         MOVLW    03FH
         MOVWF    Y1
         MOVLW    020H
         MOVWF    Y2
         DECFSZ   Y2
         GOTO     $-1
         DECFSZ   Y1
         GOTO     $-5
         RETLW    00H
;*************************
;延时750us子程序
;***********************
DELAY_750US
         MOVLW    09H
         MOVWF    Y1
         MOVLW    01AH
         MOVWF    Y2
         DECFSZ   Y2
         GOTO     $-1
         DECFSZ   Y1
         GOTO     $-5
         RETLW    00H
;======

;***************
;查表子程序,用于显示段码数字
;数码管为共阳数码管
;***************
TABLE
      ADDWF    PCL,F
      RETLW    0C0H               ;"0"
      RETLW    0F9H               ;"1"
      RETLW    0A4H               ;"2"
      RETLW    0B0H               ;"3"
      RETLW    99H                ;"4"
      RETLW    92H                ;"5"
      RETLW    82H                ;"6"
      RETLW    0F8H               ;"7"
      RETLW    80H                ;"8"
      RETLW    90H                ;"9"
;===============

;******************

;DS18B20复位和应答子程序
;*****************

RESET    BSF       STATUS,RP0     ;使当前体为体1
         BCF       DIR            ;使数据位为输出
         BCF       STATUS,RP0     ;使当前体为体0
         BSF       DQ             ;拉高数据位
         NOP                      ;空循环
         BCF       DQ             ;拉低数据位
         MOVLW     D'200'         ;延时600us
         MOVWF     Y1            
         DECFSZ    Y1
         GOTO      $-1
         BSF       STATUS,RP0     ;使当前体为体1
         BSF       DIR            ;使数据位为输入
         BCF       STATUS,RP0     ;使当前体为体0
         MOVLW     D'30'          ;延时90us
         MOVWF     Y1
         DECFSZ    Y1
         GOTO      $-1
         BTFSC     DQ             ;主机接收到低电平应答脉冲,跳转到下一句
         GOTO      RESET     
         MOVLW     D'80'          ;延时240us
         MOVWF     Y1
         DECFSZ    Y1
         GOTO      $-1
         BTFSS     DQ             ;主机接收到高电平应答脉冲,跳转到下一句
         GOTO      RESET
         RETLW     00H            ;返回00H,复位应答结束
;========================

;***********************
;写DS18B20子程序
;***********************
WR18B20
         MOVWF     COMD           ;把要写的数据写到COMD内
         MOVLW     D'8'
         MOVWF     COUNT2         ;大循环8次
WR0      BSF       STATUS,RP0     ;使当前体为体1
         BCF       DIR            ;使数据位为输出
         BCF       STATUS,RP0     ;使当前体为体0
         BCF       DQ             ;拉低数据线
         NOP
         NOP
         MOVLW     D'2'
         MOVWF     COUNT1         ;延时9us
WR1      DECFSZ    COUNT1,1
         GOTO      WR1  
         BTFSC     COMD,0         ;COMD最低位为0则跳转到下一句
         BSF       DQ             ;拉高数据线
         BTFSC     COMD,0         ;COMD最低位为0则跳转到下一句
         NOP
         BCF       STATUS,C         ;进位位置0
         RRF       COMD,1          ;带进位位,COMD向右移一位
         MOVLW     D'20'           ;延时60us
         MOVWF     COUNT1
WR2      DECFSZ    COUNT1,1
         GOTO      WR2
         BSF       DQ             ;拉高数据线,空闲状态
         BSF       STATUS,RP0     ;使当前体为体1
         BSF       DIR            ;使数据位为输入
         BCF       STATUS,RP0     ;使当前体为体0  
         DECFSZ    COUNT2,1       ;8次循环到了则跳出
         GOTO      WR0   
         RETLW     00H
;=============
       
;*****************
;读18B20子程序
;****************    
RE18B20
         MOVLW     8
         MOVWF     COUNT2
RE0      BSF       STATUS,RP0     ;使当前体为体1
         BCF       DIR            ;使数据位为输出
         BCF       STATUS,RP0     ;使当前体为体0
         BCF       DQ
         MOVLW     2
         MOVWF     COUNT1
RE1      DECFSZ    COUNT1,1
         GOTO      RE1
         BSF       STATUS,RP0     ;使当前体为体1
         BSF       DIR            ;使数据位为输入
         BCF       STATUS,RP0     ;使当前体为体0
         NOP
         BTFSS     DQ             ;如果数据线为高电平,则C=1
         BCF       STATUS,C
         BTFSC     DQ             ;如果数据线为低电平,则C=0
         BSF       STATUS,C
         RRF       DATE,1          ;数据依次存在DATE上
         MOVLW     D'20'           ;延时60us
         MOVWF     COUNT1
RE2      DECFSZ    COUNT1,1
         GOTO      RE2
         DECFSZ    COUNT2,1
         GOTO      RE0
         BSF       DQ
         RETLW     00H
;===================  

;================
         END                      ;程序结束


 

分享到:
来顶一下
返回首页
返回首页
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表
栏目导航->单片机学习
  • 电子应用基础
  • 电源技术
  • 无线传输技术
  • 信号处理
  • PCB设计
  • EDA技术
  • 单片机学习
  • 电子工具设备
  • 技术文章
  • 精彩拆解欣赏
  • 推荐资讯
    使用普通运放的仪表放大器
    使用普通运放的仪表放
    3V与5V混合系统中逻辑器接口问题
    3V与5V混合系统中逻辑
    数字PID控制及其改进算法的应用
    数字PID控制及其改进
    恶劣环境下的高性价比AD信号处理数据采集系统
    恶劣环境下的高性价比
    栏目更新
    栏目热门