アプリケーションノート 162

マイクロコントローラ環境における1-Wire®温度センサDS18X20/DS1822とのインタフェース


要約: このアプリケーションノートでは、マイクロコントローラと1-Wire温度センサDS18B20、DS18S20、およびDS1822をインタフェースするための簡素な1-Wireソフトウェアをユーザーに紹介します。本文では例として、DS5000 (8051コンパチブル)マイクロコントローラが使われています。遅延、リセット、読込みビット、書込みビット、読込みバイト、書込みバイト、ROM検索、CRC、読込み温度、および読込みスクラッチパッドルーチンの実行を示すソフトウェア例が提供されています。

はじめに

DS18B20DS18S20またはDS1822のような1-Wireデバイスをマイクロコントローラにインタフェースするためのいくつかの方法があります。これらの方法は、簡単なソフトウェアソリューションから、DS2480Bのようなシリアルインタフェースチップを使用したり、マキシムのVHDL 1-WireマスタコントローラをカスタムASICに組み込んだりと広範にわたっています。本文では、マイクロコントローラと温度センサDS18x20またはDS1822 (個数に制限なく)との間の基本的な1-Wire通信の最も簡単なソフトウェアソリューションについてユーザーに紹介します。

DS18B20、DS18S20、およびDS1822のタイミングおよび動作詳細情報は、マキシムのウェブサイトから入手可能な各データシートにてご覧いただけます。

ハードウェア構成

図1のブロックダイアグラムでは、複数の1-Wire温度センサを使うとハードウェア構成を簡素化できることを示しています。単線バスはすべてのデバイスに通信アクセスと電源の両方を供給します。バスへの電力は3V~5.5Vの電源レイルから4.7kΩプルアップ抵抗を介して提供されます。各デバイスがユニークな64ビットROMコード識別子を持っているので、ほぼ無制限数の1-Wireデバイスをバスに接続できます。

図1. ホストマイクロコントローラインタフェース
図1. ホストマイクロコントローラインタフェース

インタフェースタイミング

DS18x20/DS1822とのコミュニケーションは「時間スロット」の使用によって行われ、1-Wireバスを介してデータ送信ができます。すべての通信サイクルは図2に示しているようにマイクロコントローラからのリセットパルスで始まり、DS18x20/DS1822からのプレゼンスパルスがその後に続きます。

書込み時間スロットはバスマスタが1-Wireバスをロジックハイ(インアクティブ)からロジックローまでプルする時に開始されます。すべての書込み時間スロットは、60µs~120µsの時間持続し、サイクル間のリカバリ時間が最小1µsでなければなりません。書込み「0」と書込み「1」の時間スロットを図3に示します。書込み「0」の時間スロットでは、ホストマイクロコントローラは、ラインを時間スロットの間ローにします。しかしながら、書込み「1」の時間スロットでは、マイクロコントローラはラインをローにプルし、時間スロット開始後15µs以内にラインを開放します。

読込み時間スロットは、マイクロコントローラが1µsバスをローにし、それに続いてDS18x20/DS1822がラインの制御を行えて有効なデータ(ハイまたはローの)を出せるようにバスを開放すると開始します。全ての読込み時間スロットは60µs~120µsの時間持続し、サイクル間のリカバリ時間が最小1µsでなければなりません(図3参照)。

図2. リセットパルスとプレゼンスパルス
図2. リセットパルスとプレゼンスパルス

ラインタイプの凡例(図2および図3)

図3. 書込みおよび読込み時間スロット
図3. 書込みおよび読込み時間スロット

ソフトウェア制御

1-Wireインタフェースの特別なタイミング条件を正確にコントロールするためには、ある重要機能がまず確立されなければなりません。最初に確立される機能は「遅延」機能で、すべての読込みおよび書込み制御に不可欠なものです。この機能は完全にマイクロコントローラの速度に依存しています。このアーティクルの目的のため、11.059MHzで動作するDS5000 (8051コンパチブル)マイクロコントローラが使われています。右の例は、タイミング遅延を生成するためのプロトタイプ「C」の機能を示しています。

遅延例

// DELAY - with an 11.059MHz crystal.
// Calling the routine takes about 24us, and then
// each count takes another 16us.
//
void delay(int useconds)
{
int s;
for (s=0; s<useconds;s++);
}
各通信サイクルはマイクロコントローラからのリセットで開始しなければいけないため、「リセット」機能は実施されるべき次に最も重要な機能です。リセット時間スロットは480µsです。遅延を「3」に設定し次に「25」に設定することによって(以下例参照)、リセットパルスが必要な時間継続します。リセット後、マイクロコントローラは、DS18x20/DS1822がラインをローにすることによって、その「プレゼンス」を示すことができるように開放しなければなりません。複数の温度センサがバス上にある場合、それらはすべてプレゼンスパルスで同時に応答することに注意してください。

リセット例

//////////////////////////////////////////////////////////////////////////////
// OW_RESET - performs a reset on the one-wire bus and
// returns the presence detect. Reset is 480us, so delay
// value is (480-24)/16 = 28.5 - we use 29. Presence checked
// another 70us later, so delay is (70-24)/16 = 2.875 - we use 3.
//
unsigned char ow_reset(void)
{
unsigned char presence;
DQ = 0; //pull DQ line low
delay(29); // leave it low for 480us
DQ = 1; // allow line to return high
delay(3); // wait for presence
presence = DQ; // get presence signal
delay(25); // wait for end of timeslot
return(presence); // presence signal returned
} // 0=presence, 1 = no part
以下の4つの例で示される読込みおよび書込み機能コードセグメントは、すべてのデータビットとデータバイトの読込みおよび書込み動作に必要な基本構造を提供しています。

読込みビット例

//////////////////////////////////////////////////////////////////////////////
// READ_BIT - reads a bit from the one-wire bus. The delay
// required for a read is 15us, so the DELAY routine won't work.
// We put our own delay function in this routine in the form of a
// for() loop.
//
unsigned char read_bit(void)
{
unsigned char i;
DQ = 0; // pull DQ low to start timeslot
DQ = 1; // then return high
for (i=0; i<3; i++); // delay 15us from start of timeslot
return(DQ); // return value of DQ line
}

書込みビット例

//////////////////////////////////////////////////////////////////////////////
// WRITE_BIT - writes a bit to the one-wire bus, passed in bitval.
//
void write_bit(char bitval)
{
DQ = 0; // pull DQ low to start timeslot
if(bitval==1) DQ =1; // return DQ high if write 1
delay(5); // hold value for remainder of timeslot
DQ = 1;
}// Delay provides 16us per loop, plus 24us. Therefore delay(5) = 104us

読込みバイト例

//////////////////////////////////////////////////////////////////////////////
// READ_BYTE - reads a byte from the one-wire bus.
//
unsigned char read_byte(void)
{
unsigned char i;
unsigned char value = 0;
for (i=0;i<8;i++)
{
if(read_bit()) value|=0x01<<i; // reads byte in, one byte at a time and then
// shifts it left
delay(6); // wait for rest of timeslot
}
return(value);
}

書込みバイト例

//////////////////////////////////////////////////////////////////////////////
// WRITE_BYTE - writes a byte to the one-wire bus.
//
void write_byte(char val)
{
unsigned char i;
unsigned char temp;
for (i=0; i<8; i++) // writes byte, one bit at a time
{
temp = val>>i; // shifts val right 'i' spaces
temp &= 0x01; // copy that bit to temp
write_bit(temp); // write bit in temp into
}
delay(5);
}

検索ROMアルゴリズム

1-Wireネットの概念を最大限に活用するために、マイクロコントローラは、ネットに接続されているデバイス(数は無制限)と通信できるようにしなくてはいけません。これを行うためには、マイクロコントローラは、図4に示す「検索ROM」アルゴリズムを使ってバス上の各デバイスのユニークな64ビットROM識別コードを学習する必要があります。図4に続く例は4つのスレーブデバイスを備えたバスの検索ROMルーチンを説明します。検索ROMルーチンのサンプルコードも示されています。ROMコードがすべて認識されると、「マッチROM」コマンドを、ネット上のあらゆる特定デバイスと通信するために使うことができます。

図4. 検索ROMアルゴリズム
図4. 検索ROMアルゴリズム

ROM検索例

ROM検索プロセスの間、バスマスタは簡単な3ステップルーチンを繰り返す必要があります。1) スレーブデバイスからROMコードビットを読み込む、2) ビットの補数を読み込む、3) そのビットの選択値を書き込む。バスマスタはこの3ステップルーチンを64回(各ROMコードビットにつき1度)行う必要があります。1つの完全パスが完了するとバスマスタはバス上の1スレーブデバイスのROMコードを認識します。残りのデバイスとそのROMコードは追加パスによって認識可能です。

ROM検索プロセスは、4つの異なるデバイスが同じ1-Wireバスに接続されていると仮定する次例によって示されます。4デバイスのROMコードを示します。
ROM1 00110101...
ROM2 10101010...
ROM3 11110101...
ROM4 00010001...
検索プロセスは以下のようになります。
  1. バスマスタは、リセットパルスを出すことで初期化シーケンスを開始します。スレーブデバイスは、同時プレゼンスパルスを出すことで応答します。
  2. バスマスタは次に、1-Wireバス上で検索ROMコマンドを出します。
  3. 各デバイスは、各ROMコードの最初のビット値を1-Wireバスに置くことで検索ROMコマンドに応答します。マスタは次にバス値を読み込みます。この場合、ROM1とROM4は0を1-Wireバスに置きます。つまり、ローにします。ROM2とROM3は、ラインをハイのままにすることで、1を1-Wireバスに置きます。結果としてはライン上で全デバイスが論理ANDとなります。したがって、バスマスタは0を読み込みます。1-Wireバス上のすべてのデバイスは、ROMコードの最初のビットの補数を1-Wireバスに置くことで、この読込みに応答します。ROM1とROM4は、ラインをハイのままにできるように、1を1-Wireバスに置き、ROM2とROM3は0をバスに置き、ローにします。バスマスタは再びバスを読込み、再び0を読み込みます。

    スレーブデバイスROMコードによって、バスマスタが2つの読込みから取得できる4つのデータの組み合わせがあります。これらの組み合わせは以下のように解釈できます。

    00 現在のROMコードビット位置に衝突ビットを持つバスに接続されているデバイスがあります。
    01 バスに接続されているすべてのデバイスはこのビット位置に0を持ちます。
    10 バスに接続されているすべてのデバイスはこのビット位置に1を持ちます。
    11 1-Wireバスに接続されているデバイスはありません。

    この例では、バスマスタは各読込みの間に0を読込みました。これにより、1-Wireバス上に最初のROMコード位置に0を持つデバイスも1を持つデバイスもあることが分かります。

  4. 前のデータに対応し、バスマスタは0をバスに書き込みます。これにより、この検索パスの残りではROM2とROM3が選択解除され、ROM1とROM4のみ1-Wireバスに「接続された」状態にします。

  5. バスマスタはもう2つの読込みを行い、0、次に1を受け取ります。これは、バスにまだ接続されている全デバイスが2番目のROMデータビットとして0を持っていることを示します。

  6. ROM1とROM4の両方をバスに接続したままにするためにバスマスタは次に0を書き込みます。

  7. バスマスタは再び2つの読込みを行い、2つの0を受け取ります。これは、1-Wireバス上のデバイスの1つが3番目のROMコード位置に0を持ち他のデバイスが1を持つことをマスタに示します。

  8. バスマスタはバスに0を書き込みますが、これによりROM1が選択解除され、ROM4をいまだ接続されている唯一のデバイスとします。

  9. バスマスタはROM4からROMビットの残りを読み込み、必要であればROM4デバイスにアクセスし続けます。これにより最初のROM検索パスが完了します。バスマスタは、ROMコードを学習することで1-Wireバス上で一意的に識別された1スレーブ(ROM4)を持つことになります。

  10. バスマスタは、ステップ1から7までを繰り返すことで新しいROM検索シーケンスを開始します。

  11. バスマスタは、バスに1を書き込みます(ステップ8で行われたように0ではなく)。これはROM4を離し、ROM1のみまだ接続された状態とします。

  12. バスマスタはROM1からROMビットの残りを読み込み、必要であればROM1デバイスと通信することができます。これにより、第2のROM検索パスが完了し、マスタはもう一つのスレーブデバイス(ROM1)を認識したことになります。

  13. バスマスタは、ステップ1から3を繰り返すことで新しいROM検索を開始します。

  14. バスマスタは、バスに1を書き込みます(ステップ4で行われたように0ではなく)。これにより、残りの検索パスのためにROM1とROM4が選択解除され、ROM2とROM3のみバスとつながった状態にします。

  15. バスマスタは、2つの読込みを行い、2つの0を受け取ります。

  16. バスマスタはバスに0を書き込み、これによりROM3が離れ、ROM2のみバスに接続された状態にします。

  17. バスマスタはROM2からROMビットの残りを読み込み、必要であればROM2と通信します。これにより第3のROM検索パスが完了し、マスタはROM2スレーブデバイスを認識したことになります。

  18. バスマスタは、ステップ13から15を繰り返すことで、4番目と最後のROM検索を開始します。

  19. バスマスタは、バスに1を書き込みます(ステップ16で行われたように0ではなく)。これにより、ROM2は離れ、ROM3のみバスに接続された状態にします。

  20. バスマスタはROM3からROMビットの残りを読み込み、必要であればROM3デバイスと通信します。これにより第4のROM検索パスが完了し、その間マスタはROM3デバイスを認識しました。この点で、マスタはバス上のすべてのスレーブデバイスを認識し、この時点からバスマスタはROMコードを使ってあらゆるデバイスを個別にアドレス指定できます。
注:バスマスタは、各ROM検索パスの間、1つの1-Wireデバイスの一意的なROMコードを学習します。1つのROMコードを学習するのに必要な時間は以下です。
960µs + (8 + 3 × 64) 61µs = 13.16m
したがってバスマスタは、1秒あたり75の異なる1-Wireスレーブデバイスを識別することができます。

検索ROMコード例

以下にあるプロトタイプ機能に示すように、「Find Devices」機能は1-Wireリセットで開始し、デバイスがネット上にあるかどうかを決定し、もしそうであればデバイスをウェイクアップします。次に、この「First」機能が呼び出され、不一致のビットを追跡し、「Next」に戻り、ネット上の各ユニークデバイスを見つけます。

「Next」機能は非常に幅広く、ネット上の各デバイスのユニークな64ビットROMコード識別子を見つけるのにほとんどのタスクを行います。

// FIND DEVICES
void FindDevices(void)
{
unsigned char m;
if(!ow_reset()) //Begins when a presence is detected
{
if(First()) //Begins when at least one part is found
{
numROMs=0;
do
{
numROMs++;
for(m=0;m<8;m++)
{
FoundROM[numROMs][m]=ROM[m]; //Identifies ROM
\\number on found device
} printf("\nROM CODE =%02X%02X%02X%02X\n",
FoundROM[5][7],FoundROM[5][6],FoundROM[5][5],FoundROM[5][4],
FoundROM[5][3],FoundROM[5][2],FoundROM[5][1],FoundROM[5][0]);
}while (Next()&&(numROMs<10)); //Continues until no additional devices are found
}
}
}
// FIRST
// The First function resets the current state of a ROM search and calls
// Next to find the first device on the 1-Wire bus.
//
unsigned char First(void)
{
lastDiscrep = 0; // reset the rom search last discrepancy global
doneFlag = FALSE;
return Next(); // call Next and return its return value
}
// NEXT
// The Next function searches for the next device on the 1-Wire bus. If
// there are no more devices on the 1-Wire then false is returned.
//
unsigned char Next(void)
{
unsigned char m = 1; // ROM Bit index
unsigned char n = 0; // ROM Byte index
unsigned char k = 1; // bit mask
unsigned char x = 0;
unsigned char discrepMarker = 0; // discrepancy marker
unsigned char g; // Output bit
unsigned char nxt; // return value
int flag;
nxt = FALSE; // set the next flag to false
dowcrc = 0; // reset the dowcrc
flag = ow_reset(); // reset the 1-Wire
if(flag||doneFlag) // no parts -> return false
{
lastDiscrep = 0; // reset the search
return FALSE;
}
write_byte(0xF0); // send SearchROM command
do
// for all eight bytes
{
x = 0;
if(read_bit()==1) x = 2;
delay(6);
if(read_bit()==1) x |= 1; // and its complement
if(x ==3) // there are no devices on the 1-Wire
break;

else
{
if(x>0) // all devices coupled have 0 or 1
g = x>>1; // bit write value for search
else
{
// if this discrepancy is before the last
// discrepancy on a previous Next then pick
// the same as last time
if(m<lastDiscrep)
g = ((ROM[n]&k)>0);
else // if equal to last pick 1
g = (m==lastDiscrep); // if not then pick 0
// if 0 was picked then record
// position with mask k
if (g==0) discrepMarker = m;
}
if(g==1) // isolate bit in ROM[n] with mask k
ROM[n] |= k;
else
ROM[n] &= ~k;
write_bit(g); // ROM search write
m++; // increment bit counter m
k = k<<1; // and shift the bit mask k
if(k==0) // if the mask is 0 then go to new ROM
{ // byte n and reset mask
ow_crc(ROM[n]); // accumulate the CRC
n++; k++;
}
}
}while(n<8); //loop until through all ROM bytes 0-7
if(m<65||dowcrc) // if search was unsuccessful then
lastDiscrep=0; // reset the last discrepancy to 0
else
{
// search was successful, so set lastDiscrep,
// lastOne, nxt
lastDiscrep = discrepMarker;
doneFlag = (lastDiscrep==0);
nxt = TRUE; // indicates search is not complete yet, more
// parts remain
}
return nxt;
}

巡回冗長検査の実行

巡回冗長検査(CRC)は以下に示す機能を使って達成することができ、検索ROM機能を行う際は含まれるべきです。
//////////////////////////////////////////////////////////////////////////////
// ONE WIRE CRC
//
unsigned char ow_crc( unsigned char x)
{
dowcrc = dscrc_table[dowcrc^x];
return dowcrc;
}
#define FALSE 0
#define TRUE 1
////////////////////////////////////////////////////////////////////////////
// GLOBAL VARIABLES
//
unsigned char ROM[8]; // ROM Bit
unsigned char lastDiscrep = 0; // last discrepancy
unsigned char doneFlag = 0; // Done flag
unsigned char FoundROM[5][8]; // table of found ROM codes
unsigned char numROMs;
unsigned char dowcrc;
unsigned char code dscrc_table[] = {
0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};

デバイス温度の読込み

ネット上に単一デバイスがある場合、以下に示すように「Read Temperature」機能を直接使うことができます。しかし、複数のデバイスがネット上にあると、データの衝突を避けるために、「Match ROM」機能を使って特定デバイスを選択する必要があります。

以下のコード例は温度センサDS18S20を利用するために特別に書かれました。このコードをDS18B20またはDS1822で使用するためには、温度レジスタ形式の相違のためわずかに変更する必要があります。温度レジスタ形式の情報については各データシートをご参照ください。
void Read_Temperature(void)
{
char get[10];
char temp_lsb,temp_msb;
int k;
char temp_f,temp_c;
ow_reset();
write_byte(0xCC); //Skip ROM
write_byte(0x44); // Start Conversion
delay(5);
ow_reset();
write_byte(0xCC); // Skip ROM
write_byte(0xBE); // Read Scratch Pad
for (k=0;k<9;k++){get[k]=read_byte();}
printf("\n ScratchPAD DATA = %X%X%X%X%X\n",get[8],get[7],get[6],get[5],get[4],get[3],get[2],get[1],get[0]);
temp_msb = get[1]; // Sign byte + lsbit
temp_lsb = get[0]; // Temp data plus lsb
if (temp_msb <= 0x80){temp_lsb = (temp_lsb/2);} // shift to get whole degree
temp_msb = temp_msb & 0x80; // mask all but the sign bit
if (temp_msb >= 0x80) {temp_lsb = (~temp_lsb)+1;} // twos complement
if (temp_msb >= 0x80) {temp_lsb = (temp_lsb/2);}// shift to get whole degree
if (temp_msb >= 0x80) {temp_lsb = ((-1)*temp_lsb);} // add sign bit
printf( "\nTempC= %d degrees C\n", (int)temp_lsb ); // print temp. C
temp_c = temp_lsb; // ready for conversion to Fahrenheit
temp_f = (((int)temp_c)* 9)/5 + 32;
printf( "\nTempF= %d degrees F\n", (int)temp_f ); // print temp. F
}

スクラッチパッドメモリの読込み

スクラッチパッドメモリはユーザーに、温度、THおよびTLプログラマブル温度計設定、分数温度計測に使われるCount RemainとCount Per Cデータなどのすべての必要なデバイスデータを提供します。CRCバイトもスクラッチパッドメモリに含まれます。
void Read_ScratchPad(void)
{
int j;
char pad[10];
printf("\nReading ScratchPad Data\n");
write_byte(0xBE);
for (j=0;j<9;j++){pad[j]=read_byte();}
printf("\n ScratchPAD DATA =
%X%X%X%X%X%X\n",pad[8],pad[7],pad[6],pad[5],pad[4],pad[3],pad[2],pad[1],pad[0]);
}
ネット上に単一デバイスしかない場合、64ビットROMコードを見つけるために「Read ROM」コマンドが使われます。複数デバイスは「Search ROM」機能の使用が必要です。
void Read_ROMCode(void)
{
int n;
char dat[9];
printf("\nReading ROM Code\n");
ow_reset();
write_byte(0x33);
for (n=0;n<8;n++){dat[n]=read_byte();}
printf("\n ROM Code = %X%X%X%X\n",dat[7],dat[6],dat[5],dat[4],dat[3],dat[2],dat[1],dat[0]);
}
「Match ROM」機能は、ネット上の個別デバイスを選択するために64ビット ROM-IDを提供する必要があります。
// Perform Match ROM
//
unsigned char Send_MatchRom(void)
{
unsigned char i;
if(ow_reset()) return false;
write_byte(0x55); // match ROM
for(i=0;i<8;i++)
{
write_byte(FoundROM[numROMs][i]); //send ROM code
}
return true;
}

付録A

DS5000 (8051ソースコード)

// 1wiretalk.c -- Functions for the Dallas Semiconductor DS18x20/DS1822
// Two-Wire Temperature Sensor
// Designed for 8051 microcontrollers
// This code was developed using the DS5000/DS2251T
// Please note that 128K RAM size is required to run this program.
/*----------------------------------------------------------------------*/
//#pragma CODE SMALL OPTIMIZE(3)
/* command line directives */
#include <absacc.h> /* absolute addressing modes */
#include <ctype.h> /* character types */
#include <math.h> /* standard math */
#include <stdio.h> /* standard I/O */
#include <string.h> /* string functions */
#include <ds50001w.h> /* DS5000 series 8052 registers */
/*----------------------------------------------------------------------*/
/* Configuration parameters */
/*----------------------------------------------------------------------*/
#define XtalFreq (11059490) /* main crystal frequency */
#define CntrFreq (XtalFreq/12) /* main counter frequency */
#define BaudRate (9600) /* baud rate */
#define CntrTime (8) /* number of cycles for counter */
#define Ft (32768.0) /* target crystal frequency */
/*----------------------------------------------------------------------*/
/*--------------------------------------------------------------------* /
/////////////////////////BEGIN MAIN PROGRAM//////////////////////////////
main()
{/
*----------------------------------------------------------------------*/
/* Local variables */
/*----------------------------------------------------------------------*/
unsigned char Select_Type; /* Function variable */
/*----------------------------------------------------------------------*/
/* Start of program execution */
/*----------------------------------------------------------------------*/
/* Inhibit the watchdog timer and set up memory */
/*----------------------------------------------------------------------*/
TA = 0xAA; /* timed access */
TA = 0x55;
PCON = 0x00; /* inhibit watchdog timer */
*----------------------------------------------------------------------*/
/* Set up the serial port */
/*----------------------------------------------------------------------*/
SCON = 0x50; /* SCON: mode 1, 8-bit UART, enable rcvr */
TMOD = 0x21; /* TMOD: timer 1, mode 2, 8-bit reload */
/* TMOD: timer 0, mode 1, 16-bit */
PCON |= 0x80; /* SMOD = 1 Double Baud Rate for TH1 load */
TH0=TL0 = 0;
TH1=TL0 = (unsigned int)(256 - ( (XtalFreq / BaudRate) / 192));
TR0 = 1; /* TR0: timer 0 run */
TR1 = 1; /* TR1: timer 1 run */
TI = 1; /* TI: set TI to send first char of UART */
/*----------------------------------------------------------------------*/
/* Display DS1820 One-Wire Device banner */
/*----------------------------------------------------------------------*/
printf ("\n");
printf (" Dallas Semiconductor - Systems Extension\n");
printf (" Source for DS1820 Temperature Reading and\n");
printf (" Search ROM code.\n");
printf (" Updated Code August, 2001 \n");
printf (" [C Program for DS500x or 8051 Compatible Microcontroller]");
printf("\n\n");
printf("\n********************************************************************\n");
printf (" Select Menu Option\n");
printf (" 1. One-Wire Reset\n");
printf (" 2. Read ROM Code of Single Device On Net\n");
printf (" 3. Perform Search ROM\n");
printf (" 4. Read Scratch PAD\n");
printf (" 5. Read Temperature\n");
printf (" 6. Find All Devices\n");
printf ("\n\n");
printf (" Note: This program represents an example only.\n");
printf (" No warranties or technical support is provided with this program.\n");
/*----------------------------------------------------------------------*/
do {
/*----------------------------------------------------------------------*/
/* Enable CE2 */
/*----------------------------------------------------------------------*/
EA = 0; /* Inhibit interrupts */
TA = 0xAA; /* timed access */
TA = 0x55;
MCON = MCON |= 0x04; /* Enable topside CE 0xCC */
/*----------------------------------------------------------------------*/
/* Disable CE2 */
/*----------------------------------------------------------------------*/
TA = 0xAA; /* timed access */
TA = 0x55;
MCON = 0xC8; /* Disable topside CE */
EA = 1; /* Enable interrupts */
Select_Type = getchar(); /* get variable to start */
switch(Select_Type)
{
case '1': printf ("\n 1. Sent 1-Wire Reset\n");
ow_reset();
break;
case '2': printf (" 2. Read ROM Code of Single Device On Net\n");
ow_reset();
Read_ROMCode();
case '3': printf("\n 3. Performing Search ROM\n");
ow_reset();
First();
printf("\nROM CODE =%02X%02X%02X%02X\n",
FoundROM[5][7],FoundROM[5][6],FoundROM[5][5],FoundROM[5][4],
FoundROM[5][3],FoundROM[5][2],FoundROM[5][1],FoundROM[5][0]);
break;
case '4': printf ("\n 4. Read Scratch PAD\n");
ow_reset();
write_byte(0xCC); // Skip ROM
Read_ScratchPad();
break;
case '5': printf ("\n 5. Read Temperature\n");
Read_Temperature(); //initiates a temperature reading
break;
case '6': printf ("\n 6. Find All Devices\n");
ow_reset();
FindDevices();
break;
default: printf ("\n Typo: Select Another Menu Option\n");
break;
}; /* end switch*/
} while (1); /* Loop forever */
/*----------------------------------------------------------------------*/
/* End of program */
/*----------------------------------------------------------------------*/

付録B

DS5000 (ヘッダファイルを含む8051 C)

/*-----------------------------------------------------------------------------
DS5000.H
Header file for Dallas Semiconductor DS5000.
Copyright (c) 1995-1996 Keil Software, Inc. All rights reserved.
-----------------------------------------------------------------------------*/
#ifndef DS5000_HEADER_FILE
#define DS5000_HEADER_FILE 1
/*------------------------------------------------
DS5000 Byte Registers
------------------------------------------------*/
sfr P0 = 0x80;
sfr SP = 0x81;
sfr DPL = 0x82;
sfr DPH = 0x83;
sfr PCON = 0x87;
sfr TCON = 0x88;
sfr TMOD = 0x89;
sfr TL0 = 0x8A;
sfr TL1 = 0x8B;
sfr TH0 = 0x8C;
sfr TH1 = 0x8D;
sfr P1 = 0x90;
sfr SCON = 0x98;
sfr SBUF = 0x99;
sfr P2 = 0xA0;
sfr IE = 0xA8;
sfr P3 = 0xB0;
sfr IP = 0xB8;
sfr MCON = 0xC6;
sfr TA = 0xC7;
sfr PSW = 0xD0;
sfr ACC = 0xE0;
sfr B = 0xF0;
/*------------------------------------------------
DS5000 P0 Bit Registers
------------------------------------------------*/
//sbit P0_0 = 0x80; // Set Output Here
sbit DQ = 0x80; // Set Output Here
sbit P0_1 = 0x81;
sbit P0_2 = 0x82;
sbit P0_3 = 0x83;
sbit P0_4 = 0x84;
sbit P0_5 = 0x85;
sbit P0_6 = 0x86;
sbit P0_7 = 0x87;
AN162
17
/*------------------------------------------------
DS5000 PCON Bit Values
------------------------------------------------*/
#define IDL_ 0x01
#define STOP_ 0x02
#define EWT_ 0x04
#define EPFW_ 0x08
#define WTR_ 0x10
#define PFW_ 0x20
#define POR_ 0x40
#define SMOD_ 0x80
/*------------------------------------------------
DS5000 TCON Bit Registers
------------------------------------------------*/
sbit IT0 = 0x88;
sbit IE0 = 0x89;
sbit IT1 = 0x8A;
sbit IE1 = 0x8B;
sbit TR0 = 0x8C;
sbit TF0 = 0x8D;
sbit TR1 = 0x8E;
sbit TF1 = 0x8F;
/*------------------------------------------------
DS5000 TMOD Bit Values
------------------------------------------------*/
#define T0_M0_ 0x01
#define T0_M1_ 0x02
#define T0_CT_ 0x04
#define T0_GATE_ 0x08
#define T1_M0_ 0x10
#define T1_M1_ 0x20
#define T1_CT_ 0x40
#define T1_GATE_ 0x80
#define T1_MASK_ 0xF0
#define T0_MASK_ 0x0F
/*------------------------------------------------
DS5000 P1 Bit Registers
------------------------------------------------*/
sbit P1_0 = 0x90;
sbit P1_1 = 0x91;
sbit P1_2 = 0x92;
sbit P1_3 = 0x93;
sbit P1_4 = 0x94;
sbit P1_5 = 0x95;
sbit P1_6 = 0x96;
sbit P1_7 = 0x97;
AN162
18
/*------------------------------------------------
DS5000 SCON Bit Registers
------------------------------------------------*/
sbit RI = 0x98;
sbit TI = 0x99;
sbit RB8 = 0x9A;
sbit TB8 = 0x9B;
sbit REN = 0x9C;
sbit SM2 = 0x9D;
sbit SM1 = 0x9E;
sbit SM0 = 0x9F;
/*------------------------------------------------
DS5000 P2 Bit Registers
------------------------------------------------*/
sbit P2_0 = 0xA0;
sbit P2_1 = 0xA1;
sbit P2_2 = 0xA2;
sbit P2_3 = 0xA3;
sbit P2_4 = 0xA4;
sbit P2_5 = 0xA5;
sbit P2_6 = 0xA6;
sbit P2_7 = 0xA7;
/*------------------------------------------------
DS5000 IE Bit Registers
------------------------------------------------*/
sbit EX0 = 0xA8;
sbit ET0 = 0xA9;
sbit EX1 = 0xAA;
sbit ET1 = 0xAB;
sbit ES = 0xAC;
sbit EA = 0xAF;
/*------------------------------------------------
DS5000 P3 Bit Registers (Mnemonics & Ports)
------------------------------------------------*/
sbit RD = 0xB7;
sbit WR = 0xB6;
sbit T1 = 0xB5;
sbit T0 = 0xB4;
sbit INT1 = 0xB3;
sbit INT0 = 0xB2;
sbit TXD = 0xB1;
sbit RXD = 0xB0;
sbit P3_0 = 0xB0;
sbit P3_1 = 0xB1;
sbit P3_2 = 0xB2;
sbit P3_3 = 0xB3;
sbit P3_4 = 0xB4;
sbit P3_5 = 0xB5;
sbit P3_6 = 0xB6;
sbit P3_7 = 0xB7;
AN162
19
/*------------------------------------------------
DS5000 IP Bit Registers
------------------------------------------------*/
sbit PX0 = 0xB8;
sbit PT0 = 0xB9;
sbit PX1 = 0xBA;
sbit PT1 = 0xBB;
sbit PS = 0xBC;
sbit RWT = 0xBF;
/*------------------------------------------------
DS5000 MCON Bit Values
------------------------------------------------*/
#define SL_ 0x01
#define PAA_ 0x02
#define ECE2_ 0x04
#define RA32_8_0x08
#define PA0_ 0x10
#define PA1_ 0x20
#define PA2_ 0x40
#define PA3_ 0x80
/*------------------------------------------------
DS5000 PSW Bit Registers
------------------------------------------------*/
sbit P = 0xD0;
sbit OV = 0xD2;
sbit RS0 = 0xD3;
sbit RS1 = 0xD4;
sbit F0 = 0xD5;
sbit AC = 0xD6;
sbit CY = 0xD7;
/*------------------------------------------------
Interrupt Vectors:
Interrupt Address = (Number * 8) + 3
------------------------------------------------*/
#define IE0_VECTOR 0 /* 0x03 */
#define TF0_VECTOR 1 /* 0x0B */
#define IE1_VECTOR 2 /* 0x13 */
#define TF1_VECTOR 3 /* 0x1B */
#define SIO_VECTOR 4 /* 0x23 */
#define PFW_VECTOR 5 /* 0x2B */
/*------------------------------------------------
------------------------------------------------*/
#endif
次のステップ
EE-Mail EE-Mail配信の登録申し込みをして、興味のある分野の最新ドキュメントに関する自動通知を受け取る。
© , Maxim Integrated Products, Inc.
このウェブサイトのコンテンツは米国および各国の著作権法によって保護されています。コンテンツの複製を希望される場合は お問い合わせください。.
APP 162:
アプリケーションノート 162,AN162, AN 162, APP162, Appnote162, Appnote 162