gzyueqian
13352868059
首页 > 新闻中心 > > 正文

PIC16F877A控制DS18B20汇编程序

更新时间: 2007-12-10 09:00:19来源: 粤嵌教育浏览量:1376

  ;************************************************************************
  ;功能实现:通过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 ;程序结束

免费预约试听课