SPI Arduino เนื่องจากข้อขัดแย้งกับ pinMode (), ข้อผิดพลาด?


9

ลองพิจารณาตัวอย่างเล็กน้อยต่อไปนี้ที่ฉันตั้งค่าpinModeก่อนเรียกใช้ฟังก์ชัน SPI:

#include <SPI.h>

void setup() {
  pinMode(10, OUTPUT);
  SPI.begin(10);
  SPI.setDataMode(10,SPI_MODE1);
}

void loop() {
  delay(1000);
  SPI.transfer(10,1);
}

ตอนนี้เมื่อSPI.transfer(10,1)ถูกเรียกเข้าไปloop()ฉันเห็นเสมอว่าพินที่เลือกของทาสนั้นลดลงเหลือ 1.65V แต่ไม่ใช่ 0 เท่าที่ควร! (ดูภาพด้านล่าง)

ตั้งโหมดพินก่อนเรียกฟังก์ชั่น SPI

หากเราไม่โทรpinMode()เช่นนี้:

#include <SPI.h>

void setup() {
  SPI.begin(10);
  SPI.setDataMode(10,SPI_MODE1);
}

void loop() {
  delay(1000);
  SPI.transfer(10,1);
}

เราได้สิ่งที่เราคาดหวังเมื่อโทรSPI.transfer:

ไม่ได้ตั้งโหมด pin

นั่นเป็นข้อบกพร่องหรือคุณมีคำอธิบายสำหรับพฤติกรรมนั้นหรือไม่?

ขอบคุณล่วงหน้าสำหรับเวลาและความสนใจของคุณ!


มันไม่ควรจะเป็นSPI.setDataMode(10, SPI_MODE1);? นอกจากนี้เฉพาะอันที่สองเท่านั้นที่มีประโยชน์เช่นเดียวกับการbegin()เรียก setDataMode ดูซอร์สโค้ดดูเหมือนว่าไลบรารี SPI จะไม่เปลี่ยนพินที่คุณระบุ (แม้ว่าฉันไม่รู้ ARM)
Gerben

Ja คุณพูดถูกฉันบังเอิญโทรหา setDataMode () สองครั้ง พรุ่งนี้ฉันจะทดสอบผลของ SPI.setDataMode (10, SPI_MODE1); แต่ทำไมการโทร pinMode () ถึงมีผลกระทบนี้ยังไม่ชัดเจนหรือ? @Gerben
newandlost

@ Gerben ฉันแก้ไขโพสต์ของฉัน
newandlost

คำตอบ:


1

มันอาจมีบางอย่างเกี่ยวกับตัวต้านทานแรงดึงภายใน ตามแผ่นข้อมูล SAM3X / A

การควบคุมตัวต้านทานแบบดึงขึ้นเป็นไปได้โดยไม่คำนึงถึงการกำหนดค่าของสาย I / O

หลังจากรีเซ็ตแล้วพูลอัพทั้งหมดจะเปิดใช้งาน

หากคุณขุดไฟล์รวมทั้งหมดที่คุณพบ:

../Arduino/hardware/arduino/samd/cores/arduino/wiring_digtal.c

บรรทัดที่ 124 กำหนดpinMode(uint32_t ulPin, uint32_t ulMode)ฟังก์ชั่น ตรวจสอบคำสั่ง switch / case สำหรับ INPUT vs INPUT_PULLUP vs OUTPUT คุณจะเห็นสิ่งต่อไปนี้:

  1. INPUT reg = PORT_PINCFG_INENชุดลงทะเบียนกับ
  2. INPUT_PULLUP ตั้งค่าการลงทะเบียนเป็น reg = (PORT_PINCFG_INEN | PORT_PINCFG_PULLEN)
  3. OUTPUT reg &= ~PORT_PINCFG_INENชุดลงทะเบียนกับ

'ลงทะเบียน' ในแต่ละกรณีเหมือนกัน ฉันไม่สามารถใช้ชีวิตของฉันได้ว่าค่า PORT_PINCFG_INEN หรือ PORT_PINCFG_PULLEN มีค่าเท่าไร แต่พวกเขาไม่ต้องสงสัยเลยว่ามาส์กแบบ 8 บิต (จะถูกนำไปใช้กับ uint8_t เมื่อพวกมันถูกกำหนดให้เป็น 'register') ดังนั้นเราสามารถสรุปได้ว่าบิตใดที่ควบคุมอินพุต / เอาต์พุตจะถูกแอ็คทีฟเมื่อถูกยืนยันเช่นเดียวกับบิต pullup ตัวอย่างเช่น:

 PORT_PINCFG_INEN   = b'00000001';
 PORT_PINCFG_PULLEN = b'00000010';
~PORT_PINCFG_INEN   = b'11111110';

หากเปิดใช้งานการดึงขึ้นหลังจากรีเซ็ตเราสามารถพูดได้ว่าเมื่อรีเซ็ต:

 reg = b'xxxxxx1x';

จุด (3) ด้านบนแสดงนัยอย่างยิ่งว่าคำแนะนำคือ:

 reg = b'xxxxxx1x' & 'b11111110';
   so
 reg = b'xxxxxx10'; // pull-up is enabled!

ดังนั้นถ้าคุณเรียก pinMode (X, OUTPUT) ก่อนสิ่งอื่นใดคุณจะจบลงด้วยการเปิดใช้งานตัวต้านทานแบบดึงขึ้น การตั้งพินเป็นอินพุตจะล้างบิตการเปิดใช้งาน pullup หลังจากนั้นคุณสามารถตั้งพินเป็นเอาต์พุตและบิตจะยังคงชัดเจน

อย่างไรก็ตามการโต้แย้งทั้งหมดล้มลงด้วยความจริงง่ายๆที่ว่าถ้าคุณไม่เรียก pinMode () เลยปัญหาจะไม่เกิดขึ้น ...

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.