2

これのほとんどが何をしているのかは理解していますが、

    if (digitalRead(miso)) {      d |= 1;    }

よくわからないセリフです。このコードは、Arduino ボードに使用される Adafruit MAX31855 ライブラリからのものです。コードを c の C8051F020 MCU に移植しようとしています。このコードは熱電対から読み取り、MAX31855 は MCU へのデジタル インタフェースです。このファイルのコード全体を次に示します。に詳しくありませんdigitalRead()。上記のifステートメントは、私が解釈できていないところです。この if ステートメントはuint32_t Adafruit_MAX31855::spiread32(void)関数内にあります。

        /*************************************************** 
  This is a library for the Adafruit Thermocouple Sensor w/MAX31855K

  Designed specifically to work with the Adafruit Thermocouple Sensor
  ----> https://www.adafruit.com/products/269

  These displays use SPI to communicate, 3 pins are required to  
  interface
  Adafruit invests time and resources providing this open source code, 
  please support Adafruit and open-source hardware by purchasing 
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution
 ****************************************************/

#include "Adafruit_MAX31855.h"
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <stdlib.h>


Adafruit_MAX31855::Adafruit_MAX31855(int8_t SCLK, int8_t CS, int8_t MISO) {
  sclk = SCLK;
  cs = CS;
  miso = MISO;

  //define pin modes
  pinMode(cs, OUTPUT);
  pinMode(sclk, OUTPUT); 
  pinMode(miso, INPUT);

  digitalWrite(cs, HIGH);
}


double Adafruit_MAX31855::readInternal(void) {
  uint32_t v;

  v = spiread32();

  // ignore bottom 4 bits - they're just thermocouple data
  v >>= 4;

  // pull the bottom 11 bits off
  float internal = v & 0x7FF;
  internal *= 0.0625; // LSB = 0.0625 degrees
  // check sign bit!
  if (v & 0x800) 
    internal *= -1;
  //Serial.print("\tInternal Temp: "); Serial.println(internal);
  return internal;
}

double Adafruit_MAX31855::readCelsius(void) {

  int32_t v;

  v = spiread32();

  //Serial.print("0x"); Serial.println(v, HEX);

  /*
  float internal = (v >> 4) & 0x7FF;
  internal *= 0.0625;
  if ((v >> 4) & 0x800) 
    internal *= -1;
  Serial.print("\tInternal Temp: "); Serial.println(internal);
  */

  if (v & 0x7) {
    // uh oh, a serious problem!
    return NAN; 
  }

  // get rid of internal temp data, and any fault bits
  v >>= 18;
  //Serial.println(v, HEX);

  // pull the bottom 13 bits off
  int16_t temp = v & 0x3FFF;

  // check sign bit
  if (v & 0x2000) 
    temp |= 0xC000;
  //Serial.println(temp);

  double centigrade = v;

  // LSB = 0.25 degrees C
  centigrade *= 0.25;
  return centigrade;
}

uint8_t Adafruit_MAX31855::readError() {
  return spiread32() & 0x7;
}

double Adafruit_MAX31855::readFarenheit(void) {
  float f = readCelsius();
  f *= 9.0;
  f /= 5.0;
  f += 32;
  return f;
}

uint32_t Adafruit_MAX31855::spiread32(void) { 
  int i;
  uint32_t d = 0;

  digitalWrite(sclk, LOW);
  _delay_ms(1);
  digitalWrite(cs, LOW);
  _delay_ms(1);

  for (i=31; i>=0; i--)
  {
    digitalWrite(sclk, LOW);
    _delay_ms(1);
    d <<= 1;
    if (digitalRead(miso)) {
      d |= 1;
    }

    digitalWrite(sclk, HIGH);
    _delay_ms(1);
  }

  digitalWrite(cs, HIGH);
  //Serial.println(d, HEX);
  return d;
}
4

3 に答える 3

8

デジタル読み取り

HIGH または LOW のいずれかの指定されたデジタル ピンから値を読み取ります。


MISO (Master In Slave Out): マスターのシフト レジスタの入力、およびスレーブのシフト レジスタの出力。

SPI の概要


|ビットごとの OR 演算子です。

d |= 1の省略表記です

d = d | 1

dこのコードは、条件が真の場合、の最後のビットを 1 に設定します。


つまり、スレーブ レジスタの出力を読み取り、それが 1 の場合は、 の最後のビットをd1 に設定します。その行の直前で、 でd1 ビット左にシフトしd <<= 1;ます。そして、これをループで実行します。

  • d左に1ビットシフト
  • miso を読み取り、 の場合は の1最下位ビットを に設定d1ます。
  • 繰り返す
于 2012-10-13T02:02:40.883 に答える
2

MISO は、SPI バスのマスター イン/スレーブ アウト ピンです。このコードでは、マスターの役割を果たしているため、スレーブからの入力を読み取るピンです。d |= 1 は、スレーブから 1 を読み取った場合に d の最後のビットを 1 に設定するだけです (他のすべてのビットは影響を受けません)。反復ごとに、1 を読み取った場合は d の最後の (LSB) ビットを 1 に設定し、次の反復の開始時に d を左にシフトします。

于 2012-10-13T02:01:14.703 に答える
0

しかし、私はこの API の経験がまったくありません...

digitalRead()のドキュメントを見ると、関数は引数として指定したピンのビットを読み取るだけです。HIGHまたはのいずれかを返しますLOW

つまり、基本的には、misoビットがオンの場合、最初のビットをdオンにします。

于 2012-10-13T02:02:17.437 に答える