通信设计应用
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 0OW_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 01-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条评论
快来发表一下你的评论吧 !