Arduino Timer: เล่นกับเวลาในโครงการของคุณ

เครื่องจับเวลา Arduino UNO

เมื่อไม่นานมานี้ เราได้เผยแพร่ข้อมูลเพิ่มเติมเกี่ยวกับ ฟังก์ชัน millis() de แพลตฟอร์มฮาร์ดแวร์ตอนนี้เราจะเจาะลึกเข้าไปใน Arduino Timerเพื่อเริ่มต้นใช้งานคุณลักษณะนี้สำหรับคุณลักษณะนี้ ทำความเข้าใจว่าบอร์ดนี้จัดการเวลากับ MCU อย่างไร ตลอดจนฟังก์ชันอื่นๆ นอกเหนือจากมิลลิวินาที ()

Arduino Timer คืออะไร?

ตัวจับเวลา Arduino

El ตัวจับเวลา Arduino หรือตัวจับเวลาเป็นฟังก์ชันที่ฮาร์ดแวร์ใช้งาน (ในไมโครคอนโทรลเลอร์ โดยใช้คริสตัลควอตซ์ที่สร้างพัลส์นาฬิกาและกำหนด "จังหวะ" โดยไม่ต้องใช้ฮาร์ดแวร์ภายนอกหรือไอซี 555) ที่ช่วยให้ควบคุมเหตุการณ์ชั่วคราวได้ด้วยนาฬิกา ภายใน. ตัวอย่างเช่น การทำให้งานเกิดขึ้นเป็นช่วงๆ การวัดเวลาที่แม่นยำ ฯลฯ โดยไม่ขึ้นกับโค้ดแบบร่าง

โคโม Arduino UNO มีชิป MCU ที่ทำงานที่ 16 Mhz, 16.000.000 สามารถทำงานได้ทุกวินาที คำแนะนำต้องใช้ X cycles เพื่อดำเนินการ ไม่ใช่ทุกคำสั่งในวงจรสัญญาณนาฬิกาเดียวกัน ตัวอย่างเช่น 16 บิตต้องการรอบเพิ่มเติมในสถาปัตยกรรม AVR นี้

ลองนึกภาพว่าคุณกำลังใช้ ฟังก์ชันล่าช้า()การดำเนินการนี้จะบล็อกการดำเนินการบน Arduino MCU จนกว่าเวลาที่กำหนดจะผ่านไปแล้วดำเนินการต่อในโปรแกรม แต่ตัวจับเวลาจะไม่บล็อก มันจะเป็นจังหวะที่ MCU ยังคงดำเนินการคำสั่งอื่นๆ พร้อมกัน นั่นคือข้อได้เปรียบที่ยิ่งใหญ่

ตัวจับเวลาเกี่ยวข้องกับ รบกวน ของ Arduino เนื่องจากพวกเขาจะถูกดำเนินการผ่านพวกเขาเพื่อเข้าร่วมงานเฉพาะบางอย่าง กล่าวอีกนัยหนึ่ง Arduino Timer เป็นฟังก์ชันที่ทริกเกอร์ในช่วงเวลาหนึ่ง โดยเรียกใช้ฟังก์ชันขัดจังหวะ ด้วยเหตุนี้จึงเป็นสิ่งสำคัญที่ต้องทราบเกี่ยวกับการหยุดชะงักเหล่านี้

modos

Arduino Timer มี 2 โหมดการทำงาน, สามารถใช้งานได้ใน:

  • สัญญาณ PWM: คุณสามารถควบคุม หมุด Arduino (~).
  • CTC (ล้างตัวจับเวลาในการเปรียบเทียบการแข่งขัน): นับเวลาภายในตัวนับและเมื่อถึงค่าที่ระบุในการลงทะเบียนของตัวจับเวลา การหยุดชะงักจะดำเนินการ

มีตัวจับเวลากี่ตัว? ประเภทของตัวจับเวลา

Arduino UNO ฟังก์ชันมิลลิวินาที

ที่นั่น 3 ตัวจับเวลา บนจาน Arduino UNOแม้ว่าอาจจะมีมากกว่าบนแผ่นอื่นๆ:

  • จับเวลา 0: 8 บิตสามารถนับได้ตั้งแต่ 0 ถึง 255 (256 ค่าที่เป็นไปได้) ใช้โดยฟังก์ชันต่างๆ เช่น delay(), millis() และ micros() ไม่แนะนำให้แก้ไขเพื่อไม่ให้แก้ไขโปรแกรม
  • จับเวลา 1: เท่ากับ Timer 0 ใช้โดยไลบรารี Servo ใน UNO (Timer 5 สำหรับ MEGA)
  • จับเวลา 2: 16 บิต และสามารถอยู่ในช่วงตั้งแต่ 0 ถึง 65.525 (ค่าที่เป็นไปได้ 65.536) ใช้สำหรับฟังก์ชัน tone() หากไม่ได้ใช้ สามารถใช้กับแอปพลิเคชันของคุณได้อย่างอิสระ
  • ตัวจับเวลา 3, 4, 5 (เฉพาะใน Arduino MEGA): ทั้งหมด 16 บิต

Arduino Timer ทำงานอย่างไร

ตัวจับเวลา, ตัวจับเวลา

ไปยัง ทำงานร่วมกับ Arduino Timerจำเป็นต้องรู้ว่าทั้งหมดนี้ทำงานอย่างไรในระบบอิเล็กทรอนิกส์ใน MCU ของบอร์ดพัฒนานี้:

  • ความถี่สัญญาณนาฬิกา: คือจำนวนรอบต่อวินาทีที่สามารถพัฒนาได้ ในกรณีของ Arduino คือ 16 Mhz หรือที่เท่ากัน สัญญาณนาฬิกาจะแกว่ง 16.000.000 ครั้งในหนึ่งวินาที (รอบ)
  • ระยะเวลา: แทนด้วย T และวัดเป็นวินาที และเป็นส่วนผกผันของรอบ ตัวอย่างเช่น T=1/C ซึ่งจะส่งผลให้ 1/16000000 = 0.0000000625 เวลาที่ใช้ในแต่ละรอบจึงจะเสร็จสมบูรณ์ และความถี่คือค่าผกผันของคาบ ดังนั้น f = 1/T
  • วงจร: คือความซ้ำซ้อนของสัญญาณที่เกิดขึ้นต่อหน่วยเวลา บน Arduino มันจะเป็น 16M ในไม่กี่วินาที หรืออะไรจะเหมือนกัน ในกรณีนี้ เมื่อผ่านไป 16 ล้านรอบ หนึ่งวินาทีก็ผ่านไป ดังนั้น อาจกล่าวได้ว่าหนึ่งรอบใช้ 625 ns
  • ขอบของสัญญาณ: สัญญาณนาฬิกาเป็นสี่เหลี่ยมจัตุรัส และขอบสามารถขึ้นหรือลงได้ ขอบคือเส้นตรงของสัญญาณเมื่อเปลี่ยนจาก:
    • 0 (ต่ำ) ถึง 1 (สูง): ขอบที่เพิ่มขึ้น
    • 1 (สูง) ถึง 0 (ต่ำ): ขอบตก

ขอบมีความสำคัญเนื่องจากตัวจับเวลา Arduino วัดรอบจากขอบสัญญาณ ก. ใช่ คอนทาดอร์ มันเพิ่มขึ้นในแต่ละรอบและเมื่อถึงค่ารีจิสเตอร์ การขัดจังหวะจะดำเนินการ

ดังนั้น เมื่อรู้อย่างนี้แล้ว ถ้าคุณมี 16Mhz บน Arduino MCUและใช้ตัวจับเวลา 8 บิต อาจกล่าวได้ว่าอินเตอร์รัปต์จะเกิดขึ้นทุกๆ 16 μs (256/16000000) หรือ 4 ms สำหรับ 16 บิต (65536/16000000) ดังนั้น หากคุณตั้งค่ารีจิสเตอร์ตัวนับ 16 บิตเป็นค่าสูงสุด โดยมีค่า 65535 การขัดจังหวะจะเกิดขึ้นที่ 4 มิลลิวินาทีเพื่อดำเนินการตามภารกิจ

เมื่อตัวนับถึงค่าสูงสุดที่เป็นไปได้ มันจะกลับมาเป็น 0 อีกครั้ง. นั่นคือมีน้ำล้นเกิดขึ้นและจะนับถอยหลังตั้งแต่ต้น

ในการควบคุมอัตราการเพิ่มของตัวจับเวลาคุณสามารถใช้ พรีสเกลเลอร์ซึ่งใช้ค่า 1, 8, 64, 256 และ 1024 และเปลี่ยนเวลาดังนี้:

Timer Speed ​​​​(Hz) = ความถี่สัญญาณนาฬิกาของ Arduino / Prescaler

หากเป็น 1 พรีสเกลเลอร์ คอนโทรลเลอร์จะเพิ่มขึ้นเป็น 16 Mhz หากเป็น 8 ถึง 2 Mhz หากเป็น 64 ถึง 250 kHz เป็นต้น โปรดจำไว้ว่าจะมีตัวเปรียบเทียบสถานะตัวนับตัวจับเวลาเพื่อเปรียบเทียบค่าของตัวนับและตัวนับล่วงหน้าจนกว่าจะเท่ากันแล้วดำเนินการกระทำ ดังนั้น, ความถี่ขัดจังหวะ ถูกกำหนดโดยสูตร:

+1 เป็นเพราะตัวนับรีจิสเตอร์ถูกสร้างดัชนีที่ 0 นั่นคือไม่เริ่มนับที่ 1 แต่ที่ 0

ความเร็วขัดจังหวะ (Hz) = ความถี่นาฬิกา Arduino / Prescaler (ค่าลงทะเบียนเปรียบเทียบ + 1)

โชคดีที่เราต้องไม่ แก้ไขบันทึก ของ Arduino Timers เนื่องจากไลบรารีที่เราใช้ในโค้ดจะได้รับการดูแล แต่ถ้าไม่ได้ใช้ก็ควรกำหนดค่า

ตัวอย่างใน Arduino IDE

Arduino IDE, ชนิดข้อมูล, การเขียนโปรแกรม

เพื่อให้เข้าใจทั้งหมดนี้ดีขึ้นเล็กน้อย ในที่นี้ ฉันแสดงรหัสร่างสองชุดสำหรับ Arduino IDE ซึ่งคุณจะได้สัมผัสประสบการณ์การใช้ตัวจับเวลา อย่างแรกคือรหัสที่จะกะพริบ LED ที่เชื่อมต่อกับ Arduino pin 8 ทุกวินาที:

#define ledPin 8
void setup()
{
  pinMode(ledPin, OUTPUT);
  // Configurar Timer1
  TCCR1A = 0;                        //Registro control A a 0, pines OC1A y OC1B deshabilitados
  TCCR1B = 0;                        //Limpia el registrador
  TCCR1B |= (1<<CS10)|(1 << CS12);   //Configura prescaler a 1024: CS12 = 1 y CS10 = 1
  TCNT1 = 0xC2F8;                    //Iniciar timer para desbordamiento a 1 segundo
                                     //65536-(16MHz/1024/1Hz - 1) = 49912 = 0xC2F8 en hexadecimal
  
  TIMSK1 |= (1 << TOIE1);           //Habilitar interrupción para Timer1
}
void loop()
{
}
ISR(TIMER1_OVF_vect)                              //Interrupción del TIMER1 
{
  TCNT1 = 0xC2F7;                                 // Reniciar Timer1
  digitalWrite(ledPin, digitalRead(ledPin) ^ 1); //Invierte el estado del LED
}

ตั้งโปรแกรมให้ไฟ LED กะพริบหรือกะพริบดังเช่นครั้งก่อนทุกวินาที แต่คราวนี้ใช้ CTC คือการเปรียบเทียบ:

#define ledPin 8
void setup()
{
  pinMode(ledPin, OUTPUT);
  
  // Configuración Timer1
  TCCR1A = 0;                //Registro de control A a 0
  TCCR1B = 0;                //Limpiar registro
  TCNT1  = 0;                //Inicializar el temporizador
  OCR1A = 0x3D08;            //Carga el valor del registro de comparación: 16MHz/1024/1Hz -1 = 15624 = 0X3D08
  TCCR1B |= (1 << WGM12)|(1<<CS10)|(1 << CS12);   //Modo CTC, prescaler de 1024: CS12 = 1 y CS10 = 1  
  TIMSK1 |= (1 << OCIE1A);  //Habilita interrupción por igualdad de comparación
}
void loop()
{
}
ISR(TIMER1_COMPA_vect)          //Interrupción por igualdad de comparación en TIMER1
{
  digitalWrite(ledPin, digitalRead(ledPin) ^ 1);   //Invierte el estado del LED
}

เพิ่มเติมเกี่ยวกับการเขียนโปรแกรม Arduino

ซื้อจาน Arduino UNO Rev3

เป็นคนแรกที่จะแสดงความคิดเห็น

แสดงความคิดเห็นของคุณ

อีเมล์ของคุณจะไม่ถูกเผยแพร่ ช่องที่ต้องการถูกทำเครื่องหมายด้วย *

*

*

  1. ผู้รับผิดชอบข้อมูล: Miguel ÁngelGatón
  2. วัตถุประสงค์ของข้อมูล: ควบคุมสแปมการจัดการความคิดเห็น
  3. ถูกต้องตามกฎหมาย: ความยินยอมของคุณ
  4. การสื่อสารข้อมูล: ข้อมูลจะไม่ถูกสื่อสารไปยังบุคคลที่สามยกเว้นตามข้อผูกพันทางกฎหมาย
  5. การจัดเก็บข้อมูล: ฐานข้อมูลที่โฮสต์โดย Occentus Networks (EU)
  6. สิทธิ์: คุณสามารถ จำกัด กู้คืนและลบข้อมูลของคุณได้ตลอดเวลา