DS1307 เรียกอีกอย่างว่า RTC (นาฬิกาเรียลไทม์) ชิปนี้เป็นนาฬิกาและปฏิทินแบบเรียลไทม์ การสื่อสารกับไมโครวงจรดำเนินการผ่านอินเทอร์เฟซ I 2 C ข้อดีของมันคือใช้งานได้ (นับเวลา) เมื่อปิดไฟหลักจากแหล่งพลังงานสำรอง 3 โวลต์ (เช่นจากแบตเตอรี่ CR3022) แต่ DS1307 มีข้อเสียเปรียบประการหนึ่ง: มันไม่ได้ตรวจสอบว่าข้อมูลที่ป้อนนั้นถูกต้องหรือไม่ ในการทำงานกับไมโครวงจร คุณจะต้องมีชุดอุปกรณ์ขั้นต่ำ: ควอตซ์ที่ 32768Hz แบตเตอรี่ 3 โวลต์และตัวต้านทาน 4.7 kOhm สองตัว แผนภาพการเชื่อมต่อ DS1307:
การทำงานกับ DS1307 ใน BASCOM-AVR
ในการเริ่มทำงานกับไมโครเซอร์กิตคุณต้องกำหนดค่าพอร์ตที่ไมโครเซอร์กิตเชื่อมต่ออยู่ หากต้องการทำสิ่งนี้ให้ใช้คำสั่ง การกำหนดค่า:
กำหนดค่า Sda =(พอร์ตไมโครคอนโทรลเลอร์ที่เชื่อมต่อขา SDA ของชิป DS1307)
กำหนดค่า Scl =(พอร์ตไมโครคอนโทรลเลอร์ที่เชื่อมต่อขา SCL ของชิป DS1307)
ตัวอย่างเช่น:
กำหนดค่า Sda = Portb.1
กำหนดค่า Scl = Portb.0
หลังจากกำหนดค่าพอร์ตแล้ว คุณสามารถเริ่มทำงานกับชิปได้: อ่านและเขียนข้อมูล เวลาและวันที่จากชิป DS1307 สามารถอ่านได้ดังนี้:
I2cstart I2cwbyte &HD0 I2cwbyte &H00 I2cstart I2cwbyte &HD1 I2crbyte (ตัวแปรที่เราเขียนวินาที), Ack I2crbyte (ตัวแปรที่เราเขียนนาที), Ack I2crbyte (ตัวแปรที่เราเขียนชั่วโมง), Ack I2crbyte (ตัวแปรที่เราเขียน เขียนจำนวนวันในสัปดาห์), Ack I2crbyte (ตัวแปรที่เราเขียนวันที่), Ack I2crbyte (ตัวแปรที่เราเขียนหมายเลขเดือน), Ack I2crbyte (ตัวแปรที่เราเขียนปี), Nack I2cstop
หลังจากอ่านข้อมูลแล้ว คุณต้องแปลงเป็นรูปแบบทศนิยมดังนี้:
(ตัวแปรวินาที) = มาเดค((ตัวแปรวินาที) )
(ตัวแปรนาที) = มาเดค((ตัวแปรนาที) )
(ตัวแปรนาฬิกา) = มาเดค((ตัวแปรนาฬิกา) )
(ตัวแปรวันในสัปดาห์) = มาเดค((ตัวแปรวันในสัปดาห์) )
(ตัวแปรวันที่) = มาเดค((ตัวแปรวันที่) )
(ตัวแปรเดือน) = มาเดค((ตัวแปรเดือน) )
(ตัวแปรปี) = มาเดค((ตัวแปรปี) )
นี่คือตัวอย่างการอ่านเวลาและวันที่และแปลงเป็นรูปแบบทศนิยม:
I2cstart I2cwbyte &HD0 I2cwbyte &H00 I2cstart I2cwbyte &HD1 I2crbyte Seco , Ack I2crbyte Mine , Ack I2crbyte ชั่วโมง , Ack I2crbyte วัน , Ack I2crbyte Dat , Ack I2crbyte เดือน , Ack I2crbyte ปี , Nack I2cstop Seco = Makedec(seco M) ine = Makedec(ของฉัน) ชั่วโมง = Makedec(ชั่วโมง) วัน = Makedec(วัน) Dat = Makedec(dat) เดือน = Makedec(เดือน) ปี = Makedec(ปี)
เราได้เรียนรู้วิธีการอ่านข้อมูลแล้ว ทีนี้มาลองเขียนข้อมูลลงใน DS1307 กันดีกว่า แบบนี้:
(ตัวแปรที่เราจะเขียนลงไป) =
เมคบีซีดี((ตัวแปรที่เราจะเขียนลงไป) )
I2cstart
I2cwbyte&HD0
I2ไบต์(เซลล์ที่เราจะเขียนข้อมูล)
I2ไบต์(ตัวแปรที่เราจะเขียนลงไป)
I2cstop
โปรดทราบว่าคำสั่ง Makebcdแปลงตัวแปรเป็นรูปแบบทศนิยมไบนารี หมายเลขเซลล์และการกำหนด:
นี่คือตัวอย่างการเขียนตัวแปรวินาที:
เซโก้ = Makebcd(เซโก้)
I2cstart
I2cwbyte&HD0
I2cwไบต์ 0
I2cwbyte Seco
I2ซีสต็อป
อย่างไรก็ตามควรสังเกตว่าเมื่อ DS1307 สตาร์ทเป็นครั้งแรก (เช่นเมื่อเชื่อมต่อแบตเตอรี่สำรอง) ไมโครวงจรจะส่งคืนค่า 80 เป็นวินาทีซึ่งหมายความว่านาฬิกาหยุดทำงาน หากต้องการเรียกใช้ ให้จดค่า 1 เป็นวินาที หาก DS1307 ส่งกลับค่า 255 หรือ 168 เมื่ออ่านข้อมูลใดๆ แสดงว่าชิปไม่ได้เชื่อมต่ออย่างถูกต้องหรือไม่มีแบตเตอรี่สำรอง
ใช้งานได้จริงด้วยชิป DS1307
ตอนนี้เรามาลองใช้งานชิป DS1307 ในทางปฏิบัติ: มาประกอบนาฬิกาง่ายๆ พร้อมตั้งเวลาโดยใช้ปุ่มต่างๆ ในการทำเช่นนี้ ลองใช้ชิป DS1307, ไมโครคอนโทรลเลอร์ Attiny2313, ไฟแสดงสถานะ LCD บนคอนโทรลเลอร์ HD44780 และส่วนประกอบแยกหลายชิ้น มาสร้างแผนภาพง่ายๆ กัน:
และมาเขียนโปรแกรมง่ายๆ โดยใช้ความรู้ที่ได้รับ:
$regfile = "attiny2313.dat" $crystal = 4000000 กำหนดค่า Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7 , E = Portb.3 , Rs = Portb .2 Config Lcd = 16 * 2 Config Pind.5 = Input Config Pind.4 = Input Config Sda = Portb.1 Config Scl = Portb.0 Dim Seco As Byte Dim Mine As Byte Dim Hour As Byte Initlcd Cls Cursor Off ทำ I2cstart I2cwbyte &HD0 I2cwbyte &H00 I2cstart I2cwbyte &HD1 I2crbyte Seco , Ack I2crbyte Mine , Ack I2crbyte ชั่วโมง , Nack I2cstop Seco = Makedec(seco) Mine = Makedec(ของฉัน) ชั่วโมง = Makedec(ชั่วโมง) ค้นหา 1 , 1 Lcd ชั่วโมง ; - ของฉัน; - เซโก้; " " ถ้า Pind.5 = 0 จากนั้น Incr Mine Mine = Makebcd(ของฉัน) I2cstart I2cwbyte &HD0 I2cwbyte 1 I2cwbyte Mine I2cstop Waitms 100 สิ้นสุด ถ้าถ้า Pind.4 = 0 จากนั้น Incr ชั่วโมง ชั่วโมง = Makebcd(ชั่วโมง) I2cstart I2cwbyte &HD0 I2cwbyte 2 I2cwbyte ชั่วโมง I2cstop Waitms 100 สิ้นสุด หากสิ้นสุดลูป
DS1307- ชิปนาฬิกาเรียลไทม์พร้อมอินเทอร์เฟซ I2C(TWI)- นาฬิกา/ปฏิทินจัดเก็บข้อมูลต่อไปนี้: วินาที นาที ชั่วโมง วัน วันที่ เดือน และปี วันสิ้นเดือนจะมีการปรับโดยอัตโนมัติสำหรับเดือนที่มีน้อยกว่า 31 วัน รวมถึงการปรับสำหรับด้วย ปีอธิกสุรทิน- นาฬิกาทำงานในรูปแบบ 24 ชั่วโมงหรือ 12 ชั่วโมงพร้อมตัวบ่งชี้ AM/PM DS1307 มีวงจรตรวจสอบพลังงานในตัวที่ตรวจจับการสูญเสียพลังงานและสลับวงจรไปใช้พลังงานแบตเตอรี่โดยอัตโนมัติ
วแบต- อินพุตแบตเตอรี่สำหรับเซลล์ลิเธียม 3 โวลต์มาตรฐานหรือแหล่งพลังงานอื่นๆ สำหรับการใช้งานปกติ ต้องรักษาแรงดันไฟฟ้าของแบตเตอรี่ให้อยู่ระหว่าง 2.5 ถึง 3.5 V ระดับที่ห้ามไม่ให้เข้าถึงนาฬิกาเรียลไทม์และ RAM ของผู้ใช้นั้นได้รับการตั้งค่าภายในไว้ที่ 1.25 x Vbat แบตเตอรี่ลิเธียมที่มีความจุ 35 mAh ขึ้นไปนั้นเพียงพอที่จะจ่ายไฟให้กับ DS1307 ได้นานกว่า 10 ปีหากไม่มีพลังงาน
เอสซีแอล(อินพุตนาฬิกาอนุกรม) - SCL ใช้เพื่อซิงโครไนซ์การถ่ายโอนข้อมูลผ่านอินเทอร์เฟซแบบอนุกรม
เอส.ดี.เอ.(อินพุต/เอาต์พุตข้อมูลอนุกรม) - SDA - อินพุต/เอาต์พุตข้อมูลสำหรับอินเทอร์เฟซแบบอนุกรม 2 สาย นี่คือเอาต์พุตเดรนแบบเปิดที่ต้องใช้ตัวต้านทานแบบดึงขึ้นภายนอก
ตร.ว./ออก(ไดร์เวอร์สแควร์สแควร์ / เอาท์พุต) - เมื่อบิต SQWE ถูกตั้งค่าเป็น 1 เอาต์พุต SQW/OUT จะสร้างพัลส์คลื่นสี่เหลี่ยมที่ความถี่หนึ่งในสี่ความถี่: 1 Hz, 4 kHz, 8 kHz, 32 kHz พิน SQW/OUT เป็นแบบเปิดและต้องใช้ตัวต้านทานแบบดึงขึ้นภายนอก
X1, X2- สายสำหรับเชื่อมต่อคริสตัลควอตซ์มาตรฐาน 32.768 kHz วงจรภายในของออสซิลเลเตอร์ได้รับการออกแบบให้ทำงานกับคริสตัลที่มีความจุปกติ (CL) อยู่ที่ 12.5 pF
จีเอ็นดี- โลก.
วีซีซี– แหล่งจ่ายไฟ 5 โวลต์
DS1307ทำงานเป็นอุปกรณ์ทาสบนบัสอนุกรม ในการเข้าถึงคุณจะต้องตั้งค่าสถานะ เริ่มและส่งรหัสประจำตัวอุปกรณ์ตามด้วยที่อยู่ลงทะเบียน การลงทะเบียนครั้งต่อไปสามารถเข้าถึงได้ตามลำดับจนกว่าจะมีการตั้งค่าสถานะ หยุด- เมื่อไร วีซีซีต่ำกว่า 1.25 x Vbat อุปกรณ์จะหยุดการสื่อสารและรีเซ็ตตัวนับที่อยู่ ในช่วงเวลานี้ มันจะไม่ตอบสนองต่อสัญญาณอินพุตเพื่อป้องกันการบันทึกข้อมูลที่ผิดพลาด เมื่อไร วีซีซีหากอยู่ต่ำกว่า Vbat อุปกรณ์จะสลับไปที่โหมดจัดเก็บข้อมูลพลังงานต่ำ เมื่อคุณเปิดเครื่อง อุปกรณ์จะเปลี่ยนพลังงานจากแบตเตอรี่เป็น วีซีซีเมื่อแรงดันไฟฟ้าเกิน Vbat + 0.2V และตอบสนองต่อสัญญาณอินพุตเมื่อใด วีซีซีจะกลายเป็นมากกว่า 1.25 x Vbat เมื่อพลังงานอยู่ในขีดจำกัดปกติ อุปกรณ์จะสามารถเข้าถึงได้อย่างเต็มที่และสามารถเขียนและอ่านข้อมูลได้ เมื่อเชื่อมต่อแบตเตอรี่สามโวลต์เข้ากับอุปกรณ์และ VCC ต่ำกว่า 1.25 x Vbat ห้ามอ่านและเขียน อย่างไรก็ตาม การนับถอยหลังเวลายังคงทำงานอยู่ เมื่อไร วีซีซีต่ำกว่า Vbat แหล่งจ่ายไฟ RAM และการจับเวลาจะเปลี่ยนไปใช้แบตเตอรี่ภายนอก 3 V
ข้อมูลเวลาและวันที่ได้มาจากการอ่านบันทึกที่เกี่ยวข้อง การลงทะเบียนนาฬิกาแสดงอยู่ในตารางด้านล่าง เวลาและปฏิทินถูกตั้งค่าหรือเริ่มต้นโดยการเขียนไบต์ไปยังรีจิสเตอร์ที่เหมาะสม เนื้อหาของการลงทะเบียนเวลาและปฏิทินจะถูกจัดเก็บไว้ใน BCD (บีซีดี)ดังนั้นก่อนที่จะแสดงข้อมูลบนจอ LCD หรือตัวบ่งชี้เจ็ดส่วน จำเป็นต้องแปลงรหัส BCD เป็นรหัสไบนารี่หรือ ANSII
บิต 7 ของรีจิสเตอร์ 0 คือบิต Clock Halt เมื่อบิตนี้ถูกตั้งค่าเป็น 1 ตัวสร้างจะหยุดทำงาน เมื่อรีเซ็ตเป็นศูนย์ เครื่องกำเนิดไฟฟ้าจะทำงานและนาฬิกาจะนับเวลา
DS1307 สามารถทำงานในโหมด 12 ชั่วโมงหรือ 24 ชั่วโมงได้ บิต 6 ของการลงทะเบียนนาฬิการะบุหนึ่งในโหมดเหล่านี้ เมื่อเท่ากับ 1 โหมด 12 ชั่วโมงจะถูกตั้งค่า ในโหมด 12 ชั่วโมง ระดับสูงบิต 5 ระบุเวลาบ่าย ในโหมด 24 ชั่วโมง บิต 5 คือบิตที่สอง 10 ชั่วโมง (20-23 ชั่วโมง)
รีจิสเตอร์ควบคุม DS1307 ได้รับการออกแบบมาเพื่อควบคุมการทำงานของเอาต์พุต ตร.ว./ออก- นิดหน่อย ออก- การควบคุมเอาต์พุต บิตนี้จะควบคุมระดับเอาต์พุตของพิน ตร.ว./ออกเมื่อปิดใช้งานการสร้างคดเคี้ยว ถ้า SQWE = 0 ระดับตรรกะที่พิน ตร.ว./ออกเท่ากับ 1 ถ้า ออก= 1 และ 0 - ถ้า ออก = 0. ตาราง- ความละเอียดของการคดเคี้ยว เมื่อบิตนี้ถูกตั้งค่าเป็น 1 จะมีการเปิดใช้งานการสร้างคลื่นสี่เหลี่ยม ความถี่คลื่นสี่เหลี่ยมขึ้นอยู่กับค่าของบิต RS0 และ RS1 บิตเหล่านี้จะควบคุมความถี่ของคลื่นสี่เหลี่ยมเมื่อเปิดใช้งานการสร้างคลื่น ตารางด้านล่างแสดงความถี่ที่สามารถระบุได้ด้วยบิต RS
DS1307 รองรับบัส 2 สายแบบสองทิศทางและโปรโตคอลการถ่ายโอนข้อมูล อุปกรณ์ที่ส่งข้อมูลไปยังบัสเรียกว่าเครื่องส่ง และอุปกรณ์ที่รับข้อมูลเรียกว่าเครื่องรับ อุปกรณ์ที่ควบคุมการส่งสัญญาณเรียกว่าอุปกรณ์หลัก อุปกรณ์ที่ควบคุมโดยต้นแบบนั้นเป็นอุปกรณ์รอง บัสจะต้องได้รับการควบคุมโดยมาสเตอร์ที่สร้างนาฬิกาอนุกรม (SCL) ควบคุมการเข้าถึงบัส และสร้างสถานะ START และ STOP DS1307 ทำงานเป็นทาสบนบัส 2 สาย
ในการทำงานกับ DS1307 จำเป็นต้องจัดระเบียบฟังก์ชันการอ่านจากชิปและฟังก์ชันการเขียน
1. โหมดบันทึกใน DS1307- ได้รับข้อมูลอนุกรมและนาฬิกาผ่าน SDA และ SCL หลังจากที่แต่ละไบต์ถูกส่ง บิตการตอบรับจะถูกส่งไป ถาม- รัฐ เริ่มและ หยุดได้รับการยอมรับว่าเป็นจุดเริ่มต้นและจุดสิ้นสุดของการส่งสัญญาณแบบอนุกรม การรู้จำที่อยู่จะดำเนินการในฮาร์ดแวร์หลังจากได้รับที่อยู่ทาสและบิตทิศทาง ไบต์ที่อยู่ประกอบด้วยที่อยู่เจ็ดบิตของ DS1307 ที่เป็น 1101000 ตามด้วยบิตทิศทาง (R/W) ซึ่งเป็น 0 เมื่อได้รับและถอดรหัสไบต์ที่อยู่ DS1307 จะออกการตอบรับ ถามบนสาย SDA หลังจากที่ DS1307 ยืนยันที่อยู่สเลฟและเขียนบิตแล้ว ต้นแบบจะส่งที่อยู่รีจิสเตอร์ไปยัง DS1307 นี่จะเป็นการตั้งค่าตัวชี้การลงทะเบียนใน DS1307 จากนั้นต้นแบบจะเริ่มส่งข้อมูลไบต์ไปยัง DS1307 ซึ่งจะรับทราบแต่ละไบต์ที่ได้รับ เมื่อสิ้นสุดการบันทึก ผู้นำเสนอจะสร้างสถานะ หยุด.
2. โหมดอ่านจาก DS1307- ไบต์แรกจะได้รับและประมวลผลในโหมดตัวรับทาส อย่างไรก็ตาม ในโหมดนี้ บิตทิศทางจะระบุว่าทิศทางการส่งสัญญาณเปลี่ยนไป ข้อมูลอนุกรมจะถูกส่งผ่าน SDA จาก DS1307 ในขณะที่นาฬิกาอนุกรมจะถูกส่งผ่าน SCL ไปยัง DS1307 รัฐ เริ่มและ หยุดได้รับการยอมรับว่าเป็นจุดเริ่มต้นและจุดสิ้นสุดของการส่งสัญญาณแบบอนุกรม ไบต์ที่อยู่คือไบต์แรกที่ได้รับหลังจากที่ต้นแบบสร้างสถานะแล้ว เริ่ม- ไบต์ที่อยู่ประกอบด้วยที่อยู่เจ็ดบิตของ DS1307 ที่ 1101000 ตามด้วยบิตทิศทาง (R/W) ซึ่งเป็น 1 เมื่ออ่าน เมื่อได้รับและถอดรหัสไบต์ที่อยู่แล้ว DS1307 จะออกการตอบรับ ถามบนสาย SDA จากนั้น DS1307 จะเริ่มส่งข้อมูลโดยเริ่มจากที่อยู่รีจิสเตอร์ที่ตัวชี้รีจิสเตอร์ชี้ไป หากตัวชี้การลงทะเบียนไม่ได้ถูกเขียนก่อนที่จะเริ่มโหมดการอ่าน ที่อยู่แรกที่อ่านจะเป็นที่อยู่สุดท้ายที่เหลืออยู่ในตัวชี้การลงทะเบียน DS1307 ควรได้รับการปฏิเสธ โนสค์เพื่ออ่านให้จบ
มาดูคุณสมบัติการทำงานกับ DS1307 โดยใช้ตัวอย่างนาฬิกาธรรมดาที่จะแสดงชั่วโมง นาที และวินาที ข้อมูลจะแสดงบนจอ LCD ขนาด 16x2 ปุ่มสองปุ่ม “ชั่วโมง+” และ “นาที+” จะช่วยให้คุณตั้งเวลาที่ต้องการได้ ไมโครคอนโทรลเลอร์ Atmega 8 ได้รับการโอเวอร์คล็อกจากออสซิลเลเตอร์ภายในด้วยความถี่ 1 MHz ดังนั้นอย่าลืมเปลี่ยนฟิวส์ ด้านล่างเป็นแผนภาพการเชื่อมต่อ
โปรแกรมควบคุมประกอบด้วยชุดฟังก์ชันสำหรับการทำงานกับบัส TWI, นาฬิกา DS1307 และจอ LCD
I2CInit - การเริ่มต้นบัส
I2CStart - ส่งเงื่อนไข START;
I2CStop - การส่งเงื่อนไข STOP;
I2CWriteByte - เขียนข้อมูล
I2CReadByte - อ่านข้อมูล
DS1307Read - ฟังก์ชั่นสำหรับอ่านข้อมูลจาก DS1307;
DS1307Write - ฟังก์ชั่นสำหรับเขียนข้อมูลไปยัง DS1307;
lcd_com - การส่งคำสั่งไปยัง LCD;
lcd_data - ถ่ายโอนข้อมูลไปยัง LCD;
lcd_string - ฟังก์ชั่นแสดงสตริงบนจอ LCD
lcd_num_to_str - ฟังก์ชั่นสำหรับส่งออกอักขระประเภท int;
lcd_init - การเริ่มต้น LCD
ด้านล่างเป็นรหัสโปรแกรม:
#รวม
ธีมของนาฬิกาบนชิป DS1307 ค่อนข้างเกี่ยวข้อง - เป็นอุปกรณ์ที่เรียบง่าย แต่ในขณะเดียวกันก็น่าสนใจ นอกจากนี้ยังมีประโยชน์จริงๆ แต่ไม่มีประเด็นใดที่จะอธิบายไมโครวงจรแยกกันดังนั้นฉันจึงตัดสินใจประกอบอุปกรณ์ที่คล้ายกันสำหรับตัวเองและในขณะเดียวกันก็พูดคุยเกี่ยวกับสิ่งที่ฉันได้รับในกระบวนการนี้ ฉันจะอธิบายกระบวนการพัฒนาและการประกอบในขณะที่เราผ่านขั้นตอนบางส่วนของความพร้อมของอุปกรณ์
อัปเดต 10/17/2558
ตอนแรกมันเป็นชุดบทความโดยมีวัตถุประสงค์เพื่อพูดคุยเกี่ยวกับการสร้างอุปกรณ์ตั้งแต่เริ่มต้นจนถึงสถานะสำเร็จรูป แต่ทันใดนั้นฉันก็แพ้สิ่งที่เรียกว่า "นาฬิกา" ดังนั้นฉันจึงรวมทุกอย่างไว้ในบทความเดียว เครื่องสมบูรณ์ 99.9% (เหลือแค่ขันน็อตให้แน่น) แต่ก็ทำไม่ยาก :) พอหายภูมิแพ้ก็จะมีภาพสุดท้ายมาครับ
เริ่มจากข้อเท็จจริงที่ว่าจนถึงตอนนี้เราไม่รู้อะไรเลยเกี่ยวกับ ds1307 ยกเว้นว่านาฬิกานั้นผลิตขึ้นโดยใช้ความช่วยเหลือ ดังนั้นให้ดาวน์โหลดเอกสารสำหรับไมโครวงจรนี้และอ่านรายการ "สารพัด" ที่มี ดังนั้นจากย่อหน้าแรกโดยทั่วไปจะชัดเจนว่าใช้พลังงานต่ำ ข้อมูลจะถูกส่งผ่าน I2C คุณสามารถค้นหาวันที่และเวลา รูปแบบ 12 และ 24 ชั่วโมง การปรับวันที่อัตโนมัติ แต่สิ่งที่น่าสนใจที่สุดคือวงจร (TYPICAL OPERATING CIRCUIT)
เราสูบบุหรี่ในเอกสารข้อมูลและพยายามค้นหาว่าอะไรคืออะไร เราไปจากซ้ายไปขวา CPU - ไมโครคอนโทรลเลอร์ (นั่นคือ atmega ของเรา) ตัวต้านทานสองตัวมันบอกว่าดึงขึ้น - นั่นหมายถึงดึงขึ้น (คุณสามารถใช้แต่ละตัวได้ 10k) ควอตซ์ที่ 32768 Hz ไมโครวงจรเองและแบตเตอรี่ เอาต์พุต SQW/OUT สามารถกระโดดด้วยความถี่ 1Hz, 4kHz, 8kHz, 32kHz ตราบใดที่เราไม่สนใจสิ่งนี้ บางทีข้อมูลนี้อาจเพียงพอแล้วในตอนนี้ ฉันต้องการเขียนโค้ดบางอย่าง :)
เราสร้างโปรเจ็กต์ใน CodeVision ค้นหา ds1307 ในส่วน I2C และรวมไว้ในโปรเจ็กต์ คงจะดีถ้าแสดงข้อมูลที่ไหนสักแห่ง เช่น บนจอ LCD และปุ่มสองสามปุ่มก็ไม่เสียหาย
สิ่งที่คุณต้องมีคือกำหนดค่า LCD สำหรับพอร์ต D และปุ่มดึงขึ้นสามปุ่มสำหรับอินพุต ต่อไป เราต้องแสดงเวลาบนจอ LCD เพื่อที่จะทำเช่นนี้ มาดูคู่มือ CodeVision และยกตัวอย่างจากตรงนั้น ปรากฎว่าทุกอย่างง่าย - มีฟังก์ชั่นที่ตั้งเวลา:
rtc_set_time(3,0,0); //ตั้ง 03:00:00
เหล่านั้น. หลังจากเรียกใช้ฟังก์ชันนี้ ตัวแปร h, m, s จะมีชั่วโมง (h) นาที (m) และวินาที (s) สิ่งที่เหลืออยู่ก็คือการแสดงมันบนหน้าจอ นี่คือสิ่งที่เรารู้วิธีการทำ)
รหัสสุดท้ายจะมีลักษณะดังนี้:
#รวม |
-
ถ่าน lcd_buf; เป็นโมฆะหลัก (โมฆะ) (ถ่านชั่วโมง, นาที, sek; PORTC = 0x07; DDRC = 0x00; // การเริ่มต้นบัส I2C i2c_init (); // DS1307 การเริ่มต้นนาฬิกาเวลาจริง rtc_init (0,0,0); // โมดูล LCD การเริ่มต้น lcd_init(16); rtc_set_time(3,0,0); ในขณะที่ (1) ( rtc_get_time(&ชั่วโมง,&นาที,&sek); lcd_clear(); lcd_gotoxy(0,0); sprintf(lcd_buf,"%2d:%02d :%02d\n",ชั่วโมง,นาที,วินาที); lcd_puts(lcd_buf); Delay_ms(500); ); )
เราประกอบและทดสอบใน Proteus:
เราจะทำการอัพเกรดเฟิร์มแวร์ของเราต่อไป เริ่มจากแนวคิดต่อไปนี้: DS1307 มีเอาต์พุต SQW/OUT ที่สามารถสร้างความถี่ได้หลายความถี่ หากคุณตั้งค่าเอาต์พุตนี้เป็น 1Hz และใช้สัญญาณนี้กับอินพุตอินเทอร์รัปต์ภายนอก ปรากฎว่า 1307 จะดึง "ส่วนท้าย" ของ atmega8 ของเราทุกๆ วินาที สำหรับเมก้านี้จะเป็นสัญญาณว่าถึงเวลาที่ต้องอัพเดตเวลาแล้ว สิ่งนี้จะช่วยให้คุณไม่ต้องโหลดไมโครคอนโทรลเลอร์ด้วยการอัพเดตเวลาอย่างต่อเนื่อง ข้อมูลเกี่ยวกับเวลาปัจจุบันจะได้รับการอัปเดตอย่างแน่นอนหนึ่งครั้งต่อวินาที
มาเพิ่มการขัดจังหวะระดับต่ำภายนอกให้กับโปรเจ็กต์บนพิน Int1 แล้วเปิดการดึงขึ้น มาตั้งค่าเอาต์พุต DS1307 ให้เป็นความถี่ 1Hz อย่างไรก็ตามการอ่านคู่มือมีประโยชน์ฉันพบคุณสมบัติที่น่าสนใจ - ตัวต้านทานแบบดึงขึ้นที่ขา SCL และ SDA ควรเป็น 3.3k - 4.7k ลองพิจารณาเรื่องนี้ดู
รหัสผลลัพธ์จะมีลักษณะดังนี้:
ขัดจังหวะ [ EXT_INT1] เป็นโมฆะ ext_int1_isr (โมฆะ ) ( time_flag= 1 ; ) |
ขัดจังหวะเป็นโมฆะ ext_int1_isr (เป็นโมฆะ) ( time_flag=1; )
ในการขัดจังหวะเราตั้งค่าสถานะที่อนุญาตเอาต์พุตเวลา ในลูปหลัก หากตั้งค่าสถานะไว้ เราจะแสดงเวลา หากไม่ได้ตั้งค่าไว้ เราจะไม่ทำอะไรเลย
if (time_flag== 1 ) ( rtc_get_time(& ชั่วโมง,& นาที,& sek) ; lcd_gotoxy(0 , 0 ) ; sprintf (lcd_buf, "%02d:%02d:%02d \n", ชั่วโมง, นาที, เสก) ; lcd_puts(lcd_buf) ; - |
if(time_flag==1) ( rtc_get_time(&ชั่วโมง&นาที&sek); lcd_gotoxy(0,0); sprintf(lcd_buf,"%02d:%02d:%02d\n",ชั่วโมง,นาที,sek); lcd_puts( จอแอลซีดี_buf)
ตอนนี้เรามาดูคำถามถัดไป: การใช้ sprintf มีประสิทธิภาพเพียงใด? เพื่อไม่ให้เริ่มการสนทนาที่ว่างเปล่า ฉันจะให้โค้ด 2 ชิ้นที่ทำสิ่งเดียวกัน - แสดงข้อมูลเวลาบนหน้าจอ
ตัวเลือกแรกที่เรารู้จักแล้ว:
วิ่ง (lcd_buf, "%02d:%02d:%02d \n", ชั่วโมง, นาที, เสก) ; lcd_puts(lcd_buf) ; |
sprintf(lcd_buf,"%02d:%02d:%02d\n",ชั่วโมง,นาที,วินาที); lcd_puts(lcd_buf);
เห็นด้วย ใช้งานง่ายและชัดเจน ตอนนี้ตัวเลือกหมายเลข 2:
lcd_putchar(ชั่วโมง/ 10 + 0x30 ) ; lcd_putchar(ชั่วโมง% 10 + 0x30 ) ; lcd_putchar(/// ) ; lcd_putchar(นาที/ 10 + 0x30 ) ; lcd_putchar(ขั้นต่ำ% 10 + 0x30 ) ; lcd_putchar(/// ) ; lcd_putchar(sek/ 10 + 0x30 ) ; lcd_putchar(sek% 10 + 0x30 ) ; |
lcd_putchar(ชั่วโมง/10+0x30); lcd_putchar(ชั่วโมง%10+0x30); lcd_putchar(///); lcd_putchar(นาที/10+0x30); lcd_putchar(ขั้นต่ำ%10+0x30); lcd_putchar(///); lcd_putchar(วินาที/10+0x30); lcd_putchar(วินาที%10+0x30);
มันไม่ชัดเจนมาก แต่คุณสามารถเข้าใจได้ เราจะเปรียบเทียบพวกเขาอย่างไร? สิ่งนี้ทำได้ง่ายมาก - เปิดตัวดีบักเกอร์ AVR STUDIO และดูจำนวนรอบสัญญาณนาฬิกาที่ใช้ในการดำเนินการ ดังนั้น ดรัมโรล ผลลัพธ์... โค้ดชิ้นแรกวิ่งไปที่ 16,466 รอบนาฬิกา ซึ่งเทียบเท่ากับ 2,058.25 μs ที่ความถี่ในการทำงาน 8 MHz สำหรับโค้ดชิ้นที่สอง ตัวเลขนี้คือ 12,278 รอบนาฬิกา หรือ 1,534.75 ไมโครวินาที เห็นด้วยการลดเวลาดำเนินการและลดไมโครคอนโทรลเลอร์ลงประมาณ 25% จึงเป็นเหตุผลที่ดีพอที่จะไม่ใช้ sprintf เราละทิ้ง sprintf ออกจากโปรเจ็กต์ของเรา ตามด้วย stdio.h และ lcd_buf
มันน่าเกลียดเมื่อลูปหลักมีโค้ดที่ผิดพลาด ดังนั้นเอาต์พุตของข้อมูลจึงสามารถยัดลงในฟังก์ชันได้ ในวงหลักจะยังคงอยู่
ในขณะที่ (1) ( ถ้า (time_flag== 1) ( show_time() ; //แสดงข้อมูลเกี่ยวกับเวลาปัจจุบัน } } ; |
ในขณะที่ (1) ( if(time_flag==1) ( show_time(); //แสดงข้อมูลเกี่ยวกับเวลาปัจจุบัน) );
การประกาศฟังก์ชันจะมีลักษณะดังนี้:
ถือเป็นโมฆะ show_time() ( rtc_get_time(& ชั่วโมง,& นาที,& sek) ; lcd_gotoxy(0 , 0 ) ; lcd_putchar(ชั่วโมง/ 10 + 0x30 ) ; lcd_putchar(ชั่วโมง% 10 + 0x30 ) ; lcd_putchar(:) ) ; lcd_putchar (ต่ำสุด/ 10 + 0x30 ) ; lcd_putchar(///) ; lcd_putchar(sek/ 10 + 0x30 ) ; |
เป็นโมฆะ show_time() ( rtc_get_time(&ชั่วโมง,&นาที,&sek); lcd_gotoxy(0,0); lcd_putchar(ชั่วโมง/10+0x30); lcd_putchar(ชั่วโมง%10+0x30); lcd_putchar(″); lcd_putchar(min/ 10+0x30); lcd_putchar(ขั้นต่ำ%10+0x30); lcd_putchar(วินาที/10+0x30);
ตอนนี้เราต้องเพิ่มเอาต์พุตวันที่ให้กับเฟิร์มแวร์ของเรา วันที่ถูกตั้งค่าโดยใช้ฟังก์ชันต่อไปนี้:
rtc_set_date(6,13,10,13); //6 - วันในสัปดาห์, 13 - วัน, 10 - เดือน, 13 - ปี
rtc_get_date(&week_day,&วัน,&เดือน,&ปี); //วันในสัปดาห์ วัน เดือน ปี
สามารถจัดระเบียบเอาต์พุตวันที่ได้จนถึงตอนนี้ในลูปหลักถัดจากเวลาซอร์สโค้ดแบบเต็มจะเป็นดังนี้:
#รวม |
-
ผลลัพธ์:
วงจรและเฟิร์มแวร์:
มาดูการจัดเมนูกันดีกว่า คำถามที่สำคัญที่สุดคือทุกอย่างควรมีลักษณะอย่างไร เช่น จำเป็นต้องกำหนดข้อกำหนดทางเทคนิค (t.z.)
ฉันต้องการให้สิ่งเหล่านี้เป็นหน้าจอแยกกัน:
-หน้าจอหลัก;
-หน้าจอตั้งเวลา;
-หน้าจอการตั้งค่าวันที่;
- หน้าจอการตั้งค่านาฬิกาปลุก
ในกรณีนี้คุณสามารถใช้ปุ่มสี่ปุ่ม - ขึ้น, ลง, ซ้าย, ขวา การสลับระหว่างหน้าจอควรทำโดยใช้ปุ่มขึ้นและลง การตั้งค่าจะทำบนหน้าจอที่เกี่ยวข้อง ไมโครคอนโทรลเลอร์ที่ใช้คือ atmega8 นี่เป็นศัพท์ทางเทคนิคดั้งเดิม
ชัดเจนตั้งแต่แรกแล้วว่าขนาดโค้ดจะค่อนข้างใหญ่ ในเวลาเดียวกัน จำเป็นต้องแยกย่อยออกเป็นส่วน ๆ ที่เชื่อมโยงกันอย่างมีเหตุผล ทุกอย่างชัดเจนในส่วนต่างๆ - การประมวลผลหนึ่งหน้าจอเป็นส่วนหนึ่งของโค้ด ดังนั้นฉันจึงเริ่มต้นด้วยการแบ่งลูปหลักออกเป็นสี่ส่วน โดยสลับระหว่างลูปซึ่งดำเนินการโดยคำสั่ง switch ฉันใส่ฟังก์ชั่นเข้าไปข้างใน - หุ่นจำลอง ปุ่ม 0(ขึ้น) และ 3(ลง) บนพอร์ต C ช่วยให้คุณสามารถเปลี่ยนตัวแปรเมนูได้ ดังนั้นเราจึงข้ามไปมาระหว่างเมนูต่างๆ แต่จนถึงขณะนี้เฟิร์มแวร์ดังกล่าวไม่สามารถทำงานได้เนื่องจากยังไม่ได้กำหนดฟังก์ชันไว้
ในขณะที่ (1) ( สวิตช์ (เมนู) ( case 0 : show_time(); break ; case 1 : set_time() ; break ; case 2 : set_date() ; break ; case 3 : set_alarm() ; break ; ) ) ; |
ในขณะที่ (1) ( สวิตช์(เมนู) ( กรณีที่ 0: show_time(); แตก; กรณีที่ 1: set_time(); แตก; กรณีที่ 2: set_date(); แตก; กรณีที่ 3: set_alarm(); แตก; ) );
ขั้นตอนต่อไปคือการกำหนดฟังก์ชันเหล่านี้ ในตอนแรกฉันวาดชื่อคงที่ เช่น lcd_puts("Set time"); ฟังก์ชั่นกลายเป็นเช่นนี้
เป็นโมฆะ set_alarm () ( ///////// ดูการตั้งค่าการเตือน lcd_gotoxy (0,0); lcd_puts ("ตั้งค่าการเตือน"); ) เป็นโมฆะ set_time () ( //////// ดูการตั้งค่าเวลา lcd_gotoxy ( 0,0); lcd_puts("ตั้งเวลา");
ตอนนี้เฟิร์มแวร์ใช้งานได้แล้วซึ่งคุณสามารถสลับระหว่างเมนูและดูป้ายกำกับแบบคงที่ได้ ถึงเวลาที่จะทำให้สัญญาณเหล่านี้มีชีวิตขึ้นมา ไม่มีปัญหากับหน้าจอหลัก การแสดงเวลา/วันที่คล้ายกับบทเรียนก่อนหน้า
คำถามต่อไปเกิดขึ้น: จะจัดระเบียบกระบวนการตั้งค่าได้อย่างไร? หลังจากคิดดูแล้ว แนวคิดต่อไปนี้ดูน่าสนใจสำหรับฉัน เราใช้ปุ่มขึ้น/ลงเพื่อไปยังเมนูที่เราสนใจ กดไปทางขวา เคอร์เซอร์จะปรากฏขึ้น เพื่อแจ้งให้เราทราบว่ากระบวนการตั้งค่าอยู่ระหว่างดำเนินการ การใช้ปุ่มขึ้น/ลงทำให้เราเปลี่ยนค่า ซ้าย/ขวาเราเลื่อนเคอร์เซอร์ระหว่างพารามิเตอร์ที่ปรับได้ เมื่อเคอร์เซอร์อยู่ใต้พารามิเตอร์สุดท้าย การกดปุ่มขวาอีกครั้งจะออกจากการตั้งค่า เคอร์เซอร์หายไปซึ่งแสดงว่าเราได้ออกจากการตั้งค่าและสามารถสลับระหว่างเมนูได้อีกครั้ง
แต่มีปัญหาเล็กน้อย เช่น ปุ่มขึ้นควรเปลี่ยนพารามิเตอร์และสลับหน้าจอถัดไปไปพร้อมๆ กัน เหล่านั้น. ตรรกะของปุ่มต่างๆ ภายในหน้าจอเดียวจะต้องถูกแยกออกจากกัน ด้วยเหตุนี้โค้ดจึงมีการเติบโตอย่างมาก ตัวอย่างเช่นบนหน้าจอนาฬิกาปลุกเราเข้าสู่รูทีนย่อยการตั้งค่า (sub_alarm) ตามลำดับปุ่มภายในรูทีนย่อยจะถูกประมวลผลด้วยวิธีเดียวและภายนอกในอีกทางหนึ่ง
เป็นโมฆะ set_alarm() // ฟังก์ชั่นการประมวลผลสัญญาณเตือน ( // โหมดการแสดงผลของเมนูการตั้งค่าการเตือน if(sub_alarm==0) ( if(PINC.0==0) // ปุ่มขึ้น - เปลี่ยนหน้าจอเมนู ( เมนู=0; ... .. ) ) //เมนูย่อยสำหรับการตั้งค่าการเตือน if(sub_alarm==1) ( if(PINC.0==0) // ปุ่มขึ้น - เพิ่มค่า ( a_hour++; .... ) )
นอกจากนี้ยังมีช่วงเวลาที่คุณไปที่เมนูย่อยการตั้งค่าและปุ่มเดิม (ลองใช้ปุ่มขึ้นอีกครั้งเป็นตัวอย่าง) สามารถเปลี่ยนชั่วโมงหรืออาจเป็นนาทีได้ ดังนั้นจึงมีการแนะนำโปรแกรมย่อยตัวแปรอื่น
ตัวอย่างเช่น:
if(PINC.0==0) // ปุ่มขึ้น ( if(subProgram==1) //subProgram=1 - เปลี่ยนนาฬิกา ( a_hour++; ... ) if(subProgram==2) //subProgram=2 - เปลี่ยนนาที ( a_min++; ... ) if(subProgram==3) //subProgram=3 เปลี่ยนการตั้งค่าสถานะการเตือน ( ... ) )
สิ่งเดียวที่ควรกล่าวถึงคือสัญลักษณ์พิเศษที่แสดงบนหน้าจอหลักเมื่อเปิดนาฬิกาปลุก
ตัวอย่างนี้นำมาจากตัวอย่างในโฟลเดอร์ถ่าน CodeVision\examples\lcd
typedef ถ่านไบต์ที่ไม่ได้ลงนาม; //กำหนดประเภทใหม่แฟลชไบต์ char_table[ 8 ] = ( //วาดสัญลักษณ์ของคุณ 0b10000000, 0b10000100, 0b10001110, 0b10001110, 0b10001110, 0b10011111, 0b10100100, 0b11000000); // ฟังก์ชันที่ใช้กำหนดอักขระของผู้ใช้เป็นโมฆะกำหนด_char (ไบต์แฟลช * pc, ไบต์ char_code) ( ไบต์ i, ที่อยู่; ที่อยู่ = (char_code<< 3 ) | 0x40 ; for (i= 0 ; i< 8 ; i++ ) lcd_write_byte(address++,* pc++ ) ; } void main(void ) { byte i, address; lcd_init(16 ) ; define_char(char_table, 0 ) ; //โหลดสัญลักษณ์ลงใน LSDในขณะที่ (1) ( lcd_putchar(0) ; //แสดงสัญลักษณ์ } |
typedef ถ่านไบต์ที่ไม่ได้ลงนาม; // กำหนดประเภทแฟลชใหม่ char_table=( // วาดตัวละครของคุณ 0b10000000, 0b10000100, 0b10001110, 0b10001110, 0b10001110, 0b10011111, 0b10100100, 0b11000000); // ฟังก์ชั่นที่ใช้ในการกำหนดอักขระผู้ใช้ void Define_char(byte flash *pc,byte char_code) ( byte i,address; address=(char_code<<3)|0x40; for (i=0; i<8; i++) lcd_write_byte(address++,*pc++); } void main(void) { byte i,address; lcd_init(16); define_char(char_table,0); //Грузим символ в лсд while(1) { lcd_putchar(0); //выводим символ на дисплей }
คุณสามารถวาดสัญลักษณ์ขนาด 5x7 ได้ สัญลักษณ์หนึ่งหมายถึงพิกเซลเต็มแล้ว ศูนย์หมายถึงไม่ได้เติมเข้าไป ผลที่ได้คือสัญลักษณ์ระฆัง
เฟิร์มแวร์
ขั้นตอนต่อไปคือการคิดถึงรูปลักษณ์ของอุปกรณ์ ในความคิดของฉันมันจะเป็นหน้าจอ LCD และปุ่มสี่ปุ่มที่ด้านหน้าภายในจะมีแผงวงจรพิมพ์ซึ่งจะมีองค์ประกอบอื่น ๆ ทั้งหมดอยู่ พลังงานจะมาจากแหล่งจ่ายไฟคล้ายกับที่ชาร์จจากจีน
เริ่มจากแผงวงจรพิมพ์กันก่อน ซึ่งต้องใช้โปรแกรมที่ให้คุณวาดตราสัญลักษณ์ได้ มีโปรแกรมที่คล้ายกันมากมาย: P-cad, Altium, เค้าโครง Sprint... ฉันชอบ Altium เพียงเพราะมีไลบรารีสำเร็จรูปพร้อมองค์ประกอบมากมายเพราะในความคิดของฉัน การใช้เวลาในการสร้างไลบรารีองค์ประกอบของคุณเองนั้นไม่ได้ จุด ความหมายทั่วไปของโปรแกรมทั้งหมดนั้นเหมือนกัน - ขั้นแรกให้วาดวงจรไฟฟ้า
ในการติดตามองค์ประกอบทั้งหมดรู้อยู่แล้วว่าควรเชื่อมต่อกับส่วนใดด้วยวงจรไฟฟ้า
สิ่งที่เหลืออยู่คือการจัดองค์ประกอบให้สะดวกและเชื่อมต่อกับตัวนำ
ความคิดเห็นเกี่ยวกับนาฬิกาเรือนนี้บนอินเทอร์เน็ตมีความขัดแย้งมากที่สุด บางคนบอกว่านาฬิกาเรือนนี้วิเศษมาก ในขณะที่บางคนเรียกว่าเป็นผลงานการสร้างสรรค์ของดัลลัสที่น่าสงสาร ดังนั้น เพื่อขจัดข่าวลืออันเป็นเท็จทั้งหมด ฉันจึงนำมิครูคาออกจากคลังและเริ่มทำการทดลอง
ลักษณะเฉพาะ:
- การใช้พลังงานต่ำมาก ผู้ผลิตรับประกันการใช้งานนาฬิกาเป็นเวลา 10 ปีโดยใช้แบตเตอรี่มาตรฐานหนึ่งก้อน CR2032
- หน่วยความจำ 56 ไบต์สำหรับจัดเก็บข้อมูลผู้ใช้ ฉันคิดว่านี่ไม่ใช่ตัวเลือกที่จำเป็นอย่างยิ่ง แต่อาจเป็นประโยชน์กับใครบางคน
- เอาต์พุตที่ตั้งโปรแกรมได้สำหรับการตอกบัตรอุปกรณ์ภายนอก สามารถส่งสัญญาณออกได้ 1 Hz, 4.096 kHz, 8.192 kHz และ 32.768 kHz
- โหมด 24 ชั่วโมง และ 12 ชั่วโมง
พินเอาท์
หมุดนาฬิกามีดังต่อไปนี้:
X1, X2— หมุดสำหรับเชื่อมต่อเครื่องสะท้อนควอทซ์ที่ความถี่ 32.768 kHz
วทท— เอาต์พุตสำหรับเชื่อมต่อแบตเตอรี่สำรองขนาด 3 โวลต์
จีเอ็นดี- โลก
เอส.ดี.เอ.- สายข้อมูลบัส i2c
เอสซีแอล- สายนาฬิกาบัส i2c
ตร.ว./ออก– สัญญาณเอาท์พุตสำหรับการตอกบัตรอุปกรณ์ภายนอก
วีซีซี- แหล่งจ่ายไฟ 5 โวลต์
การเชื่อมต่อกับคอนโทรลเลอร์
ความผูกพันมีน้อย คุณจะต้องใช้ควอตซ์ 32.768 kHz ตัวต้านทาน 1 ตัวเพื่อใช้งานบัส i2c และแบตเตอรี่ 3 โวลต์
เค้าโครงบอร์ดที่ถูกต้อง
ความแม่นยำของนาฬิกาและประสิทธิภาพของนาฬิกาโดยทั่วไปนั้นขึ้นอยู่กับโครงร่างของแผงวงจรพิมพ์ ดัลลัสในเอกสารข้อมูลของเขาแนะนำให้ลดความยาวของตัวนำจากวงจรไมโครไปจนถึงตัวสะท้อนควอทซ์ให้เหลือน้อยที่สุด และล้อมรอบตัวนำเหล่านี้ด้วยสี่เหลี่ยมผืนผ้าที่เชื่อมต่อกับกราวด์ นอกจากนี้เพื่อความน่าเชื่อถือ ฉันบัดกรีสายไฟที่ต่อลงกราวด์กับตัวเรือนควอทซ์ และวางตัวเก็บประจุ 0.1 uF ขนานกับแหล่งจ่ายไฟ
อย่างไรก็ตามมันสามารถทำงานได้โดยไม่ต้องใช้ควอตซ์ ในการดำเนินการนี้ สัญญาณนาฬิกาภายนอกที่มีความถี่ 32.768 kHz จะถูกส่งไปยังขา X1 และ X2 ยังคงลอยอยู่ในอากาศ
การจัดระเบียบหน่วยความจำนาฬิกา
อุปกรณ์ขนาดเล็กนี้มีหน่วยความจำขนาด 64 ไบต์ แปดไบต์แรกกำลังทำงาน พวกเขาจัดเก็บเวลา, วันที่, วันในสัปดาห์ ส่วนที่เหลือจะถูกจัดสรรตามความต้องการของผู้ใช้ ตัวอย่างเช่น คุณสามารถจัดเก็บการตั้งค่าบางอย่างหรืออย่างอื่นไว้ในนั้นได้ โดยปกติแล้วเมื่อพลังงานสำรองหายไป ข้อมูลทั้งหมดในหน่วยความจำนี้จะถูกทำลาย การทำงานกับนาฬิกาทั้งหมด (การอ่านและการตั้งเวลา/วันที่) ขึ้นอยู่กับการอ่านและการเขียนเซลล์หน่วยความจำที่จำเป็น
ตัวเลขทั้งหมดในหน่วยความจำจะถูกจัดเก็บในรูปแบบทศนิยมไบนารี ซึ่งหมายความว่าสามารถจัดเก็บตัวเลขสองหลักในหนึ่งไบต์ได้ ตัวอย่างเช่น หมายเลข 0x23 ประกอบด้วยหมายเลข 2 และหมายเลข 3 สำหรับแต่ละหมายเลข จะมีการจัดสรร 4 บิต เหตุใดจึงทำเช่นนี้? เพื่อความสะดวกและประหยัดหน่วยความจำ นอกเหนือจากเวลาและวันที่แล้ว การตั้งค่าหลายบิตยังถูกจัดเก็บไว้ในหน่วยความจำ:
- นาฬิกาหยุด- ควบคุมนาฬิกา เมื่อบิตถูกตั้งค่า นาฬิกาจะหยุดเดิน ในการเริ่มนาฬิกาคุณต้องเขียน 0 ไปที่บิตนี้ หลังจากเชื่อมต่อแบตเตอรี่สำรองแล้ว บิตนี้จะถูกตั้งค่าและนาฬิกาจะไม่นับเวลา! คุณต้องจำสิ่งนี้
- 24/12 - บิตนี้สำหรับเลือกโหมดนาฬิกา เมื่อบิตนี้เท่ากับหนึ่ง ระบบจะใช้โหมด 12 ชั่วโมง มิฉะนั้น 24 ชม. หากใช้โหมด 12 ชั่วโมง บิตที่ 5 จะระบุ AM หรือ PM ทันที ถ้าบิตเป็น 1 แสดงว่า PM ในโหมด 24 ชั่วโมง บิตนี้ใช้เพื่อจัดเก็บเวลาหลายสิบชั่วโมงร่วมกับบิต 4
- เอาท์พุต— ควบคุมสถานะของขา SQW/OUT บิตถูกตั้งค่า - บันทึกอยู่ที่ขา 1 รีเซ็ต - ที่ขา 0 เพื่อควบคุมด้วยวิธีนี้บิต ตารางจะต้องรีเซ็ต
- ตาราง- เมื่อตั้งค่าบิตแล้ว พัลส์สี่เหลี่ยมจะปรากฏบนขา SQW/OUT
- RS1, RS0— บิตเหล่านี้จะตั้งค่าความถี่พัลส์ การขึ้นต่อกันของความถี่ของชุดบิตอยู่ในตารางด้านล่าง:
ซอฟต์แวร์
ในการทำงานกับนาฬิกา DS1307 ได้มีการเขียนไลบรารีอย่างง่ายที่มีฟังก์ชันพื้นฐานดังต่อไปนี้:
DS_start— เริ่มนาฬิกา คุณยังสามารถเริ่มนาฬิกาได้ด้วยการตั้งเวลา
ดีเอส_สต็อป- หยุดนาฬิกา
DS_set_time —การตั้งเวลา ก่อนที่จะเรียกโพรซีเดอร์ คุณต้องใส่วินาทีใน tmp1 นาทีใน tmp2 และชั่วโมงใน tmp3 นาฬิกาในรูปแบบ 24 ชั่วโมง
DS_get_time: —อ่านเวลาจากนาฬิกา วินาทีจะถูกบันทึกเป็น tmp1 นาทีเป็น tmp2 ชั่วโมงเป็น tmp3
DS_get_date:— อ่านวันที่จากนาฬิกา วันจะถูกบันทึกเป็น tmp1 เดือนเป็น tmp2 ปีเป็น tmp3
DS_set_date: —การตั้งวันที่ ก่อนที่จะเรียกขั้นตอนนี้ คุณต้องใส่วันใน tmp1, เดือนใน tmp2 และปีใน tmp3 (ตัวเลข 2 หลักสุดท้าย)
กิจวัตรสำหรับการตั้งค่า/อ่านเวลาและวันที่สามารถรับ/ส่งคืนข้อมูลอินพุตในรูปแบบ BCD และทศนิยม ในการเลือกรูปแบบที่ต้องการ คุณจะต้องแสดงความคิดเห็นหรือไม่ใส่เครื่องหมายข้อคิดเห็นสามบรรทัดในแต่ละขั้นตอน (มีหมายเหตุเกี่ยวกับสิ่งนี้ในโค้ด)
โปรแกรมทดสอบช่วยให้คุณควบคุมนาฬิกาผ่าน UART (ความเร็ว 9600 คอนโทรลเลอร์ทำงานที่ 8 MHz) เมื่อเริ่มต้น เวลา วันที่ และข้อความแจ้งให้ป้อนคำสั่งตั้งแต่ 1 ถึง 3 จะปรากฏขึ้นทันที เมื่อคุณเลือกตัวเลือก 1 เวลา/วันที่จะถูกอ่านอีกครั้ง ตัวเลือกที่ 2 ให้คุณตั้งเวลา และตัวเลือกที่ 3 วันที่ หากคุณต้องการลองเล่นกับนาฬิกา ไฟล์จำลองจะรวมอยู่ในไฟล์เก็บถาวรต้นทาง
ความแม่นยำ
ส่วนใหญ่ขึ้นอยู่กับควอตซ์ที่ใช้และโครงร่างของบอร์ด เอกสารข้อมูลรายงานว่าความจุของควอตซ์ควรอยู่ที่ 12.5 pF พวกเขาบอกว่าควรใช้คริสตัลจากมาเธอร์บอร์ดดีที่สุด เพื่อแก้ไขจังหวะ คุณสามารถบัดกรีตัวเก็บประจุแบบทริมมิงเข้ากับตัวสะท้อนเสียงและใช้เพื่อเปลี่ยนความถี่ภายในขีดจำกัดเล็กๆ โดยส่วนตัวแล้ว นาฬิกาเรือนนี้ใช้งานได้สำหรับฉันมาสองวันแล้วและช้ากว่า 3 วินาที มีบางอย่างบอกฉันว่าปัญหาอยู่ที่ความสามารถของควอตซ์ ฉันจะลองอีกครั้งแล้วรายงานกลับ
บทสรุป
ไม่ใช่นาฬิกาที่ไม่ดี เหมาะสำหรับมือสมัครเล่น แม้ว่าบางคนจะเขียนเกี่ยวกับข้อบกพร่อง แต่ฉันยังไม่เคยเจอมันเลย
DS1307 เป็นโมดูลขนาดเล็กที่ออกแบบมาเพื่อการนับเวลา ประกอบขึ้นโดยใช้ชิป DS1307ZN และใช้พลังงานจากแบตเตอรี่ลิเธียม (LIR2032) ซึ่งช่วยให้ทำงานอัตโนมัติได้เป็นเวลานาน นอกจากนี้ในโมดูลยังมีหน่วยความจำ EEPROM แบบไม่ลบเลือนขนาด 32 KB (AT24C32) ไมโครวงจร AT24C32 และ DS1307ZN เชื่อมต่อกันด้วยบัสทั่วไปโดยใช้อินเทอร์เฟซ I2C
ข้อกำหนดทางเทคนิค
แรงดันไฟฟ้า: 5V
อุณหภูมิในการทำงาน: – 40°C … + 85°C
หน่วยความจำ: 56 ไบต์ (ไม่ลบเลือน)
แบตเตอรี่ :
LIR2032 (การตรวจจับแหล่งพลังงานอัตโนมัติ)
อินเทอร์เฟซ: I2C
ขนาด: 28มม.x 25มม.x 8มม
ข้อมูลทั่วไป
การใช้โมดูล DS1307 มักจะมีความสมเหตุสมผล เช่น เมื่อข้อมูลถูกอ่านน้อยครั้ง เป็นระยะเวลานานกว่าหนึ่งสัปดาห์ การใช้ทรัพยากรของตัวควบคุมจะไม่มีเหตุผลหรือเป็นไปไม่ได้ ตัวอย่างเช่น การให้พลังงานอย่างต่อเนื่องแก่บอร์ด Arduino เป็นเวลานานนั้นมีราคาแพงแม้ว่าจะใช้แบตเตอรี่ก็ตาม
ด้วยหน่วยความจำและความเป็นอิสระของตัวเอง ทำให้สามารถบันทึกเหตุการณ์ (ด้วยแหล่งจ่ายไฟอัตโนมัติ) เช่น การเปลี่ยนแปลงของอุณหภูมิ และอื่นๆ ข้อมูลจะถูกเก็บไว้ในหน่วยความจำและสามารถอ่านได้จากหน่วยความจำของโมดูล ดังนั้นโมดูล DS1307 จึงมักใช้เมื่อตัวควบคุม Arduino จำเป็นต้องทราบเวลาที่แน่นอน เพื่อทริกเกอร์เหตุการณ์บางอย่าง และอื่นๆ
การแลกเปลี่ยนข้อมูลกับอุปกรณ์อื่นดำเนินการผ่านอินเทอร์เฟซ I2C จากพิน SCL และ SDA จำเป็นต้องใช้ตัวเก็บประจุ C1 และ C2 เพื่อลดเสียงรบกวนตามแนวสายไฟ เพื่อให้แน่ใจว่าสัญญาณ SCL และ SDA อยู่ในระดับที่เหมาะสม จึงมีการติดตั้งตัวต้านทาน R2 และ R3 (ดึงขึ้นไปที่แหล่งจ่ายไฟ) ในการตรวจสอบการทำงานของโมดูล สัญญาณ SQ รูปทรงสี่เหลี่ยมที่มีความถี่ 1 Hz จะถูกส่งไปยังพิน 7 ของชิป DS1307Z จำเป็นต้องใช้องค์ประกอบ R4, R5, R6, VD1 เพื่อชาร์จแบตเตอรี่ลิเธียม นอกจากนี้บอร์ดยังมีที่นั่ง (U1) สำหรับติดตั้งเซ็นเซอร์อุณหภูมิ DS18B20 (หากจำเป็นคุณสามารถบัดกรีเข้าไปได้) คุณสามารถอ่านค่าที่อ่านได้จากพิน DS ซึ่งเชื่อมต่อกับแหล่งจ่ายไฟผ่านตัวต้านทาน R1 ด้วย ความต้านทาน 3.3 kOhm แผนภาพวงจรและวัตถุประสงค์ของหน้าสัมผัสสามารถดูได้จากภาพด้านล่าง
บนบอร์ดมีหน้าสัมผัสสองกลุ่มโดยมีระยะห่าง 2.54 มม. ฉันจะใช้ขั้วต่อแบบพินเพื่อความสะดวกในการเชื่อมต่อกับเขียงหั่นขนมซึ่งจะต้องบัดกรี
ผู้ติดต่อกลุ่มแรก:
DS: เอาต์พุต DS18B20 (1 สาย)
VCC: แหล่งจ่ายไฟโมดูล "+"
GND: แหล่งจ่ายไฟโมดูล "-"
ผู้ติดต่อกลุ่มที่สอง:
ตาราง: อินพุต 1 MHz
DS: เอาต์พุต DS18B20 (1 สาย)
SCL: นาฬิกาอนุกรม
SDA: สายข้อมูล (Serial Dфta)
VCC: แหล่งจ่ายไฟโมดูล "+"
GND: "-" แหล่งจ่ายไฟโมดูล
ค้างคาว:
การชาร์จแบตเตอรี่
ตามที่อธิบายไว้ โมดูลของคุณสามารถชาร์จแบตเตอรี่ได้ ซึ่งใช้งานโดยใช้ส่วนประกอบ R4, R5, R6 และไดโอด D1 แต่วงจรนี้มีข้อเสียเปรียบ: แบตเตอรี่จะคายประจุผ่านตัวต้านทาน R4 และ R6 (ตามที่ผู้ใช้ ALEXEY ระบุไว้ไม่มากนัก) เนื่องจากโมดูลใช้กระแสไฟเพียงเล็กน้อย คุณจึงสามารถถอดวงจรไฟฟ้าออกได้ โดยถอด R4, R5, R6 และ VD1 ออก แทนที่ R6 ด้วยจัมเปอร์ (หลังจากถอดส่วนประกอบออกแล้ว คุณสามารถใช้แบตเตอรี่ CR2032 ทั่วไปได้)
การเชื่อมต่อ DS1307 กับ Arduino
ชิ้นส่วนที่จำเป็น:
Arduino UNO R3 x 1 ชิ้น
ลวดดูปองท์ 2.54 มม. 20 ซม. x 1 ชิ้น
สาย USB 2.0 A-B x 1 ชิ้น
นาฬิกาเรียลไทม์ RTC DS1307 x 1 ชิ้น
การเชื่อมต่อ:
หากต้องการเชื่อมต่อนาฬิกาเรียลไทม์ DS1307 คุณจะต้องบัดกรีขั้วต่อพินเข้ากับพินกลุ่มแรก ต่อไปเราเชื่อมต่อสายไฟ SCL (DS1307) กับพิน 4 (Arduino UNO) และ SDA (DS1307) กับพิน 5 (Arduino UNO) สิ่งที่เหลืออยู่คือเชื่อมต่อ VCC กับ +5V และ GND กับ GND อย่างไรก็ตาม เอาต์พุตอินเทอร์เฟซ I2C จะแตกต่างกันในบอร์ด Arduino ที่แตกต่างกัน สามารถดูวัตถุประสงค์ของแต่ละรายการได้ด้านล่าง
ตั้งเวลา DS1307
ก่อนอื่นคุณต้องดาวน์โหลดและติดตั้งไลบรารี่ "DS1307RTC" และ "TimeLib" ในสภาพแวดล้อมการพัฒนา Arduino IDE จากนั้นคุณจะต้องตั้งเวลาเปิดตัวอย่างจากไลบรารี DS1307RTC "ไฟล์" -> "ตัวอย่าง" - > “DS1307RTC” -> “SetTime” หรือคัดลอกโค้ดด้านล่าง
ดาวน์โหลดแบบร่าง
เราโหลดร่างนี้ลงในคอนโทรลเลอร์ Arduino (เวลาถูกนำมาจากระบบปฏิบัติการ) เปิด "การตรวจสอบพอร์ต"
โปรแกรม
มีอีกตัวอย่างหนึ่งในไลบรารี คุณสามารถเปิด DS1307RTC “File” -> “Examples” -> “DS1307RTC” -> “ReadTest”
/* ทำการทดสอบบน Arduino IDE 1.6.12 วันที่ทดสอบ 23/11/2559 */ #รวม
ดาวน์โหลดแบบร่าง
เราโหลดโค้ดนี้ลงในคอนโทรลเลอร์ Arduino เปิด "Port Monitoring"