เมื่อไม่นานมานี้ เราได้เผยแพร่ข้อมูลเพิ่มเติมเกี่ยวกับ ฟังก์ชัน millis() de แพลตฟอร์มฮาร์ดแวร์ตอนนี้เราจะเจาะลึกเข้าไปใน Arduino Timerเพื่อเริ่มต้นใช้งานคุณลักษณะนี้สำหรับคุณลักษณะนี้ ทำความเข้าใจว่าบอร์ดนี้จัดการเวลากับ MCU อย่างไร ตลอดจนฟังก์ชันอื่นๆ นอกเหนือจากมิลลิวินาที ()
Arduino Timer คืออะไร?
El ตัวจับเวลา Arduino หรือตัวจับเวลาเป็นฟังก์ชันที่ฮาร์ดแวร์ใช้งาน (ในไมโครคอนโทรลเลอร์ โดยใช้คริสตัลควอตซ์ที่สร้างพัลส์นาฬิกาและกำหนด "จังหวะ" โดยไม่ต้องใช้ฮาร์ดแวร์ภายนอกหรือไอซี 555) ที่ช่วยให้ควบคุมเหตุการณ์ชั่วคราวได้ด้วยนาฬิกา ภายใน. ตัวอย่างเช่น การทำให้งานเกิดขึ้นเป็นช่วงๆ การวัดเวลาที่แม่นยำ ฯลฯ โดยไม่ขึ้นกับโค้ดแบบร่าง
ลองนึกภาพว่าคุณกำลังใช้ ฟังก์ชันล่าช้า()การดำเนินการนี้จะบล็อกการดำเนินการบน Arduino MCU จนกว่าเวลาที่กำหนดจะผ่านไปแล้วดำเนินการต่อในโปรแกรม แต่ตัวจับเวลาจะไม่บล็อก มันจะเป็นจังหวะที่ MCU ยังคงดำเนินการคำสั่งอื่นๆ พร้อมกัน นั่นคือข้อได้เปรียบที่ยิ่งใหญ่
ตัวจับเวลาเกี่ยวข้องกับ รบกวน ของ Arduino เนื่องจากพวกเขาจะถูกดำเนินการผ่านพวกเขาเพื่อเข้าร่วมงานเฉพาะบางอย่าง กล่าวอีกนัยหนึ่ง Arduino Timer เป็นฟังก์ชันที่ทริกเกอร์ในช่วงเวลาหนึ่ง โดยเรียกใช้ฟังก์ชันขัดจังหวะ ด้วยเหตุนี้จึงเป็นสิ่งสำคัญที่ต้องทราบเกี่ยวกับการหยุดชะงักเหล่านี้
modos
Arduino Timer มี 2 โหมดการทำงาน, สามารถใช้งานได้ใน:
- สัญญาณ PWM: คุณสามารถควบคุม หมุด Arduino (~).
- CTC (ล้างตัวจับเวลาในการเปรียบเทียบการแข่งขัน): นับเวลาภายในตัวนับและเมื่อถึงค่าที่ระบุในการลงทะเบียนของตัวจับเวลา การหยุดชะงักจะดำเนินการ
มีตัวจับเวลากี่ตัว? ประเภทของตัวจับเวลา
ที่นั่น 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 เป็นต้น โปรดจำไว้ว่าจะมีตัวเปรียบเทียบสถานะตัวนับตัวจับเวลาเพื่อเปรียบเทียบค่าของตัวนับและตัวนับล่วงหน้าจนกว่าจะเท่ากันแล้วดำเนินการกระทำ ดังนั้น, ความถี่ขัดจังหวะ ถูกกำหนดโดยสูตร:
ความเร็วขัดจังหวะ (Hz) = ความถี่นาฬิกา Arduino / Prescaler (ค่าลงทะเบียนเปรียบเทียบ + 1)
โชคดีที่เราต้องไม่ แก้ไขบันทึก ของ Arduino Timers เนื่องจากไลบรารีที่เราใช้ในโค้ดจะได้รับการดูแล แต่ถ้าไม่ได้ใช้ก็ควรกำหนดค่า
ตัวอย่างใน 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