คุณไม่จำเป็นต้องมี RTC เพื่อสร้างนาฬิกา: ชิป ATmega มีฮาร์ดแวร์ทั้งหมดที่จำเป็นในการปฏิบัติหน้าที่ของ RTC เอง นี่คือวิธี:
รับคริสตัลนาฬิกา 32768 Hz: ซื้อหรือแยกนาฬิกาเก่า ผลึกเหล่านี้ได้รับการออกแบบมาโดยเฉพาะสำหรับการรักษาเวลามีมากลอยอุณหภูมิขนาดเล็ก คุณจะต้องมีหนึ่งในนั้นหากคุณต้องการใช้ชิป RTC
กำหนดค่าฟิวส์ของ ATmega ของคุณเพื่อให้หลุดออกจาก 8 MHz RC oscillator สิ่งนี้จะทำให้millis()
ฟังก์ชั่นของคุณไม่ถูกต้องอย่างน่ากลัวและยังเพิ่มหมุด XTAL1 และ XTAL2
เชื่อมต่อคริสตัลนาฬิกากับพิน TOSC1 และ TOSC2 เหล่านี้เป็นพินเดียวกับ XTAL1 และ XTAL2 (9 และ 10 ใน 328P) ชื่อที่แตกต่างกันใช้เพื่อหมายถึงฟังก์ชั่นต่าง ๆ
กำหนดค่า Timer / Counter 2 สำหรับการทำงานแบบอะซิงโครนัสโหมดนับปกติ prescaler ตั้งไว้ที่ 128 และเปิดใช้งานการขัดจังหวะตัวตั้งเวลาล้น
ตอนนี้คุณจะได้รับการขัดจังหวะโดย TIMER2_OVF ในอัตราที่คงที่มาก ๆ หนึ่งครั้งต่อวินาที คุณจะต้องเลื่อนการแสดงผลนาฬิกาล่วงหน้าไปหนึ่งวินาทีใน ISR ในระหว่างการขัดจังหวะคุณสามารถทำให้ MCU อยู่ในโหมดสลีปที่ลึกมาก (โหมดประหยัดพลังงาน: ไม่มีอะไรทำงานนอกจากตัวจับเวลา / ตัวนับ 2) และทำงานเป็นเวลาหลายปีในเซลล์ AA สองเซลล์ เว้นเสียแต่ว่าจอแสดงผลจะเต็มไปด้วยกำลัง
ผมทำตรงนี้ในการสร้างของฉันตลอด 24 ชั่วโมงนาฬิกาผนังด้านหนึ่งมือ ลิงค์นี้ชี้ไปที่การแปลภาษาอังกฤษของเอกสารต้นฉบับเป็นภาษาฝรั่งเศส
การสอบเทียบควอตซ์
หากคุณไม่ได้สอบเทียบควอทซ์ของคุณคุณสามารถคาดหวังการดริฟท์อย่างมีนัยสำคัญโดยทั่วไปไม่กี่วินาทีต่อสัปดาห์ อัตราดริฟท์ขึ้นอยู่กับความจุจรจัดของร่องรอยที่เชื่อมต่อคริสตัลเข้ากับ MCU โดยหลักการแล้วสามารถลบออกได้โดยการเพิ่มความจุที่ปรับแต่งแล้ว เป็นที่น่าสังเกตว่าคุณจะมีปัญหาดริฟท์แบบเดียวกันกับ RTC
หากคุณพอใจกับความถูกต้องแบบนี้จงใช้ชีวิตให้ดีและมีความสุข อย่างไรก็ตามหากคุณต้องการวัดค่าดริฟท์คุณจะสังเกตเห็นว่ามันเสถียรมาก จากนั้นคุณสามารถชดเชยในซอฟต์แวร์และบรรลุความถูกต้องของไม่กี่วินาทีต่อปี
อัลกอริทึมสำหรับการแก้ไขการดริฟท์นั้นง่ายมาก จากดริฟท์ที่วัดได้คุณจะทราบความล่าช้าที่แม่นยำระหว่างอินเทอร์รัปต์ซึ่งควรใกล้เคียงกับ 10 9 นาโนวินาทีมากแล้ว:
#define ONE_SECOND 1000000000 // in nanoseconds
#define ONE_INTERRUPT 999993482 // for example
ISR(TIMER2_OVF_vect)
{
static uint32_t unaccounted_time;
unaccounted_time += ONE_INTERRUPT;
while (unaccounted_time >= ONE_SECOND) {
advance_display_by_one_second();
unaccounted_time -= ONE_SECOND;
}
}
ในตัวอย่างด้านบนควอทซ์นั้นเร็วเกินไปเล็กน้อยและซอฟต์แวร์ชดเชยด้วยการทำเครื่องหมาย“ หายไป” ทุกสองสามวัน หากควอตซ์ช้าเกินไปรหัสเดียวกันจะแทนการทำเครื่องหมายสองครั้งทุกๆสองสามวัน
การสอบเทียบแบบนี้สามารถทำได้สำหรับ RTC แต่มันจะมีความซับซ้อนมากขึ้นเนื่องจาก RTC รายงานเวลาในรูปแบบที่ไม่สามารถใช้งานได้ซึ่งโดยปกติแล้วจะไม่ได้ให้การดำเนินการทางคณิตศาสตร์