DAC0808 不想转模拟

DAC0808 doesn't want tranfer to analog

我的讲座给了我们 DAC 实验室。他要求从 Arduino 制作一个 8 位的锯齿波,然后将其连接到 DAC0808 以通过放大器产生模拟信号。所以我们做了一个电路。检查了它。有用。然后开始做计算和预期的结果。我们已经做到了。最后我们用接线语言编写程序。我想更进一步,制作了一个程序,它接受来自串行的不同输入并改变波形类型。但是当我们出于某种原因试图检查工作电路时它不想工作。我检查了 8 个 LED 上的程序,它们都工作得很好。但是我们把我的 ecircuit 放在示波器上,当它应该有 0 或 5 伏时,它显示 9.7 伏。这些位仍然进入 DAC 输入,但 DAC 没有将它们转换为模拟输出。

讲师确定问题出在我的复杂问题上,而不是我的电路或处理器上,但我注意到非常奇怪的电压输出。当我用万用表触摸 DAC 上的高输入电压时,它会给出该值。他仍然认为代码有问题,因为他的简单版本有效。 :c

代码:

    //Global Variables
enum wave {SAWTOOTH = 49, TRIANGLE, SQUARE, SINE, TANGENT};
int incomingByte;
int lastState = 0;
int calcResult;
int binaryOutput;
int triangleCheck;
int squareCheck;
int squareCount;
int sineOutput;
int tangentOutput;
int pin[8];

//Prototypes
int bitConversion(int);

//Setup
void setup() {
  Serial.begin(250000);
  for (int i = 2; i < 10; i++)
  {
    pinMode(i, OUTPUT);
    pin[i - 2] = i;
  }
}

void loop() {
  if (Serial.available())
    incomingByte = (int)Serial.read();

  Serial.print("Incoming Byte: ");
  Serial.write(incomingByte);
  Serial.println();
  Serial.print("Last State: ");
  Serial.write(lastState);
  Serial.println();

  if (incomingByte != lastState)
  {
    lastState = incomingByte;
    calcResult = 0;
    triangleCheck = 0; 
    squareCheck = 0;
    squareCount = 0;
    sineOutput = 0;
    tangentOutput = 0;
    Serial.println("State changed!");
  }

  Serial.print("STATE:                 ");
  switch (lastState)
  {
    case (SAWTOOTH):
      Serial.println("SAWTOOTH WAVE");
      Serial.println("------------------------------------------");
      if (calcResult == 255)
        calcResult = 0;
      calcResult++;
      break;

    case (TRIANGLE):
      Serial.println("TRIANGLE WAVE");
      Serial.println("------------------------------------------");
      if (calcResult == 255 || !calcResult)
      {
        Serial.println("Triangle changed!");
        Serial.println();
        triangleCheck++;
      }
      if ((triangleCheck % 2))
      {
        Serial.print("ODD   ");
        calcResult++;
      }
      else
      {
        Serial.print("EVEN  ");
        calcResult--;
      }   
      break;

    case (SQUARE):
      Serial.println("SQUARE WAVE");
      Serial.println("------------------------------------------");
      if (squareCount == 255 || squareCount == 0)
      {
        Serial.println("Square changed!");
        Serial.println();
        squareCheck++;
      }
      if ((squareCheck % 2))
      {
        Serial.print("ODD   ");
        calcResult = 0;
        squareCount++;
      }
      else
      {
        Serial.print("EVEN  ");
        calcResult = 255;
        squareCount--;
      }
      break;

    case (SINE):
      Serial.println("SINE WAVE");
      Serial.println("------------------------------------------");
      calcResult = 128+128*sin(2*PI*100*(sineOutput/10000.0));
      sineOutput++;
      break;

    case(TANGENT):
      Serial.println("TANGENT WAVE");
      Serial.println("------------------------------------------");
      calcResult = 128+64*tan(2*PI*100*(tangentOutput/10000.0));
      tangentOutput++;
      break;

    default:
      Serial.println("DEFAULT");
      Serial.println("------------------------------------------");
      calcResult = 0;
      break;
  }

  binaryOutput=calcResult;
  Serial.print("Binary Output: ");
  Serial.println(binaryOutput, DEC); 

  if (binaryOutput)
  {
    for (int i = 7; i >= 0; i--)
    {
      if (binaryOutput >= bitConversion(i))
      {
        digitalWrite(pin[i], HIGH);
        binaryOutput -= bitConversion(i);
        Serial.print(1);
        Serial.print(" ");
      }
      else
      {
        digitalWrite(pin[i], LOW);
        Serial.print(0);
        Serial.print(" ");
      }
    }
  }

  else
  {
    for (int i = 7; i >= 0; i--)
    {
      pinMode(pin[i], LOW);
      Serial.print(0);
      Serial.print(" ");
    }
  }
  Serial.println("\n\n");
  delay(50);
}

int bitConversion(int n)
{
  int result = 1;
  for (int i = 0; i<n; i++)
    result *= 2;
  return result;

}

关于您项目的一些事情

  1. 对于波形发生器,在主循环中生成信号不是一个好主意。正确的方法是使用定时器和计数器(必要时可以中断)。这是因为在数字信号发生器中,采样频率和波形频率很重要,而在主回路中生成波形可能会产生延迟,从而改变频率。使用计数器,您还可以控制输出信号的频率。

    顺便说一下,您可以按照自己的方式进行操作,但正如我所说,它有其局限性。

  2. 因为您使用 8 位作为输出并且用 calcResult 变量表示,也许您可​​以考虑将其设为 byteunsigned char(两者基本相同)

  3. 在正弦波的 calcResult 计算中,它说 calcResult = 128+128*sin(2*PI*100*(sineOutput/10000.0)) 但它应该是 calcResult = 128+127*sin(2*PI*100*(sineOutput/10000.0)) 因为其他方式你将有 calcResult=256有时。

  4. 变量triangleCheck一直在增加,这会导致你溢出。尽管这也可以为您提供正确的行为,但使用取值 0 和 1 的布尔值或字符是更好的方法。 squareCheck.

    也会发生这种情况
  5. 您似乎在主循环的所有迭代中打印有关 incomingByte 的文本,我认为这可能很烦人(并且还占用处理能力)。

  6. 看一下切线波,我在正弦波中提到的溢出也有同样的问题。您应该使用信号的周期性来执行此操作。您还应该考虑到切线是一个无界函数,因此它的值将超过您的 DAC 接受的 255。

  7. 对于你在最后一部分做的位转换,也许你可以用位掩码来完成。这样会更干净,更容易处理。

  8. 如果您不确定自己的 DAC,可以使用拨码开关进行测试。或者,如果可能的话,使用信号发生器,然后是 ADC,然后是 DAC,最后是示波器。这样您将 100% 确定您的 DAC 正在工作。

  9. 你测试过Arduino的输出了吗?您可以将带有电阻的 LED 连接到输出引脚,使用方波信号您应该会看到一些非常清晰的行为。

  10. 对于正弦波和正切波我建议看一下变量的转换(float to int)。也许关于它是如何完成的没有问题,但是确定您正在处理的信息是很好的。

希望这至少能对您的项目有所帮助。

您好!