- TIMER ใน Embedded Electronics คืออะไร?
- Arduino Timer Registers
- Arduino Timer Interrupts
- ส่วนประกอบที่จำเป็น
- แผนภูมิวงจรรวม
- การเขียนโปรแกรม Arduino UNO Timers
แพลตฟอร์มการพัฒนา Arduino ได้รับการพัฒนาในปี 2548 เป็นอุปกรณ์ที่ตั้งโปรแกรมได้ง่ายสำหรับโครงการออกแบบงานศิลปะ ความตั้งใจนี้คือการช่วยผู้ที่ไม่ใช่วิศวกรให้ทำงานกับอุปกรณ์อิเล็กทรอนิกส์และไมโครคอนโทรลเลอร์ขั้นพื้นฐานโดยไม่ต้องมีความรู้ด้านการเขียนโปรแกรมมากนัก แต่แล้วเนื่องจากลักษณะการใช้งานที่ง่ายจึงได้รับการดัดแปลงโดยผู้เริ่มต้นใช้งานอุปกรณ์อิเล็กทรอนิกส์และมือสมัครเล่นทั่วโลกในไม่ช้าและปัจจุบันเป็นที่ต้องการสำหรับการพัฒนาต้นแบบและการพัฒนา POC
แม้ว่าจะเริ่มต้นด้วย Arduino ได้ แต่สิ่งสำคัญคือต้องค่อยๆย้ายเข้าไปในไมโครคอนโทรลเลอร์หลักเช่น AVR, ARM, PIC, STM เป็นต้นและตั้งโปรแกรมโดยใช้แอปพลิเคชันดั้งเดิม เนื่องจากภาษาโปรแกรม Arduinoนั้นเข้าใจง่ายมากเนื่องจากงานส่วนใหญ่ทำโดยฟังก์ชันที่สร้างไว้ล่วงหน้าเช่น digitalWrite (), AnalogWrite (), Delay () เป็นต้นในขณะที่ภาษาเครื่องระดับต่ำจะซ่อนอยู่ด้านหลัง โปรแกรม Arduino ไม่เหมือนกับการเข้ารหัส C แบบฝังตัวอื่น ๆ ที่เราจัดการกับบิตรีจิสเตอร์และทำให้สูงหรือต่ำตามตรรกะของโปรแกรมของเรา
Arduino Timers โดยไม่ชักช้า:
ดังนั้นเพื่อให้เข้าใจถึงสิ่งที่เกิดขึ้นภายในฟังก์ชันที่สร้างไว้ล่วงหน้าเราจำเป็นต้องขุดคุ้ยคำศัพท์เหล่านี้ ตัวอย่างเช่นเมื่อมีการใช้ฟังก์ชันdelay ()มันจะตั้งค่าบิต Timer และ Counter Registerของไมโครคอนโทรลเลอร์ ATmega
ในแบบฝึกหัดการจับเวลา arduinoนี้เราจะหลีกเลี่ยงการใช้ฟังก์ชัน delay () นี้และจัดการกับ Registers ด้วยตัวเองแทน สิ่งที่ดีคือคุณสามารถใช้ Arduino IDE เดียวกันสำหรับสิ่งนี้ เราจะตั้งเวลาของเราลงทะเบียนบิตและใช้จับเวลาล้นขัดจังหวะเพื่อสลับไฟ LED ทุกครั้งที่เกิดขึ้นขัดจังหวะ นอกจากนี้ยังสามารถปรับค่าพรีโหลดของบิตตัวจับเวลาได้โดยใช้ปุ่มกดเพื่อควบคุมระยะเวลาที่การขัดจังหวะเกิดขึ้น
TIMER ใน Embedded Electronics คืออะไร?
ตัวจับเวลาเป็นตัวขัดจังหวะ เปรียบเสมือนนาฬิกาธรรมดาที่สามารถวัดช่วงเวลาของเหตุการณ์ได้ ไมโครคอนโทรลเลอร์ทุกตัวมีนาฬิกา (ออสซิลเลเตอร์) พูดใน Arduino Uno คือ 16Mhz สิ่งนี้รับผิดชอบต่อความเร็ว ความถี่สัญญาณนาฬิกาที่สูงขึ้นจะเป็นความเร็วในการประมวลผล ตัวจับเวลาใช้ตัวนับซึ่งนับด้วยความเร็วที่กำหนดขึ้นอยู่กับความถี่สัญญาณนาฬิกา ใน Arduino Uno ใช้เวลา 1/16000000 วินาทีหรือ 62nano วินาทีในการนับครั้งเดียว ความหมาย Arduino จะย้ายจากคำสั่งหนึ่งไปยังคำสั่งอื่นทุกๆ 62 นาโนวินาที
ตัวจับเวลาใน Arduino UNO:
ใน Arduino UNO มีตัวจับเวลาสามตัวที่ใช้สำหรับฟังก์ชันต่างๆ
จับเวลา 0:
เป็นตัวจับเวลาแบบ 8 บิตและใช้ในฟังก์ชันจับเวลาเช่นดีเลย์ (), มิลลิวินาที ()
จับเวลา 1:
เป็นตัวจับเวลา 16 บิตและใช้ในไลบรารีเซอร์โว
จับเวลา 2:
เป็นตัวตั้งเวลา 8 บิตและใช้ในฟังก์ชัน tone ()
Arduino Timer Registers
ในการเปลี่ยนการกำหนดค่าของตัวจับเวลาจะใช้รีจิสเตอร์ตัวจับเวลา
1. Timer / Counter Control Registers (TCCRnA / B):
รีจิสเตอร์นี้เก็บบิตควบคุมหลักของตัวจับเวลาและใช้เพื่อควบคุมพรีสเกลเลอร์ของตัวจับเวลา นอกจากนี้ยังอนุญาตให้ควบคุมโหมดจับเวลาโดยใช้บิต WGM
รูปแบบเฟรม:
TCCR1A | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
COM1A1 | COM1A0 | COM1B1 | COM1B0 | COM1C1 | COM1C0 | WGM11 | WGM10 |
TCCR1B | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
ICNC1 | ICES1 | - | WGM13 | WGM12 | CS12 | CS11 | CS10 |
Prescaler:
CS12, CS11, CS10 บิตใน TCCR1B ตั้งค่า Prescaler Prescaler ใช้เพื่อตั้งค่าความเร็วนาฬิกาของตัวจับเวลา Arduino Uno มีตัวแทนจำหน่าย 1, 8, 64, 256, 1024
CS12 | CS11 | CS10 | ใช้ |
0 | 0 | 0 | ไม่มีนาฬิกาจับเวลาหยุด |
0 | 0 | 1 | CLCK i / o / 1 ไม่มี Prescaling |
0 | 1 | 0 | CLK i / o / 8 (จาก Prescaler) |
0 | 1 | 1 | CLK i / o / 64 (จาก Prescaler) |
1 | 0 | 0 | CLK i / o / 256 (จาก Prescaler) |
1 | 0 | 1 | CLK i / o / 1024 (จาก Prescaler) |
1 | 1 | 0 | แหล่งสัญญาณนาฬิกาภายนอกบนขา T1 นาฬิกาที่ขอบตก |
1 | 1 | 1 | แหล่งสัญญาณนาฬิกาภายนอกบนขา T1 นาฬิกาบนขอบที่เพิ่มขึ้น |
2. จับเวลา / ลงทะเบียนเคาน์เตอร์ (TCNTn)
การลงทะเบียนนี้ใช้เพื่อควบคุมค่าตัวนับและตั้งค่าตัวโหลดล่วงหน้า
สูตรสำหรับค่าตัวโหลดล่วงหน้าสำหรับเวลาที่ต้องการเป็นวินาที:
TCNTn = 65535 - (16x10 10 xTime เป็นวินาที / Prescaler Value)
ในการคำนวณค่าตัวโหลดล่วงหน้าสำหรับ timer1 เป็นเวลา 2 วินาที:
TCNT1 = 65535 - (16x10 10 x2 / 1024) = 34285
Arduino Timer Interrupts
ก่อนหน้านี้เราได้เรียนรู้เกี่ยวกับ Arduino Interrupts และได้เห็นว่าการขัดจังหวะของ Timer เป็นซอฟต์แวร์ขัดจังหวะ มีการขัดจังหวะการจับเวลาหลายแบบใน Arduino ซึ่งอธิบายไว้ด้านล่างตัวจับเวลาล้นขัดจังหวะ:
เมื่อใดก็ตามที่ตัวจับเวลาถึงค่าสูงสุดให้พูดเช่น (16 Bit-65535) Timer Overflow Interrupt จะเกิดขึ้น ดังนั้นรูทีนเซอร์วิสการขัดจังหวะ ISR จึงถูกเรียกเมื่อเปิดใช้งานบิต Timer Overflow Interrupt ใน TOIEx ที่มีอยู่ในตัวจับเวลาอินเตอร์รัปต์มาสก์ลงทะเบียน TIMSKx
รูปแบบ ISR:
ISR (TIMERx_OVF_vect) { }
เอาต์พุตเปรียบเทียบรีจิสเตอร์ (OCRnA / B):
ที่นี่เมื่อผลลัพธ์เปรียบเทียบการขัดจังหวะการจับคู่เกิดขึ้นจะเรียกใช้บริการขัดจังหวะ ISR (TIMERx_COMPy_vect) และบิตแฟล็ก OCFxy จะถูกตั้งค่าในการลงทะเบียน TIFRx ISR นี้ถูกเปิดใช้งานโดยการตั้งค่าเปิดใช้งานบิตใน OCIExy ที่มีอยู่ในการลงทะเบียน TIMSKx โดยที่ TIMSKx คือ Timer Interrupt Mask Register
ตัวจับเวลาอินพุตจับ:
ถัดไปเมื่อตัวจับเวลา Input Capture Interrupt เกิดขึ้นจากนั้นอินเตอร์รัปต์เซอร์วิส ISR (TIMERx_CAPT_vect) จะถูกเรียกและบิตแฟล็ก ICFx จะถูกตั้งค่าใน TIFRx (Timer Interrupt Flag Register) ISR นี้เปิดใช้งานโดยการตั้งค่าบิตเปิดใช้งานใน ICIEx ที่มีอยู่ในการลงทะเบียน TIMSKx
ส่วนประกอบที่จำเป็น
- Arduino UNO
- ปุ่มกด (2)
- LED (สีใดก็ได้)
- ตัวต้านทาน 10k (2), 2.2k (1)
- จอ LCD 16x2
แผนภูมิวงจรรวม
การเชื่อมต่อวงจรระหว่าง Arduino UNO และจอ LCD 16x2:
16x2 LCD |
Arduino UNO |
VSS |
GND |
VDD |
+ 5V |
V0 |
ไปยังพินกลางโพเทนชิออมิเตอร์เพื่อควบคุมความเปรียบต่างของ LCD |
อาร์เอส |
8 |
RW |
GND |
จ |
9 |
D4 |
10 |
D5 |
11 |
D6 |
12 |
D7 |
13 |
ก |
+ 5V |
เค |
GND |
ปุ่มกดสองปุ่มพร้อมตัวต้านทานแบบดึงลง 10K เชื่อมต่อกับหมุด Arduino 2 และ 4 และ LED เชื่อมต่อกับ PIN 7 ของ Arduino ผ่านตัวต้านทาน 2.2K
การตั้งค่าจะมีลักษณะเหมือนภาพด้านล่าง
การเขียนโปรแกรม Arduino UNO Timers
ในบทช่วยสอนนี้เราจะใช้TIMER OVERFLOW INTERRUPTและใช้เพื่อกะพริบไฟ LED เปิดและปิดในช่วงเวลาหนึ่งโดยปรับค่าพรีโหลด (TCNT1) โดยใช้ปุ่มกด รหัสที่สมบูรณ์สำหรับ Arduino Timer จะได้รับในตอนท้าย ที่นี่เรากำลังอธิบายรหัสทีละบรรทัด:
เนื่องจากใช้ LCD 16x2 ในโปรเจ็กต์เพื่อแสดงค่าพรีโหลดดังนั้นจึงใช้ไลบรารีคริสตัลเหลว
# รวม
ขาแอโนด LED ที่มีการเชื่อมต่อกับ Arduino ขา 7 ถูกกำหนดให้เป็นledPin
# กำหนด ledPin 7
ถัดไปวัตถุสำหรับเข้าถึงคลาส Liquid Crystal จะถูกประกาศด้วยหมุด LCD (RS, E, D4, D5, D6, D7) ที่เชื่อมต่อกับ Arduino UNO
LiquidCrystal LCD (8,9,10,11,12,13);
จากนั้นตั้งค่าตัวโหลดล่วงหน้า 3035 เป็นเวลา 4 วินาที ตรวจสอบสูตรด้านบนเพื่อคำนวณค่าตัวโหลดล่วงหน้า
ค่าลอย = 3035;
ถัดไปใน การตั้งค่าโมฆะ () ขั้น แรกให้ตั้งค่า LCD ในโหมด 16x2 และแสดงข้อความต้อนรับเป็นเวลาสองสามวินาที
lcd.begin (16,2); lcd.setCursor (0,0); lcd.print ("ARDUINO TIMERS"); ล่าช้า (2000); lcd.clear ();
ถัดไปตั้งขา LED เป็นขาเอาท์พุทและปุ่มกดจะตั้งเป็นพิน INPUT
PinMode (ledPin, เอาท์พุท); pinMode (2, อินพุต); pinMode (4, อินพุต);
ถัดไปปิดใช้งานการขัดจังหวะทั้งหมด:
noInterrupts ();
ถัดไป Timer1 จะเริ่มต้น
TCCR1A = 0; TCCR1B = 0;
ตั้งค่าตัวจับเวลาพรีโหลดแล้ว (เริ่มต้นเป็น 3035)
TCNT1 = ค่า;
จากนั้นค่า Pre scaler 1024 จะถูกตั้งค่าในทะเบียน TCCR1B
TCCR1B - = (1 << CS10) - (1 << CS12);
การขัดจังหวะของ Timer overflow ถูกเปิดใช้งานในการลงทะเบียน Timer Interrupt Mask เพื่อให้สามารถใช้ ISR ได้
TIMSK1 - = (1 << TOIE1);
ในที่สุดการขัดจังหวะทั้งหมดจะถูกเปิดใช้งาน
ขัดจังหวะ ();
ตอนนี้เขียน ISR สำหรับจับเวลาล้นขัดจังหวะซึ่งเป็นผู้รับผิดชอบสำหรับการเปิดไฟ LED และปิดใช้digitalWrite สถานะจะเปลี่ยนไปเมื่อใดก็ตามที่เกิดการขัดจังหวะของตัวจับเวลามากเกินไป
ISR (TIMER1_OVF_vect) { TCNT1 = ค่า; digitalWrite (ledPin, digitalRead (ledPin) ^ 1); }
ใน void loop () ค่าของตัวโหลดล่วงหน้าจะเพิ่มขึ้นหรือลดลงโดยใช้อินพุตปุ่มกดและค่าจะแสดงบน LCD 16x2
ถ้า (digitalRead (2) == สูง) { value = value + 10; // Incement preload value } if (digitalRead (4) == HIGH) { value = value-10; // ลดค่าพรีโหลด } lcd.setCursor (0,0); lcd.print (ค่า); }
นี่คือวิธีใช้ตัวจับเวลาเพื่อสร้างความล่าช้าในโปรแกรม Arduino ตรวจสอบวิดีโอด้านล่างซึ่งเราได้แสดงให้เห็นถึงการเปลี่ยนแปลงความล่าช้าโดยการเพิ่มและลดค่าตัวโหลดล่วงหน้าโดยใช้ปุ่มกด