Lab 3.1 เขียนและอ่านค่าจากอุปกรณ์ผ่านทาง I2C Bus
โจทย์
- ให้นำโปรแกรมตัวอย่างด้านล่างไปทดลอง เพื่อให้จอภาพแสดงค่า 1000 ขึ้นมา เมื่อทำได้แล้วให้ทดลองเปลี่ยนค่าเป็นค่าอื่นๆ เพื่อศึกษาให้เข้าใจว่าการส่งค่า high-byte และ low-byte ทำงานอย่างไร
- ให้เขียนโปรแกรมนับเลข เพื่อแสดงค่าตั้งแต่ 0,1,2,3,… เพิ่มขึ้นไปเรื่อยๆ จะถึง 9999
- ให้ใช้ Logic Analyzer จัดภาพตัวอย่างขณะ Master ส่งค่าไปให้กับ display module โดยแสดงตัวอย่างการส่งค่า 1 ค่า
จุดประสงค์การเรียนรู้
- ฝึกเขียนโปรแกรม I2C Master เพื่อสั่งงานอุปกรณ์ I2C Slave
แนวทางการปฏิบัติ
- Address ของ Display Module คือ 0xB0
- ตารางต่อไปนี้แสดงหน้าที่ของ Register ตำแหน่งต่างๆ ของ display module
Address | หน้าที่ |
2 | Display Value (Hight Byte) |
3 | Display Value (Low Byte) |
แนวทางการต่อวงจร
การแสดงค่าขึ้นจอ
ค่าตัวเลขที่แสดงบนหน้าจอจะเป็นตัวเลขขนาด 16 บิต (แสดงได้ตั้งแต่ 0 – 65535) โดยในการแสดงค่าแต่ละครั้งให้เริ่มด้วยการตั้งค่าตำแหน่ง Register Address ให้ชี้ไปที่ตำแหน่งที่ 2 แล้วแบ่งค่า 16 บิตที่จะแสดงออกเป็นสองส่วนค่าไบท์บน (High Byte) และไบท์ล่าง (Low Byte) และส่งทั้งสองไบท์ไปยัง Slave ตามตัวอย่าง
ตัวอย่างนี้จะแสดงค่า 1000 (ซึ่งเท่ากับ 0x3E8 ฐาน 16) ขึ้นจอ ซึ่งค่านี้จะแบ่งออกเป็นสองไบท์คือ ไบท์บน = 0x03 และไบท์ล่าง = 0xE8
การเขียนโปรแกรม
1. ให้เปิดใช้วงจร i2c บน mcu โดยประกาศคำสั่งต่อไปนี้เหนือ main() ของโปรแกรม (ถ้านำโปรแกรมจากแบบฝึกหัดเดิมมาใช้ ก็อาจเพิ่มคำสั่งไปต่อจากคำสั่ง #use rs232(…) ก็ได้)
#use i2c(MASTER, I2C1, FORCE_HW) // configure the i2c port
2. ประกาศ Slave Address ดังนี้เหนือ main()
#define SLAVE_ADDRESS 0xB0
3. เพิ่มคำสั่งต่อไปนี้ใน main() ซึ่งจะเขียนค่า 1000 ไปยังหน้าจอ
i2c_start(); i2c_write(SLAVE_ADDRESS); i2c_write(2); // set register pointer to location 2 i2c_write(0x03); // send high byte i2c_write(0xE8); // send low byte i2c_stop();
ข้อผิดพลาดที่พบบ่อย
- หน้าจอตอนที่ boot ใหม่ๆ จะแสดงคำว่า “GoGo” ซึ่งระหว่างนั้นจอจะไม่รับคำสั่งใดๆ ดังนั้นขอให้ delay ตัว PIC ก่อนประมาณ 1 วินาที ถึงเริ่มส่งคำสั่งไปให้หน้าจอ
- ข้อผิดพลาดที่พบบ่อยที่สุดคือไม่สามารถแสดงค่าที่สูงกว่า 255 ซึ่งเป็นผลจากการที่ส่งค่า byte บน ไม่ถูกต้อง ขอให้ศึกษาทำความเข้าใจเรื่องการแบ่งไบท์ให้ดี
- ตัวต้านทาน pull-up ที่ใช้ไม่ควรมีค่าต่ำกว่า 1 k โอห์ม เพราะจะทำให้สายสัญญาณค่าค้างที่ high (บางครั้ง นศ. ใช้ 100 ohm เป็น pull-up ซึ่งจะทำให้ i2c ไม่ทำงาน)
- การเขียนค่าไปยัง i2c ทุกครั้งต้องทำกระบวนการตั้งแต่ i2c_start() ถึง i2c_stop() ทุกครั้ง ไม่สามารถส่งค่าหลายครั้งไปยังรีจิสเตอร์ตำแหน่งเดิมภายใน i2c_start() กับ i2c_stop() ครั้งเดียวได้ เช่น
วิธีนี้ผิด
i2c_start(); i2c_write(SLAVE_ADDRESS); for (i=0;i<10;i++) { i2c_write(2); i2c_write(i); } i2c_stop();
วิธีนี้ถูกต้อง
for (i=0;i<10;i++) { i2c_start(); i2c_write(SLAVE_ADDRESS); i2c_write(2); i2c_write(i); i2c_stop(); }