FpgaI2c

概要

  • Nexys 4 付属のI2C温度計の SDA, SCL 信号線を直接スイッチで ON/OFFしながら、温度計を操作してみます。チャタリング防止や LED 表示などのため、ちょっと verilog で回路を作ります。
  • Nexys 4 付属の温度計, Analog Devices の ADT7420
    • 詳しい情報は以下の pdf に載っています。
    • ADT7420 をNexys 4 で使うとき、
      • Vivadoのxdcファイルの場合は、sclの PACKAGE_PIN は "F16", sdaの PACKAGE_PINは "G16" を指定します。 (Nexys4のマニュアルのpage 22, 12 Temperature Sensor で確認してください)
        ##Temperature Sensor
        ##Bank = 15, Pin name = IO_L14N_T2_SRCC_15,					Sch name = TMP_SCL
        set_property PACKAGE_PIN F16 [get_ports scl]					
        	set_property IOSTANDARD LVCMOS33 [get_ports scl]
        ##Bank = 15, Pin name = IO_L13N_T2_MRCC_15,					Sch name = TMP_SDA
        set_property PACKAGE_PIN G16 [get_ports sda]					
        	set_property IOSTANDARD LVCMOS33 [get_ports sda]
  • ISEのUCFの場合は、sclの LOCは "F16", sdaの LOCは "G16" を指定します。 (Nexys4のマニュアルのpage 22, 12 Temperature Sensor で確認してください)
    NET "scl"			LOC = "F16"	| IOSTANDARD = "LVCMOS33";		#Bank = 15, Pin name = IO_L14N_T2_SRCC_15,					Sch name = TMP_SCL
    NET "sda"			LOC = "G16"	| IOSTANDARD = "LVCMOS33";		#Bank = 15, Pin name = IO_L13N_T2_MRCC_15,					Sch name = TMP_SDA
  • ADT7420 の(slave)device addressは、0x4b (=1001011) です。
  • 温度データを取り出すには、以下の手順を実行します。
    • Master がStart 信号を送信。... scl=1, sda=1の状態から、scl=1, sda=0 の状態にして、その後、scl=0, sda=0 とする。
    • これ以降、通信を終了するまで、Master またはdeviceが sda に high(=Z=1)または low(=0)を設定し、その状態で、Master が sclを 0->1->0 に変化することを繰り返す。
    • Master がdevice(ADT7420)のアドレス(0x4b)と、Masterからデータが送信されることを表す 0 (レジスタ番号書き込み)を送信。
    • device が ack 信号(成功していれば、0)を出力。 Master側ではこのとき、 sda 端子をZ状態(=1)として、入力を待つ。
    • Master がレジスタを表す 8bitのデータ(0000 0000)を出力。
    • device が ack 信号 0 を出力
    • Master がrestart 信号を送信(start と同じ)
    • Master が device address (0x4b)と、入力を表す 1を出力。
    • device が ack 信号 0 を出力
    • device が 最初の 8 bit を出力... この時のbit 列を Master 側で入力。
    • Master が ack 0 を出力。
    • device が次の8 bit を出力 ... この時の bit 列を Master 側で入力。
    • Master が nack 1 を出力。
    • 通信終了手順を行う。 ... sclを 1 にして、その間に sdaを 0から 1 にする。

回路の概要

  • sw[7:0]と up button, left button, center button, right button をチャタリング防止回路に通し、その出力をswx[7:0], BUx, BLx, BCx, BRx とします。
  • sw[0]をチャタリング防止回路を通して(swx[o]), sda に接続します。
  • center button をチャタリング防止回路を通して(BCx), sclに接続します。
  • down button をリセット信号とします。
  • sda を led[8] に接続します。scl が 0->1 に変化するたびに、これをシフトして、過去8回のsda の High/Low の遷移を led[15:8] に表示します。 これを実現するために、レジスタ data[7:0] を使っています。
  • 1つのポートで入出力を行う為、scl, sda は verilog の inout 型を使います。
  • data[7:0]の値を16進法4桁でLEDマトリックスの左側4個に出力する回路に接続します。
  • sw[7:0]をled[7:0]に接続します。
  • sw[7:0]を16進法4桁でLEDマトリックスの右側4個に出力する回路に接続します。
  • 回路図
    • i2c-1-circuit.jpg

Verilog と xdc または ucf

  • ソース: i2c-thermo-verilog-xdc
  • Vivadoの画面の例 (ISEの場合はisc-thermo-ise?)
    • 入力終了後の状態(上のverilog のコピペで良いです)
      • i2c_thermo-1.png

verilog のコンパイルと bit ファイルの作成

  • Run systhesis をクリック
    • i2c-thermo-run-synthesis.png
  • Run Implementation ... ポップアップウィンドウで指定, 左側のメニュー一覧から選んでもよい.
    • i2c-therm-synthesis-2.png
  • bitファイルの生成,Generate bit stream
    • i2c_thermo-generate-bitstream-1.png

Nexys4とパソコンの接続, bit ファイルのダウンロード

  • bitファイル生成後, ポップアップウィンドウが開きます. Open Hardware Manager を選びます。ここでは OKはクリックしません.
    • i2c-thermo-open-hw-manager-2.png
  • パソコンとNexys4を接続します.
    • i2c-1-7-s.jpg
  • ポップアップウィンドウのOKをクリックします.
    • Hardware Managerの Open Tagert が click 可能になります。
      • i2c-thermo-open-manager-0.png
  • Open Taget を click し, auto connect をクリックします。 
    • i2c-therm-hw-manager-auto-connect.png
  • Program Device をクリックします。
    • i2c-thermo-hw-manager-program-device.png
  • プログラム可能なデバイス名(xc7a100t)が表示されます。これをクリックします。
    • i2c-thermo-hw-manager-program-device-2.png
  • プログラム(download)するbitファイルの候補が表示されるので、確認して、programボタンをクリックします。
    • i2c-thermo-hw-manager-program-device-3.png
  • ダウンロードが終了すると、ボードの7セグメントLEDに"0000 0000"が表示される(スライドスイッチがすべてOffの場合)。
    • i2c-1-19-s.jpg 
      (スライドスイッチ 0 がONになっているので、左端が1になっています。)

実行

  • 手順詳細
    • bitファイルのダウンロード終了時点で、自動的に回路に電源が供給されて、回路が動き始めます。
    • sw[0](sda) を1にします。center button (scl)は、押していない時に0, 押したときに 1 になります。
    • sclを1 にして、sda を 1->0にします。(center button を1にして、その状態のまま, sw[0]を1から0にする)
    • sclを0にします。(center buttonを離す)
    • sdaを1にして、sclを 0->1->0にします。(sw[0]を1にして、center button を押して離す)... これで device の7bit のアドレスのMSBの1bit がデバイス側に送られます。
    • sdaを0にして、sclを 0->1->0にします。
    • sdaを0のまま、sclを 0->1->0にします。
    • sdaを1にして、sclを 0->1->0にします。
    • sdaを0にして、sclを 0->1->0にします。
    • sdaを1にして、sclを 0->1->0にします。
    • sdaを1のまま、sclを 0->1->0にします。ここまでが、ADT7420のアドレス, 0x4bの出力です。
    • sdaを0にして、sclを 0->1->0にします。write (=0)の出力です。
    • sdaを1(Z)にして、sclを0->1->0にします。ADT7420から ack(=0)が出力され、led[8]に表示されるはずです。
    • sdaを0にして、sclを8回、0->1->0にします。 ... register 0の指定です。
    • sdaを1(Z)にして、sclを0->1->0にし、ADT7420から ackを入力します。
    • sdaを1のまま、sclを1にします。
    • sclを1のまま、sdaを0にして、restart します。そのあと、sclを0にします。
    • sdaを1にして、sclを 0->1->0にします。
    • sdaを0にして、sclを 0->1->0にします。
    • sdaを0のまま、sclを 0->1->0にします。
    • sdaを1にして、sclを 0->1->0にします。
    • sdaを0にして、sclを 0->1->0にします。
    • sdaを1にして、sclを 0->1->0にします。
    • sdaを1のまま、sclを 0->1->0にします。ADT7420のアドレス, 0x4bの再出力です。
    • sdaを1にして、sclを 0->1->0にします。read (=1)の出力です。
    • sdaを1のまま、sclを 0->1->0にし、ADT7420からackを入力します。
    • sdaを1のまま、sclを8回 0->1->0します。このとき、ADT7420から温度データが送られてきて、それが、led[8]から入力され、右にシフトされます。最初の bit は、符号を表します。符号を含む最初の8bitは、全16bitのMSB側の8bitです。
    • sdaを0にして、sclを 0->1->0にして、Master から ADT7420へ ack (0)を送ります。
    • sdaを1にして、そのまま、sclを8回 0->1->0します。このとき、ADT7420から温度データの下位8bitが送られてきて、それが、led[8]から入力され、右にシフトされます。入力された全16bitのうち、符号を除く上位8bit、(つまり、最初の1byte(8bit)のうち、2番目以降の7bit と、次に入力された1byte の最初の1bit )が、摂氏で表した温度の整数部分を表します。
    • 最後に、sdaを0, sclを1, そのまま sdaを1, にすることによって、通信終了信号がMaster からADT7420へ送られます。これで一通りのサイクルが終了します。

  • 実際に操作しているところの動画です。
  • 説明
    • 最初のスイッチの操作 ... I2C通信開始信号送信
      • center button を押して sclを 1にして、押したままにしておく。
        i2c-1-23.jpg
      • スライドスイッチをOffからONにして, sdaを1にする。
        i2c-1-24.jpg
      • スライドスイッチをONからOFFにする。
        i2c-1-25.jpg
    • アドレスの送信の最初の部分
      • sclを0にしたあと, sdaを1にして、sclを 0->1->0
        i2c-1-26.jpg
      • led[8]が点灯(1がsdaに流れたことを示す)。
        i2c-1-27.jpg
    • 再スタート, アドレス指定, 読み込みbit (1)送信, ack受信(0)受信の後, 最初に読み込んだ8bitのデータが 00010000
      • i2c-1-r-data-2.jpg
    • 次の8bit が, 11010000
      • i2c-1-r-data-3.jpg
    • この2つの01の列を接続した16bitの値が計測された温度です。最初の1bitは符号で、そのあとの8bit が摂氏で表した温度の小数点より大きいあたい、残りが、小数点より小さい値です。
    • 従って、0010 0001 が摂氏の小数点より大きい値となり、摂氏33度であることがわかります(ボードの熱で、ちょっと高い温度になるようです)。小数点以下の部分は、101なので 1/2 + 1/8=0.5+0.125=0.625となり、整数部分に加えると、33.625度、ということになります。
      • 実際に赤外線温度計で計測すると、摂氏33.6度となっており、かなり近い値が計測されていることが確認できます。
      • i2c-1-28.jpg

考察

  • 手でI2Cデバイスを制御するのは大変。ちょっと間違えたら1からやり直し。
  • tinyCPUを作ったのだから、それを使って、プログラムで制御したらいいじゃん。

Counter: 6439, today: 1, yesterday: 1

添付ファイル: filei2c-thermo-open-manager-0.png 344件 [詳細] filei2c-thermo-open-hw-manager-2.png 397件 [詳細] filei2c_thermo-generate-bitstream-1.png 347件 [詳細] filei2c-therm-synthesis-2.png 390件 [詳細] filei2c-thermo-open-hw-manager-.png 236件 [詳細] filei2c-thermo-menu.png 167件 [詳細] filei2c-thermo-hw-manager-program-device-3.png 326件 [詳細] filei2c-thermo-hw-manager-program-device-2.png 334件 [詳細] filei2c-thermo-hw-manager-program-device.png 323件 [詳細] filei2c-therm-implementation-1.png 172件 [詳細] filei2c-therm-hw-manager-auto-connect.png 377件 [詳細] filei2c_thermo-add-xdc.png 121件 [詳細] filei2c_thermo-add-v-3.png 135件 [詳細] filei2c_thermo-add-v-2.png 137件 [詳細] filei2c_thermo-add-v.png 149件 [詳細] filei2c-thermo-run-synthesis.png 401件 [詳細] filei2c_thermo-1.png 627件 [詳細] filei2c-1-28.jpg 432件 [詳細] filei2c-1-r-data-3.jpg 356件 [詳細] filei2c-1-r-data-2.jpg 402件 [詳細] filei2c-1-27.jpg 435件 [詳細] filei2c-1-26.jpg 450件 [詳細] filei2c-1-25.jpg 377件 [詳細] filei2c-1-24.jpg 449件 [詳細] filei2c-1-23.jpg 381件 [詳細] filei2c-1-19-s.jpg 437件 [詳細] filei2c-1-18.jpg 397件 [詳細] filei2c-1-17.jpg 389件 [詳細] filei2c-1-16.jpg 415件 [詳細] filei2c-1-14.jpg 400件 [詳細] filei2c-1-13.jpg 377件 [詳細] filei2c-1-12.jpg 422件 [詳細] filei2c-1-11.jpg 399件 [詳細] filei2c-1-10.jpg 435件 [詳細] filei2c-1-9.jpg 418件 [詳細] filei2c-1-7-s.jpg 668件 [詳細] filei2c-1-circuit.jpg 766件 [詳細] filei2c-1-8.jpg 467件 [詳細] filei2c-1-6.jpg 451件 [詳細] filei2c-1-5.jpg 203件 [詳細] filei2c-1-4.jpg 443件 [詳細] filei2c-1-3.jpg 502件 [詳細] filei2c-1-2.jpg 427件 [詳細] filei2c-1-1.jpg 504件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-08-27 (日) 21:08:35 (2426d)