【发布时间】:2020-11-12 12:47:30
【问题描述】:
我正在使用 Arduino Mega 来控制 CS1237 ADC。根据我找到的datasheet(通过https://github.com/SiBangkotan/CS1237-ADC-cpp-library),我正在向时钟引脚发送一个信号,并在每个时钟脉冲之后等待1ms,然后读取响应。这似乎在某种程度上起作用,因为当我为接收到的每个位和结果数据字执行Serial.println() 时,我得到一个与我得到的 24 个单独位匹配的 24 位数据字。但是,当我取出Serial.println() 的额外调试用途时,它会在收到每个位时打印它们,我也会得到一个不同的数据字。每次都是全 1 的 20 位,而不是各种 1 和 0 的 24 位。我不明白为什么串行通信通道中的这个额外的调试输出会改变进入串行监视器的数据字?
这是我的设置和预设置代码:
// Using pins 2 and 3 on the Arduino, since 0 and 1 are used to talk to the USB port.
int ndrdy = 2;
int clck = 3;
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// make the drdy's pin an input and clock an output:
pinMode(ndrdy, INPUT);
}
以下是相关代码:
void loop() {
// Hacky way of waiting for the signal that !DRDY is ready.
while(digitalRead(ndrdy) == LOW) {
// do nothing until pin pulls high.
}
while(digitalRead(ndrdy) == HIGH) {
// keep doing nothing until pin goes low again.
}
// now data is ready, we can read
long dataword = 0;
for(int i = 0; i < 24; i++) {
digitalWrite(clck, HIGH);
delayMicroseconds(1);
digitalWrite(clck, LOW);
int new_bit = digitalRead(ndrdy);
dataword <<= 1; // shift everything one place to the left
dataword |= new_bit; // add the new bit to the newly empty place
}
// There's a total of 27 bits but we don't care about the last 3.
// Write HIGH 3 times to flush it out.
for (int i = 0; i < 3; i++) {
digitalWrite(clck, HIGH);
delayMicroseconds(1);
digitalWrite(clck, LOW);
}
// Send out the data to the USB serial out:
Serial.println(dataword, BIN);
}
这个在串口监视器中的输出是
13:44:45.685 -> 11111111111111111111
13:44:45.685 -> 11111111111111111111
13:44:45.718 -> 11111111111111111111
13:44:45.751 -> 11111111111111111111
13:44:45.751 -> 11111111111111111111
13:44:45.785 -> 11111111111111111111
13:44:45.818 -> 111111111111111111111
13:44:45.852 -> 11111111111111111111
13:44:45.852 -> 11111111111111111111
13:44:45.885 -> 11111111111111111111
13:44:45.918 -> 111111111111111111111
13:44:45.918 -> 11111111111111111111
13:44:45.951 -> 11111111111111111111
...等等。但是,当我在 for(int i = 0; i < 24; i++) 循环的右括号之前添加一个额外的 Serial.println(new_bit); 时,我在 Arduino IDE 的串行监视器中得到这样的输出(显示打开时间戳):
14:41:19.992 -> 0
14:41:19.992 -> 1
14:41:19.992 -> 1
14:41:19.992 -> 1
14:41:19.992 -> 1
14:41:19.992 -> 1
14:41:19.992 -> 1
14:41:19.992 -> 1
14:41:19.992 -> 1
14:41:19.992 -> 0
14:41:19.992 -> 1
14:41:20.025 -> 1
14:41:20.025 -> 1
14:41:20.025 -> 1
14:41:20.025 -> 1
14:41:20.025 -> 0
14:41:20.025 -> 0
14:41:20.025 -> 1
14:41:20.025 -> 1
14:41:20.025 -> 1
14:41:20.025 -> 1
14:41:20.025 -> 1
14:41:20.058 -> 0
14:41:20.058 -> 1
14:41:20.058 -> 11111111011111001111101
14:41:20.091 -> 0
14:41:20.091 -> 1
14:41:20.091 -> 1
14:41:20.091 -> 1
14:41:20.091 -> 1
14:41:20.091 -> 1
14:41:20.091 -> 1
14:41:20.091 -> 1
14:41:20.091 -> 1
14:41:20.091 -> 0
14:41:20.125 -> 1
14:41:20.125 -> 1
14:41:20.125 -> 1
14:41:20.125 -> 1
14:41:20.125 -> 1
14:41:20.125 -> 0
14:41:20.125 -> 0
14:41:20.125 -> 1
14:41:20.125 -> 1
14:41:20.125 -> 1
14:41:20.125 -> 1
14:41:20.158 -> 1
14:41:20.158 -> 0
14:41:20.158 -> 1
14:41:20.158 -> 11111111011111001111101
如果我在Serial.println()-ing 该行上的new_bit 以外的任何内容,例如如果我执行Serial.println(dataword); 或者如果我引入一个小延迟而不是执行串行打印,则不会发生这种情况。在这些情况下,它仍然会输出 21 的输出。我不知道串行通信出了什么问题,因为从 ADC 读取似乎一切正常。如果我引入 5000us 或更多的延迟,那么dataword 的内容就会发生变化,这似乎成为延迟长度的函数。 IE。 dataword 的内容对于每个延迟长度都是恒定的(我尝试过 5000us、6000us、10000us 和 20000us)。如果延迟足够长,它会回到全 1。
【问题讨论】:
-
如果不是将 Serial.println(new_bit) 放在 for() 循环的右括号之前,而是放置一个小延迟,会发生什么?
-
对于
clck信号的bitbanging,您使用delayMicroseconds(1)和digitalRead作为计时。最后 3 位缺少 clck 的 LOW 阶段的时序。这是否正常并符合预期? -
@ocrdu 将
Serial.println(new_bit);更改为无效;就好像那里什么都没有一样。将Serial.println(new_bit);更改为Serial.println(new_bit);与删除该行相同。 @datafiddler 只要我在从第一个 AFAICT 读取数据之前不发送另一个信号,clck信号的发送速度就无关紧要。这 1us 的延迟使我处于数据表中的最大时钟速度之内。 -
使其工作的 Serial.println() 引入了延迟。您很可能需要延迟 HIGH 和 LOW,而您现在只有一个。你试过了吗?
-
@ocrdu 是的,我尝试引入延迟。它没有任何效果。我在之前的评论中犯了一些奇怪的复制/粘贴错误,并没有及时注意到它进行编辑。但是是的,我确实尝试将
Serial.println(new_bit);更改为delayMicroseconds(1);,这就像我只是删除了Serial.println(new_bit);而没有替换任何东西一样。
标签: c++ arduino arduino-ide serial-communication adc