要約
マキシム製品の幾つかは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
{{modalTitle}}
{{modalDescription}}
{{dropdownTitle}}
- {{defaultSelectedText}} {{#each projectNames}}
- {{name}} {{/each}} {{#if newProjectText}}
-
{{newProjectText}}
{{/if}}
{{newProjectTitle}}
{{projectNameErrorText}}