这个Arduino代码有什么作用

What does this Arduino code do?

本文关键字:什么 作用 代码 Arduino 这个      更新时间:2023-10-16

我明白其中大部分在做什么,但是,

    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;
}

数字阅读

从指定的数字引脚读取值,高电平或低电平。

<小时 />
MISO(主站从站出):主站移位寄存器的

输入,以及从站移位寄存器的输出。

SPI 概述

<小时 />

| 是按位 OR 运算符。

d |= 1是 的简写符号

d = d | 1

如果条件为 true,则此代码将 d 的最后一位设置为 1。

<小时 />

所以你正在做的是读取从属寄存器的输出,如果它是1,它将d的最后一位设置为1。就在该行之前,它d d <<= 1;向左移动了一位。它在一个循环中执行此操作:

  • 向左移动 1 位d
  • 阅读味噌,如果是1,将d的最低有效位设置为 1
  • 重复

MISO是SPI总线上的主输入/从输出引脚。在此代码中,您扮演的是主站的角色,因此这是您从从站读取输入的引脚。d |= 1 只是将 d 中的最后一位设置为 1,如果它从从站读取 1(所有其他位将不受影响)。如果每次迭代,如果读取 1,它将 d 的最后一个 (LSB) 位设置为 1,然后在下一次迭代开始时将 d 向左移动。

我对这个 API 完全没有经验,但是......

如果您查看 digitalRead() 文档,该函数所做的只是读取您作为参数提供的引脚上的位。它返回 HIGHLOW

所以基本上,我看到的是:如果miso位打开,则d打开第一个位。