通信设计应用
OW_HIZ:MACRO
;Force the DQ line into a high impedance state.
BSF STATUS,RP0 ; Select Bank 1 of data memory
BSF TRISB, DQ ; Make DQ pin High Z
BCF STATUS,RP0 ; Select Bank 0 of data memory
ENDM
OW_LMACRO
;Force the DQ line to a logic low.
BCF STATUS,RP0 ; Select Bank 0 of data memory
BCF PORTB, DQ ; Clear the DQ bit
BSF STATUS,RP0 ; Select Bank 1 of data memory
BCF TRISB, DQ ; Make DQ pin an output
BCF STATUS,RP0 ; Select Bank 0 of data memory
ENDM
这两段代码都是作为宏指令来编写的。把它们写成宏指令,在汇编源代码中通过一个宏指令调用即可自动插入这些代码,这样就减少了代码重写的次数。第一个宏指令OW_HIZ的功能就是把DQ强制变为高阻态。由于TRISB寄存器位于数据存储器的bank 1,所以第一步就是选择数据存器的bank 1。接着通过把TRISB寄存器的DQ位置位,使DQ输出驱动器变为高阻态。代码的最后一行变回到数据存储器的bank 0,最后一行不是必需的,但这里还是加进去了,以便所有的宏指令和功能调用之后数据存储器都处在一个确定的状态。 WAIT:MACRO TIME
;Delay for TIME µs.
;Variable time must be in multiples of 5µs.
MOVLW (TIME/5) - 1 ;1µs to process
MOVWF TMP0 ;1µs to process
CALL WAIT5U ;2µs to process
ENDM
WAIT5U:
;This takes 5µs to complete
NOP ;1µs to process
NOP ;1µs to process
DECFSZ TMP0,F ;1µs if not zero or 2µs if zero
GOTO WAIT5U ;2µs to process
RETLW 0 ;2µs to process
这个子程序和WAIT宏指令一起使用,即可产生常用的延时。例如如果需要40µs的延时,就调用WAIT 0.40。先运行WAIT的前3行,产生4µs的延时,然后运行6次WAIT5U的前4行,每次产生5µs的延时,总延时为30µs,最后一圈的WAIT5U需要6µs,然后就返回到WAIT宏指令,这样总的处理时间就是30 + 4 + 6 = 40µs。| 2.5V < VDD < 5.5V, TA = -20°C to 70°C | |||||
| Parameter | Symbol | Min | Typ | Max | Units |
| Time Slot | tSLOT | 60 | 120 | µs | |
| Recovery Time | tREC | 1 | µs | ||
| Write 0 Low Time | tLOW0 | 60 | 120 | µs | |
| Write 1 Low Time | tLOW1 | 1 | 15 | µs | |
| Read Data Valid | tRDV | 15 | µs | ||
| Reset Time High | tRSTH | 480 | µs | ||
| Reset Time Low | tRSTL | 480 | 960 | µs | |
| Presence Detect High | tPDH | 15 | 60 | µs | |
| Presence Detect Low | tPDL | 60 | 240 | µs | |

OW_RESET:
OW_HIZ ; Start with the line high
CLRF PDBYTE ; Clear the PD byte
OW_LO
WAIT .500 ; Drive Low for 500µs
OW_HIZ
WAIT .70 ; Release line and wait 70µs for PD Pulse
BTFSS PORTB,DQ ; Read for a PD Pulse
INCF PDBYTE,F ; Set PDBYTE to 1 if get a PD Pulse
WAIT .430 ; Wait 430µs after PD Pulse
RETLW 0
OW_RESET子程序从确保DQ引脚处于高阻态开始,这样就可以通过上拉电阻把DQ拉为高电平。随后清PDBYTE寄存器,这样就为随后的在位检测脉冲做好了准备。之后DQ变为低电平500µs,这就满足了表1中tRSTL参数的要求,同时还留出了20µs额外的缓冲时间。把这个引脚变为低电平之后,又回到高阻态,在开始读取在位检测脉冲之前又加入一70µs的延时。这个70µs的延时可以保证无论tPDL、 tPDH如何变化,PIC总能在有效的时间进行取样。一旦读到在位检测脉冲,PDBYTE寄存器就设置为已读到逻辑状态值。DQ引脚再保持高阻态430µs,以保证满足tRSTH的要求,还可留出20µs额外的缓冲时间。
DSTXBYTE: ; Byte to send starts in W
MOVWF IOBYTE ; We send it from IOBYTE
MOVLW .8
MOVWF COUNT ; Set COUNT equal to 8 to count the bits
DSTXLP:
OW_LO
NOP
NOP
NOP ; Drive the line low for 3µs
RRF IOBYTE,F
BSF STATUS,RP0 ; Select Bank 1 of data memory
BTFSC STATUS,C ; Check the LSB of IOBYTE for 1 or 0
BSF TRISB,DQ ; HiZ the line if LSB is 1
BCF STATUS,RP0 ; Select Bank 0 of data memory
WAIT .60 ; Continue driving line for 60µs
OW_HIZ ; Release the line for pullup
NOP
NOP ; Recovery time of 2µs
DECFSZ COUNT,F ; Decrement the bit counter
GOTO DSTXLP
RETLW 0
1-Wire通信的最后一个子程序是DSRXBYTE,主要功能是从从器件接收信息,其代码如图3所示。在DQ有所动作之前首先把COUNT寄存器初始化为8,表示要接收的位数。开始时DSRXLP首先把DQ引脚变为低电平,向从器件发出信号,表示已经做好接收数据的准备。该线保持低电平6µs,通过将DQ线置为高阻态来释放口线,随后PIC在采样数据线之前要再等待4µs。当口线电平变低之后,在OW_LO存在1行代码,在OW_HIZ之中存在3行代码。一行代码的处理时间为1µs,所有的时间加在一起就是1 + 6 + 3 + 4 = 14µs,刚好比15µs的tRDV低。PORTB读取之后,DQ位被屏蔽,该寄存器进行加法运算直到255,强制CARRY位去镜像DQ位,然后CARRY位移位至保存接收数据的IOBYTE。一旦这个字节被存储起来,就需要再引入50µs的延时,以保证满足tSLOT的要求。最后检查是判断COUNT寄存器是否为零。如果为零,则表明已读完8位,退出子程序;否则,转到DSRXLP处重复这个循环。读0和读1的过程如图3所示。 
DSRXBYTE: ; Byte read is stored in IOBYTE
MOVLW .8
MOVWF COUNT ; Set COUNT equal to 8 to count the bits
DSRXLP:
OW_LO
NOP
NOP
NOP
NOP
NOP
NOP ; Bring DQ low for 6µs
OW_HIZ
NOP
NOP
NOP
NOP ; Change to HiZ and Wait 4µs
MOVF PORTB,W ; Read DQ
ANDLW 1<
小结
Microchip微控制器的PICmicro可以很容易地实现Dallas Semiconductor的1-Wire通信协议。1-Wire数据传输的实现,只需要GPIO的两个状态。PIC有多个GPIO,因此很容易就可完成这样的工作。1-Wire通信有3个基本的字程序:初始化、读数据、写数据。本文对这3个子程序完整详细地作了介绍,用它可以完成常规速度的1-Wire通信,这样就可使PIC与Dallas Semiconductor的任何1-Wire器件接口。文后的附录A是一个3个子程序的传统头文件,附录B则是PIC16F628与高精度锂电池监视器DS2761相连的一段汇编小程序。
附录A:1-Wire包含FILE (1W_16F6X.INC)
; *******************************************************
;
; Dallas 1-Wire Support for PIC16F628
;
; Processor has 4MHz clock and 1µs per instruction cycle.
;
; *******************************************************
; *******************************************************
; Dallas Semiconductor 1-Wire MACROS
; *******************************************************
OW_HIZ:MACRO
BSF STATUS,RP0 ; Select Bank 1 of data memory
BSF TRISB, DQ ; Make DQ pin High Z
BCF STATUS,RP0 ; Select Bank 0 of data memory
ENDM
; --------------------------------------------------------
OW_LMACRO
BCF STATUS,RP0 ; Select Bank 0 of data memory
BCF PORTB, DQ ; Clear the DQ bit
BSF STATUS,RP0 ; Select Bank 1 of data memory
BCF TRISB, DQ ; Make DQ pin an output
BCF STATUS,RP0 ; Select Bank 0 of data memory
ENDM
; --------------------------------------------------------
WAIT:MACRO TIME
;Delay for TIME µs.
;Variable time must be in multiples of 5µs.
MOVLW (TIME/5)-1 ;1µs
MOVWF TMP0 ;1µs
CALL WAIT5U ;2µs
ENDM
; *******************************************************
; Dallas Semiconductor 1-Wire ROUTINES
; *******************************************************
WAIT5U:
;This takes 5µS to complete
NOP ;1µs
NOP ;1µs
DECFSZ TMP0,F ;1µs or 2µs
GOTO WAIT5U ;2µs
RETLW 0 ;2µs
; --------------------------------------------------------
OW_RESET:
OW_HIZ ; Start with the line high
CLRF PDBYTE ; Clear the PD byte
OW_LO
WAIT .500 ; Drive Low for 500µs
OW_HIZ
WAIT .70 ; Release line and wait 70µs for PD Pulse
BTFSS PORTB,DQ ; Read for a PD Pulse
INCF PDBYTE,F ; Set PDBYTE to 1 if get a PD Pulse
WAIT .400 ; Wait 400µs after PD Pulse
RETLW 0
; --------------------------------------------------------
DSRXBYTE: ; Byte read is stored in IOBYTE
MOVLW .8
MOVWF COUNT ; Set COUNT equal to 8 to count the bits
DSRXLP:
OW_LO
NOP
NOP
NOP
NOP
NOP
NOP ; Bring DQ low for 6µs
OW_HIZ
NOP
NOP
NOP
NOP ; Change to HiZ and Wait 4µs
MOVF PORTB,W ; Read DQ
ANDLW 1<
附录B:PIC16F628至DS2761汇编代码(PIC_2_1W.ASM)
; *******************************************
;
; Dallas Semiconductor PIC code
;
; This code will interface a PIC16F628 microcontroller to
; a DS2761 High-Precision Li+ Battery Monitor
;
; *******************************************;
;
; VCC
; ^
; |
; |
; /
; \ Rpup
; /
; \
; |
; 16F628 | DS2761
; RB1 (pin 7) ------------------------------ DQ (pin 7)
;
; *******************************************;
;---------------------------------------------------------
; List your processor here.
list p=16F628
; Include the processor header file here.
#include
;---------------------------------------------------------
; Assign the PORTB with Constants
constant DQ=1 ; Use RB1 (pin7) for 1-Wire
;--------------------------------------------------------
; These constants are standard 1-Wire ROM commands
constant SRCHROM=0xF0
constant RDROM=0x33
constant MTCHROM=0x55
constant SKPROM=0xCC
;---------------------------------------------------------
; These constants are used throughout the code
cblock 0x20
IOBYTE
TMP0 ; Address 0x23
COUNT ; Keep track of bits
PICMSB ; Store the MSB
PICLSB ; Store the LSB
PDBYTE ; Presence Detect Pulse
endc
;---------------------------------------------------------
; Setup your configuration word by using __config.
; For the 16F628, the bits are:
; CP1,CP0,CP1,CP0,N/A, CPD, LVP, BODEN, MCLRE, FOSC2, PWRTE, WDTE, FOSC1, FOSC0
; CP1 and CP0 are the Code Protection bits
; CPD: is the Data Code Protection Bit
; LVP is the Low Voltage Programming Enable bit
; PWRTE is the power-up Timer enable bit
; WDTE is the Watchdog timer enable bit
; FOSC2, FOSC1 and FOSC0 are the oscillator selection bits.
; CP disabled, LVP disabled, BOD disabled, MCLR enabled, PWRT disabled, WDT disabled, INTRC I/O oscillator
; 11111100111000
__config 0x3F38
;---------------------------------------------------------
; Set the program origin for subsequent code.
org 0x00
GOTO SETUP
NOP
NOP
NOP
GOTO INTERRUPT ; PC 0x04...INTERRUPT VECTOR!
;---------------------------------------------------------
INTERRUPT:
SLEEP
;---------------------------------------------------------
; Option Register bits
; ____
; RBPU,INTEDG,TOCS,TOSE,PSA,PS2,PS1,PS0
; 7=PORTB Pullup Enable, 6=Interrupt Edge Select, 5=TMR0 Source,
; 4=TMR0 Source Edge, 3=Prescaler Assign, 2-0=Prescaler Rate Select
; 11010111
; PORTB pullups disabled,rising edge,internal,hightolow,TMR0,1:256
SETUP:
BCF STATUS,RP1
BSF STATUS,RP0 ; Select Bank 1 of data memory
MOVLW 0xD7
MOVWF OPTION_REG
BCF STATUS,RP0 ; Select Bank 0 of data memory
;---------------------------------------------------------
BCF INTCON,7 ; Disable all interrupts.
;---------------------------------------------------------
GOTO START
;---------------------------------------------------------
; Include the 1-Wire communication routines and macros
#INCLUDE 1w_16f6x.inc
;---------------------------------------------------------
START:
;---------------------------------------------------------
GET_TEMP:
CALL OW_RESET ; Send Reset Pulse and read for Presence Detect Pulse
BTFSS PDBYTE,0 ; 1 = Presence Detect Detected
GOTO NOPDPULSE
MOVLW SKPROM
CALL DSTXBYTE ; Send Skip ROM Command (0xCC)
MOVLW 0x69
CALL DSTXBYTE ; Send Read Data Command (0x69)
MOVLW 0x0E
CALL DSTXBYTE ; Send the DS2761 Current Register MSB address (0x0E)
CALL DSRXBYTE ; Read the DS2761 Current Register MSB
MOVF IOBYTE,W
MOVWF PICMSB ; Put the Current MSB into file PICMSB
CALL DSRXBYTE ; Read the DS2761 Current Register LSB
MOVF IOBYTE,W
MOVWF PICLSB ; Put the Current LSB into file PICLSB
CALL OW_RESET
NOPDPULSE: ; Add some error processing here!
SLEEP ; Put PIC to sleep
;---------------------------------------------------------
end
全部0条评论
快来发表一下你的评论吧 !