要約
マキシム製品の幾つかは1-Wire®通信インタフェースを備えており、さまざまなアプリケーションで使用されています。このアプリケーションの中には、良く知られたマイクロチップ社のPICmicro® (PIC)とのインタフェースなどがあります。1-Wireデバイスとペリフェラルインタフェースコントローラ(PIC)マイクロコントローラとの間のインタフェース接続を容易にするために、このアプリケーションノートでは、PICマイクロコントローラ用として汎用の1-Wireソフトウェアルーチンを紹介し、タイミングとその詳細について説明します。また、このアプリケーションノートには、すべての1-Wireルーチンを収録したインクルードファイルも掲載しています。さらに、サンプルのアセンブリコードも掲載しています。このアセンブリコードは、PIC16F628がDS2762高精度リチウムイオンバッテリモニタを読み取ることができるように特別に記述されています。
はじめに
マイクロチップ社のPICmicroマイクロコントローラデバイス(PIC)は、低電力で低コストのシステムソリューションを設計する際の良く知られた選択肢となっています。マイクロコントローラには、複数の汎用入力/出力(GPIO)ピンがあり、マキシムの1-Wireプロトコルを実現するように容易に設定することができます。1-Wireプロトコルを使用すると、バッテリおよび熱管理、メモリ、iButton®デバイスなど、多くのマキシム製品との連携が可能になります。このアプリケーションノートでは、PIC16F628用の汎用の1-Wireルーチンを紹介し、タイミングとその詳細について説明します。分かりやすくするために、紹介するすべての機器が4MHzクロックで動作するものと想定しています。多くのPICでこの周波数を内部クロックとして利用することができます。このアプリケーションノートの付録Aには、すべての1-Wireルーチンを収めたインクルードファイルを掲載しています。付録Bでは、PIC16F628がDS2762高精度リチウムイオンバッテリモニタを読み取れるように設計されたサンプルのアセンブリコードプログラムを紹介します。このアプリケーションノートでは、標準速度の1-Wire通信に範囲を限定しています。
一般的なマクロ
1-Wireプロトコルをマスタとして送信するために必要となるGPIO状態は、次の2つだけです。すなわち、ハイインピーダンスとロジックローです。以下のPICアセンブリコードの抜粋は、これら2つの状態を実現しています。PIC16F628は2つのGPIOポート(PORTAおよびPORTB)を備えています。いずれのポートも1-Wire通信用に設定することができますが、この例ではPORTBを使用しています。また、以下のコードでは、アセンブリコード内で定数DQを設定し、これによって、PORTB内のどのビットが1-Wire端子に対応するかを示すことを想定しています。コード全体にわたって、このビット番号を単にDQと呼びます。この端子は、外付けのプルアップ抵抗を介して電源に接続する必要があります。
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_LO:MACRO
;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
これらのコード抜粋は、いずれもマクロとして記述されています。コードをマクロとして記述することによって、マクロを1個呼び出すことで自動的にアセンブリソースコードにコードが挿入されます。こうすることにより、コードの再記述を必要とする回数を抑えることができます。1つ目のマクロ(OW_HIZ)は、DQラインをハイインピーダンス状態にします。最初の手順は、データメモリのバンク1を選択することです。これはTRISBレジスタがバンク1にあるからです。次に、TRISBレジスタの中のDQビットを1に設定することにより、DQ出力ドライバをハイインピーダンス状態に変更します。コードの最終行では、データメモリのバンク0に戻しています。最終行は必須ではありませんが、これを使用すれば、すべてのマクロと関数の呼び出しに対してデータメモリを既知の状態に保持しておくことができます。
2つ目のマクロ(OW_LO)は、DQラインをロジックローにします。最初に、データメモリのバンク0を選択して、PORTBレジスタにアクセスできるようにします。PORTBレジスタはデータレジスタであり、TRISB端子を出力として設定した場合にTRISB端子に渡す値が含まれます。
PORTBのDQビットはクリアされ、DQラインはローになります。最後にデータメモリのバンク1を選択してTRISBレジスタのDQビットをクリアし、DQを出力ドライバにします。先ほどと同様、データメモリのバンク0を選択してマクロは終了します。
WAITと名付けられた最後のマクロは、1-Wireの信号送出の遅延を生成するために存在します。WAITを使用して、5µsの倍数の遅延を生成します。マクロはTIMEの値(マイクロ秒単位)を用いて呼び出され、これに相当する遅延時間が生成されます。マクロは単純に5µsの遅延が必要な回数を計算して、WAIT5U内でループします。WAIT5Uルーチンを、次の項で紹介します。WAIT内の各命令では、遅延が実現される様子をわかりやすくするために、処理時間をコメントとして記しています。
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
汎用の1-Wireルーチン
1-Wireタイミングプロトコルには規定されたタイミング制約があり、通信を成功させるためにはこの制約に従う必要があります。特定のタイミング遅延を作り出せるようにするため、WAIT5Uのルーチンを使用して5µsの遅延を生成します。このルーチンを以下に示します。
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の遅延が生成されます。次にWAIT5Uのコードの初めの4行が5µsで実行され6回ループして、合計30µsになります。WAIT5Uの最後のループは6µsかかり、その後WAITマクロに戻ります。したがって、処理時間の合計は、4 + 30 + 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 | |
1-Wire通信処理はいずれも、マスタデバイスが送出するリセットパルスから開始され、その後にスレーブデバイスから送出されるプレゼンス検出パルスが続きます。図1にこの処理を示しています。この初期化シーケンスは、PICを介して容易に送信することが可能で、このアセンブリコードを図1の下に示しています。1-Wireの初期化、読取り、および書込みのタイミング仕様を上記の表1に示しています。これらのパラメータは、このアプリケーションノート内で参照することができます。
図1. 1-Wireの初期化シーケンス
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端子がハイインピーダンス状態にあることを確認します(プルアップ抵抗によってハイにプルできるようにするためです)。次に、OW_RESETルーチンは、PDBYTEレジスタをクリアし、次のプレゼンス検出パルスを有効にする準備を行います。その後、DQ端子は500µsの間ローになります。これは、表1に示されているtRSTLパラメータを満たすものであり、20µsの追加バッファも設けられています。この端子をローにした後、端子は開放されてハイインピーダンス状態になり、プレゼンス検出パルスを読み取る前に70µsの遅延が追加されます。この70µsを追加することによって、tPDLとtPDHのどのような組み合わせについても、PICが適切な時刻にサンプリングできるようになります。プレゼンス検出パルスが読み取られると、PDBYTEレジスタは、ロジックレベルの読取りを示すように調整されます。この後、DQピンのハイインピーダンス状態がさらに430µsの間維持されるので、tRSTH時間が満たされ、また、20µsの追加バッファも含まれます。
1-Wire通信で必要な次のルーチンはDSTXBYTEです。これを使用して、1-Wireのスレーブデバイスにデータを送信します。このルーチンのPICコードを図2の下に示しています。このルーチンは、WREGレジスタ内に送信データを用意して呼び出され、直ちにIOBYTEレジスタに移動されます。次に、COUNTレジスタが8に初期化され、DQラインに送出されるビット数をカウントします。PICは、DSTXLPから始めてデータの送出を開始します。送信されるロジックレベルに関わらず、最初にDQ端子が3µsの間ローになります。こうすることで、tLOW1時間が満たされます。次に、IOBYTEのLSBがCARRYビットにシフトされ、1か0かをテストされます。CARRYが1の場合、TRISBのDQビットがセットされて、ピンはハイインピーダンス状態に変化し、ラインはプルアップ抵抗によってハイにプルされます。CARRYが0の場合、ラインはローの状態を維持します。次に、tLOW0の最小時間を満たすため60µsの遅延が追加されます。60µsの待機後、この端子はハイインピーダンス状態に変化し、プルアップ抵抗の回復のためにさらに2µsが追加されます。最後に、COUNTレジスタがデクリメントされます。COUNTレジスタが0の場合、8ビットのすべてが送信されており、ルーチンは終了します。COUNTレジスタが0でない場合、DSTXLPから始めて別のビットが送信されます。図2は、「書込み0」と「書込み1」の手順を視覚的に説明しています。
図2. 1-Wireの書込みタイムスロット
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です。これによってPICはスレーブデバイスから情報を受信することができます。このコードは、図3の下に示されています。COUNTレジスタが8に初期化された後、DQ動作が開始されます。この機能は、受信したビット数をカウントします。まず、DSRXLPはDQ端子をローにし、PICがデータを受信する準備ができていることをスレーブデバイスに通知します。ラインは6µsの間ローになり、その後DQ端子をハイインピーダンス状態にすることで開放されます。次に、PICはさらに4µsの間待機してからデータラインをサンプリングします。ラインがローになった後、OW_LO内には1行のコードがあり、OW_HIZ内には3行のコードがあります。各行の処理には1µsかかります。これらの時間をすべて加算すると、1 + 6 + 3 + 4 = 14µsになりますが、これはtRDV仕様の15µsをわずかに下回っています。PORTBレジスタを読み取った後、DQビットのみを取り出し、レジスタに255を加算してCARRYビットにDQビットを反映させます。CARRYビットは次にIOBYTEにシフト入力され、着信バイトはここに格納されます。バイトが格納されたら、tSLOTが満たされるように50µsの遅延が追加されます。最後のチェックは、COUNTレジスタが0かどうかを判定することです。0の場合、8ビットが読み取られており、ルーチンは終了します。そうでない場合は、DSRXLPからループは繰り返されます。「読取り0」および「読取り1」の処理を図3に視覚的に示しています。
図3. 1-Wireの読取りタイムスロット
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<<DQ ; Mask off the DQ bit
ADDLW .255 ; C = 1 if DQ = 1: C = 0 if DQ = 0
RRF IOBYTE,F ; Shift C into IOBYTE
WAIT .50 ; Wait 50µs to end of time slot
DECFSZ COUNT,F ; Decrement the bit counter
GOTO DSRXLP
RETLW 0
まとめ
マキシムの1-Wire通信プロトコルは、マイクロチップ社のPICmicroファミリのマイクロコントローラ内に容易に実現することができます。1-Wire処理を完了するために必要となるGPIO状態は2つだけであり、PICにある多数のGPIOは、この仕事を行うように容易に設定することができます。1-Wire通信には、3つの基本ルーチンが必要となります。「初期化」、「バイトの読取り」、および「バイトの書込み」です。正確な1-Wireの標準速度の通信を実現するため、これら3つのルーチンを提示して詳細に説明しました。これらを使用することで、PICは多くのマキシムの1-Wireデバイスのいずれにでも接続することができます。このアプリケーションノートの付録Aは、3つのルーチンすべてを使いやすいインクルードファイルに収録しています。付録Bは、DS2762高精度リチウムイオンバッテリモニタにPIC16F628を接続するための短いアセンブリプログラムを収録しています。
付録A:1-Wireのインクルードファイル(1W_16F6X.INC)
; *******************************************************
;
; Maxim 1-Wire Support for PIC16F628
;
; Processor has 4MHz clock and 1µs per instruction cycle.
;
; *******************************************************
; *******************************************************
; Maxim 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_LO:MACRO
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
; *******************************************************
; Maxim 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<<DQ ; Mask off the DQ bit
ADDLW .255 ; C=1 if DQ=1: C=0 if DQ=0
RRF IOBYTE,F ; Shift C into IOBYTE
WAIT .50 ; Wait 50µs to end of time slot
DECFSZ COUNT,F ; Decrement the bit counter
GOTO DSRXLP
RETLW 0
; --------------------------------------------------------
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
; --------------------------------------------------------
付録B:PIC16F628をDS2762に接続するためのアセンブリコード(PIC_2_1W.ASM)
; *******************************************
;
; Maxim PIC code
;
; This code will interface a PIC16F628 microcontroller to
; a DS2762 High-Precision Li+ Battery Monitor
;
; *******************************************;
;
; VCC
; ^
; |
; |
; /
; \ Rpup
; /
; ; |
; 16F628 | DS2762
; RB1 (pin 7) ------------------------------ DQ (pin 7)
;
; *******************************************;
;---------------------------------------------------------
; List your processor here.
list p=16F628
; Include the processor header file here.
#include <p16F628.inc>
;---------------------------------------------------------
; 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 DS2762 Current Register MSB address (0x0E)
CALL DSRXBYTE ; Read the DS2762 Current Register MSB
MOVF IOBYTE,W
MOVWF PICMSB ; Put the Current MSB into file PICMSB
CALL DSRXBYTE ; Read the DS2762 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
この記事に関して
製品
高精度Li+ (リチウムイオン)バッテリモニタ
高精度クーロンカウンタ
警報付き、高精度Li+ (リチウムイオン)バッテリモニタ
あらゆるバッテリに対応したバッテリ残量ゲージ
エコノ1-Wireデジタルサーモメータ
1-Wire寄生電力デジタルサーモメータ
1-Wireデジタル温度センサー、1Kbロック可能なEEPROM内蔵
1-Wire寄生電力デジタルサーモメータ
寄生電源デジタルサーモメータ
1-Wire周囲温度センサー
1-Wire寄生電源、周囲温度センサー
プログラマブル分解能1-Wireデジタルサーモメータ
1-Wire EEPROM
1024ビット、1-Wire EEPROM