Arduino: ความละเอียดไมโครวินาทีที่ดีกว่าไมโคร ()?


11

เอกสารประกอบ micros () ตั้งข้อสังเกตว่าค่าส่งคืนจะเป็นผลคูณของ 4

มีวิธีใดบ้างที่จะได้รับการคลิกไมโครวินาทีความละเอียดสูงกว่าโดยเฉพาะอย่างยิ่งจนถึงระดับ 1 ไมโครวินาที

ปล่อยลงไปที่ระดับ AVR เป็นที่ยอมรับ


1
ทำไมคุณยืนยันที่จะเริ่มต้นชื่อของคุณด้วยแท็กเมื่อฉันทำให้มันเป็นคำถามที่สมบูรณ์แบบภาษาอังกฤษ?
stevenvh

4
ขอโทษสตีเวนฉันคิดอย่างจริงใจ (และคิดว่า) มันเป็นวิธีที่ดีในการแสดงคำถามรวบรัดและชัดเจน มีการถกเถียงกันมากมายเกี่ยวกับเรื่องนี้และเจฟฟ์ก็เห็นด้วยในบางกรณีว่ามันเป็นวิธีที่ดีในการถาม การสนทนาอยู่ที่นี่; heatmaps เป็นสิ่งที่ทำให้ฉันเชื่อมั่นว่าสำหรับคำถามสไตล์เหล่านี้มันจ่ายเพื่อเน้นสภาพแวดล้อมการทำงาน meta.stackexchange.com/questions/10647/writing-good-titles/ แต่ด้วยความเคารพสำหรับคำตอบที่ยอดเยี่ยมของคุณฉันยินดีที่จะเปลี่ยนกลับหากคุณคิดว่าดีที่สุด
Mark Harrison

เป็นไปได้ไหมที่จะใช้สำหรับฟังก์ชั่น pulsein ()? ฉันต้องวัดความยาวพัลส์ในความละเอียดและมากกว่า 1 usec

พื้นที่นี้สงวนไว้สำหรับคำตอบของคำถามที่อยู่ด้านบน หากคุณมีสิ่งที่ถามเริ่มคำถามของคุณเอง
Olin Lathrop

คำตอบ:


9

ใช่ขึ้นอยู่กับอัตรานาฬิกาพื้นฐานของ Arduino ตัวอย่างเช่นที่นี่เป็นความถี่อินพุตและตัวนับเวลานับถอยหลังหลังจากปรับขนาดล่วงหน้าสำหรับตัวนับเวลา 2 ของ ATMega2560 และอัตราสัญญาณนาฬิกาพื้นฐานที่ 16MHz ตัวจับเวลามีอยู่ในตัวเลือกค่า "prescaler" ซึ่งกำหนดความถี่ / ระยะเวลาดังแสดงในตารางนี้:

    TCCR2B bits 2-0    Prescaler    Freq [KHz], Period [usec] after prescale
          0x0          (TC stopped)      --         --
          0x1                1        16000.        0.0625
          0x2                8         2000.        0.500
          0x3               32          500.        2.000
          0x4               64          250.        4.000
          0x5              128          125.        8.000
          0x6              256           62.5      16.000
          0x7             1024           15.625    64.000

สำหรับการแก้ปัญหาเรื่องจังหวะเวลาที่ดีกว่าคุณใช้ค่าที่เรียกว่า TCNT2 มีบิลด์ในบิลด์จาก 0 ถึง 255 เนื่องจากตัวจับเวลาเป็น 8 บิต เมื่อตัวนับถึงค่าที่กำหนดโดย TCNT2 จะทริกเกอร์การขัดจังหวะ การขัดจังหวะนี้เรียกว่า TIMER2_OVF_vect

จากข้อมูลนี้อัตราการขัดจังหวะที่เกิดขึ้นจะเป็น: 16MHz / (prescaler * (255 - TCNT2))

คุณสามารถตั้งเวลาให้ทำงานที่ 16MHz เต็ม (62.5nSec) แม้ว่าจะเร็วกว่าที่คุณต้องการ 2MHz พร้อมด้วยจำนวนเริ่มต้น (255-2) จะให้อัตราการขัดจังหวะ 1MHz หารด้วย 2 ใน ISR ของคุณ:

extern uint32_t MicroSecClock = 0;

ISR(TIMER2_OVF_vect) {// this is a built in function that gets called when the timer gets to the overflow counter number
  static uint_8 count;            // interrupt counter

  if( (++count & 0x01) == 0 )     // bump the interrupt counter
    ++MicroSecClock;              // & count uSec every other time.

  digitalWrite(53,toggle);// pin 53 is arbitrary
  TCNT2 = 253;                    // this tells the timer when to trigger the interrupt. when the counter gets to 253 out of 255(because the timer is 8 bit) the timmer will trigger an interrupt
  TIFR2 = 0x00;                   // clear timer overflow flag
};

แผ่นข้อมูลสำหรับ MCU ของคุณเป็นทรัพยากรพื้นฐาน บทความนี้จะให้ (และให้ฉัน!) เริ่มต้นที่ดี


4

ทำเครื่องหมายฉันตัดสินใจที่จะเขียนชุดฟังก์ชั่นใหม่ตาม Arduino Atmega328 Timer2 และใช้การขัดจังหวะการโอเวอร์โฟลว์เพื่อให้ได้ความแม่นยำ 0.5us รหัสของฉันสามารถดาวน์โหลดและใช้งานได้ที่นี่:

http://electricrcaircraftguy.blogspot.com/2014/02/Timer2Counter-more-precise-Arduino-micros-function.html

นี่คือคำอธิบายสั้น ๆ : "ฉันเขียน" libary "เพื่อรับความแม่นยำ 0.5us ในฟังก์ชั่นการแทนที่" micros () "เพื่อที่ฉันจะได้ผลลัพธ์ที่ทำซ้ำได้โดยอ่านสัญญาณ PWM หรือ PPM ไปที่ภายใน 1us ฉันค้นหาทั่ว อินเทอร์เน็ตและไม่สามารถหาสิ่งที่เทียบเคียงได้ (หรือใช้งานง่ายและรักษาความสามารถของ Arduino ในการเขียนสัญญาณ PWM ผ่าน Servo Libary) ดังนั้นฉันคิดว่านี่เป็นครั้งแรกที่ฉันมีส่วนร่วมในโลกของ Arduino และ Radio Control "


3

หากปล่อยลงไปที่ระดับ AVR เป็นที่ยอมรับ (ตามที่คุณกล่าวถึงในคำถามของคุณ) คุณสามารถตั้งค่าตัวจับเวลาและแม้แต่รับสัญญาณติ๊กของนาฬิกาของ AVR

คุณต้องอ้างถึงแผ่นข้อมูลของ AVR เพราะมันแตกต่างกันใน ATMegas และ ATTinys ที่แตกต่างกัน แต่ขั้นตอนจะเหมือนกันเสมอ สิ่งที่คุณต้องทำคือ:

  • เลือก prescaler ที่จะใช้ (ตัวอย่างเช่นตั้งค่าเป็น 1 คือไม่มีการตั้งค่าล่วงหน้าหากคุณต้องการความเร็วสัญญาณนาฬิกา CPU จริง) อ้างอิงเอกสาร TCCR
  • ตั้งค่าการขัดจังหวะตัวจับเวลามากเกินไปตัวจัดการขัดจังหวะและเปิดใช้งานการขัดจังหวะทั่วโลก
  • เปิดใช้งานตัวจับเวลาในการลงทะเบียนตัวควบคุมการจับเวลา / นับ TCCR

ด้วยวิธีนี้สามารถรับเห็บที่แน่นอนจากการลงทะเบียนตัวจับเวลาได้อย่างไรก็ตามคุณจำเป็นต้องนับการโอเวอร์โฟลด้วยตนเอง นี่เป็นเทคโนโลยีที่แม่นยำที่สุดเท่าที่จะเป็นไปได้

นี่คือตัวอย่างโค้ดสำหรับ AT90S2313 ที่ล้าสมัย แต่ให้คำแนะนำที่ดีแก่คุณว่าควรทำอย่างไร:

/* uC: AT90S2313 */
#include <avr/io.h>
#include <avr/interrupt.h>

int main(void)
{
  // set up timer 0
  TCCR0 = (1<<CS01); // Prescaler 8

  // enable overflow interrupt
  TIMSK |= (1<<TOIE0);

  // activate interrupts
  sei();

  while(1)
  {
     /* Do whatever you like */
  }
}


ISR (TIMER0_OVF_vect)
{    
   /*
      This gets called everytime there in an overflow in the timer register  
   */
}

ขอบคุณสำหรับใจ ฉันสามารถตั้งค่าอินเตอร์รัปต์เหล่านี้ในบริบทของร่าง Arduino ได้หรือไม่?
Mark Harrison

1
ฉันไม่คุ้นเคยกับกรอบของ arduino แต่ถ้ามันไม่ได้ตั้งค่าตัวจับเวลาทั้งหมดภายในคุณสามารถทำได้อย่างแน่นอน มิฉะนั้นคุณยังสามารถอ่านการจับเวลาและคำนวณด้วยตัวเอง
FeeJai

ใช่คุณจะเขียนโปรแกรมภาษา C ++ เต็มรูปแบบใน Arduino และสามารถใช้ลงทะเบียนและสัญลักษณ์ทั้งหมดเช่นTIMSK, TOIE0ฯลฯ (การตั้งค่าตัวจับเวลาการคัดลอกจากแผ่นข้อมูล atmega328p) ที่ ดูเหมือนว่าคุณไม่สามารถใช้ ISR () แมโครแทนที่จะใช้arduino.cc/en/Reference/AttachInterrupt
joeforker
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.