โจทย์
1. ให้นักศึกษาอ่านค่าวันเวลาปัจจุบันจากโมดูลนาฬิกามาแสดงผลบนคอมพิวเตอร์ ตามรูปแบบนี้
9:33:16 Wed 25/1/2017
เป็นเวลา 9 นาฬิกา 33 นาที 16 วินาที วันพุธที่ 25 มกราคม 2017
2. ให้นักศึกษาเขียนโปรแกรมแสดงค่าเวลาปัจจุบัน (นาที, วินาที) จาก I2C Clock Module ไปแสดงบน 7-segment display
จุดประสงค์
- เพื่อให้ได้ฝึกใช้ Bit-wise operation ร่วมกับการอ่านค่าผ่าน i2c
อุปกรณ์ที่ต้องใช้
- โมดูลนาฬิกา – ขอให้นำไปตั้งเวลากับ Staff ก่อนนำมาใช้งาน ระวังอย่าให้ถ่านหลุดเพราะเวลาจะหายไปและต้องทำการตั้งเวลาใหม่โมดูลจะมีสองรุ่น คือรุ่นที่ใช้ Chip เบอร์ DS1307 และรุ่นที่ใช้ DS323 โดยทั้งสองรุ่นเขียนโปรแกรมอ่านค่าเหมือนกัน รุ่น DS1307 จะมีขาต่อดังในภาพ
ส่วนรุ่น DS323 ขาต่อจะมี Label อยู่บนบอร์ดอยู่แล้ว
แนวทาง
โมดูลนาฬิกาที่ใช้ในกิจกรรมนี้ใช้ไอซีหมายเลข DS1307 ซึ่งเป็นอุปกรณ์ i2c ที่มีรายละเอียดดังนี้
- สามารถศึกษา Data Sheet ได้
- i2C Address คือ 0xD0
- มีรีจิสเตอร์ที่เก็บค่าวันเวลาตามตารางต่อไปนี้
แนวทางปฏิบัติ
- รีจิสเตอร์จะเก็บค่าแยกหลักหน่วยและหลักสิบ เช่น ค่าวินาทีหลักหน่วยจะเก็บไว้ที่บิต 0-3 ของรีจิสเตอร์ 0 ส่วนหลักสิบคือบิท 4-6 ของรีจิสเตอร์เดียวกัน ยกตัวอย่างเช่น ถ้าค่าวินาทีคือ 23 ค่าที่จะถูกเก็บในรีจิสเตอร์คือ 0b00100011 เป็นต้น นักศึกษาจะต้องแบ่งบิตเหล่านี้แล้วนำมาคำนวณให้ดี
- บิตที่ 7 ของรีจิสเตอร์ 0 คือ Clock Halt (CH) ถ้าเขียนบิตนี้ให้มีค่าเป็น 1 นาฬิกาจะหยุดเดิน ขอให้ระวังอย่าเซ็ทบิตนี้โดยบังเอิญ
- วันในสัปดาห์ (Mon-Sun) อ่านค่าได้จากรีจิสเตอร์ตำแหน่งที่ 3 ซึ่งใน Datasheet ระบุไว้ว่าค่าใดหมายถึงวันใดนั้นขึ้นอยู่กับผู้ใช้จะตั้งเอาเอง ตัวโมดูลจะทำอย่างเดียวคือเพิ่มค่าของรีจิสเตอร์ในตอนเที่ยงคืน และถ้าค่านี้เกิน 7 ก็จะวนกลับมาเป็น 1 อีกครั้ง
- รีจิสเตอร์เก็บค่านี้ใน 3 บิตแรก แต่ค่าที่เก็บจะอยู่ระหว่าง 1 – 7 เท่านั้น (จะไม่เป็น 0)
- บิตที่ 6 ของรีจิสเตอร์ 2 จะใช้กำหนดว่าค่าชั่วโมงจะเป็นโหมด 24 ชม (บิต=0) หรือ 12 ชม (บิต=1) ถ้ากำหนดให้เป็นโหมด 12 ชม บิตที่ 5 ของรีจิสเตอร์นี้จะเป็นตัวระบุว่าเวลาดังกล่าวเป็น AM (บิต=0) หรือ PM (บิต=1)
ตัวอย่างโปรแกรม
โปรแกรมต่อไปนี้จะทำการอ่านค่า “ปี” ปัจจุบันออกมาจาก Clock Module และแสดงผลบนจอภาพ
void main() { int8 value, year; delay_ms(1000); while(1) { i2c_start(); i2c_write(0xD0 | 0); // Clock module address = 0xD4 i2c_write(6); // indicate we want to read from register address 6 (year) i2c_start(); // restart i2c i2c_write(0xD0 | 1); // send address with bit 0 = 1 indicating that we want to read from slave value = i2c_read(0); // read one byte. Note parameter 0 i2c_stop(); // end i2c operation year = (value >> 4)*10 + (value & 0xf); // transform the year format printf("Year = %u\r\n", year); delay_ms(1000); } }