我的讲座给了我们DAC实验室。他要求从Arduino产生8位锯齿波形,然后连接DAC0808以产生带放大器的模拟信号。所以我们制作了一个电路。检查了它。有用。然后开始做计算和预期结果。我们已经做到了。最后我们用布线语言编写程序。我想更进一步,制作一个程序,接受来自串行的不同输入并改变波形类型。但是当我们试图检查工作电路的某些原因时,它不想工作。我在8 LED上检查了程序,他们都完美无缺。但我们把它放在ecircuit并检查振荡器它显示9.7伏特它应该有0或5伏特。这些位仍然用于DAC输入,但DAC没有将它们转换为模拟输出。
讲师确定问题出在我的复杂问题中,而不是在我的电路中,或者可能在我的处理器上,但我注意到电压输出非常奇怪。当我用万用表触摸DAC上的HIGH输入电压时,它会输出该值。他仍然认为这是代码的问题,因为他的简单版本有效。 :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;
}
答案 0 :(得分:1)
关于项目的一些事情
对于波形发生器,在主循环中生成信号不是一个好主意。正确的方法是使用计时器和计数器(如果有必要,可以使用中断)。这是因为在数字信号发生器中,采样频率和波频率很重要,并且在主环路中产生波可能会产生改变频率的延迟。使用计数器,您还可以控制输出信号的频率。
顺便说一下,你可以按照你的方式做到这一点但正如我所说,它有其局限性。
因为您使用8位作为输出并且使用calcResult
变量表示,所以您可以考虑将其设为byte
或unsigned char
(两者都是基本相同)。
在正弦波的calcResult
计算中,它显示calcResult = 128+128*sin(2*PI*100*(sineOutput/10000.0))
但它应该是calcResult = 128+127*sin(2*PI*100*(sineOutput/10000.0))
,因为其他方式有时会calcResult=256
。< / p>
变量triangleCheck
总是在增加,这会导致溢出。虽然这也可以为您提供正确的行为,但它是使用布尔值或取0和1值的char的更好方法。这也发生在squareCheck
。
您似乎正在打印有关incomingByte所有主循环迭代的文本,我认为这可能很烦人(并且还需要处理能力)。
看看切线波,我在正弦波中提到的溢出问题也存在同样的问题。您应该使用信号的周期来执行此操作。您还应该考虑切线是一个无界函数,因此它将具有超过您的DAC接受的255的大量值。
对于您在最后一部分中进行的位转换,也许您可以使用位掩码进行。这将更清洁,更容易处理。
如果您对DAC不确定,可以使用DIP开关进行测试。或者,如果您有可能,请使用信号发生器,然后使用ADC,然后使用DAC,最后使用示波器。通过这种方式,您可以100%使用DAC。
您是否测试过Arduino的输出?您可以通过对输出引脚的电阻来连接LED,并且使用方波信号,您应该看到一些非常清晰的行为。
对于sin波和切线波,我建议看一下变量的转换(float to int)。也许没有关于它是如何完成的问题,但确定你正在处理的信息是好的。
希望这至少可以帮助您完成项目。
问候!