->> หมวดหมู่และหัวข้อบทความ << คลิ๊ก
บันทึกช่วยจำ และความเข้าใจส่วนตัว 7seg TM1637 TM1638 และอื่นๆ เพื่อเขียน atmega328p ด้วย asm , c
---กำลังศึกษาอยู่ครับ มันเป็นแค่บันทึกช่วยจำส่วนตัว ผมสนใจอะไรก็จะบันทึกลงไป อาจไม่มีประโยชน์แก่ผู้อ่านและไม่ได้ครอบคลุมทั้งหมด เนื่องจากผมไม่เคยใช้c และเพิ่งเริ่มจับ แต่ในใจผมชอบแอสเซมบลี้มากกว่า เมื่อมีอุปกรณ์ใหม่ๆจึงต้องขุดข้อมูลออกมามาใช้ด้วยตัวเองและบันทึกลงไปพื่อเอาไว้ใช้ส่วนตัวเท่านั้น-
-ในที่นี้เริ่มต้นผมคงใช้ arduino uno และโค๊ดทั่วไปๆมาทดลองเขียนและแกะมาใช้งานจากภาษาC ก่อนแล้วลามไปภาษาแอสเซมบลี้ ส่วนฮาร์ดแวร์โมลดูลต่างๆที่มีข้อกำหนดและด้าต้าชีทที่จะถูกกำหนดให้ใช้สำหรับ atmega328p หรืออื่นๆก็จะถูกบันทึกเอาไว้เพื่อช่วยเตือนความจำอีกด้วย-
-กำลังศึกษาอยู่ครับ 15/5/2560-
สมัยนี้ตั้งแต่ Arduinoฮิตติดตลาด โมดูลเซเว่นเซ็กเม้น4-8ตัวเลข (4-8 digit) หรือจอแสดงตัวเลขที่เป็นชนิดแอลอีดี หรือโมดูอื่นๆ สำหรับไมโครคอนโทรลเลอร์ต่างๆโดยเฉพาะสินค้าที่มาจากประเทศจีนโดยมันถูกสร้างขึ้นมาเฉพาะให้เสียบใช้งานได้เลย มีราคาไม่แพงและมีความสะดวกอย่างมากเมื่อเทียบกับสมัยก่อน เหมาะสำหรับผู้ที่จะนำไปพัฒนาต่อยอดหรือแม้กระทั่งทำผลิตภัณท์ควบคุมต่างๆทั้งใช้หรือขายก็ได้มีราคาที่ย่อมเยาว์ขึ้นโดยไม่ต้องไปออกแบบวงจรและสร้างเอาเอง
ถ้ากล่าวถึง โมดูลเซเว่นเซ็กเม้น ตั้งแต่4 digit ขึ้นไป จะมีข้อที่ได้เปรียบคือ มีไอซีต่างๆที่สร้างเฉพาะด้านเพื่อให้บรรลุงานที่แต่เดิมต้องใช้ขาของ MCU จำนวนมากในการควบคุมตัวเลข4หลัก และการเสียเวลาวนหลูปในMCU ที่ต้องวนให้แต่ละดิจิตแสดงทีละหลักตามของการส่องสว่างแบบ 7 segment multiplex คือการสลับให้แสดงผลทีละดิจิตวนจนครบทั้ง4ตัวเลขด้วยความเร็วเกินกว่าตามนุษย์จะเห็นทัน มีผลให้เหมือนหลอกตาทำให้เห็นเป็นตัวเลขทั้ง4สว่างพร้อมๆกัน ถ้าจำไม่ผิดโดยทั่วๆไปตามนุษย์จะเห็นภาพและรู้สึกต่อเนื่องเหมือนหนังอย่างน้อยต้องมี24ภาพต่อวินาที และจอแอลอีดีทั่วๆไปกระพริบที่60-100ครั้งต่อวินาที ถ้าที่100 Hz แต่ละภาพใช้เวลา10ms ส่วนการกระพริบของtm1637แต่ละตัวเลขของ7segmentเมื่อกลับมากระพริบอีกครั้งกินเวลาประมาณ 3.5ms ซึ่งถือว่าเป็นความเร็วที่มากพอ
--
---
---
โมดูล 7segment ที่สร้างด้วย TM1637
-ในรูปข้างล่าง เป็นโมดูลจอ แอลอีดี 7segment 4digit คือมีตัวเลขทั้งหมด4ตัว ถูกขับด้วยไอซีTM1637 สามารถรับข้อมูลจากไมโครคอนโทรลเลอร์ใดๆที่เข้าใจภาษาการติดต่อของมัน ด้วยสาย2เส้น คล้าย I2C และอีกสองเส้นคือกราวด์และVcc3.3-5v แต่เดิมไอซีนี้ได้ถูกสร้างเพื่อเอาไว้ใช้กับเตาแม่เหล็กไฟฟ้าหรือเตาไมโครเวฟ โดยที่ตัวมันสามารถขับ LEDได้มากถึง6 digit และตัวมันยังสามารถเป็นตัวรับอินพุทคีย์ได้มากถึง16 keyด้วยวิธีการสแกนด้วยความเร็ว500usในเวลาถัดๆมา โดยที่mcu สามารถนำข้อมูลคีย์ที่มันอ่านเอาไปใช้ได้ตลอดเวลา
-
-ในรูปข้างล่าง ช่างกำลังใช้เตาแม่เหล็กไฟฟ้า(induction cooker)อุ่นแหวนเพื่อให้เกิดความร้อนและขยายตัวในการสวมแหวนชนิดสวมฟิตซึ่งอาจเป็นแหวนสำหรับรองลูกปืนหรือเฟืองก็ได้ จากรูปถ้าเราสังเกตดูเตาแม่เหล็กไฟฟ้า ยี่ห้อ imarflex รุ่นนี้พบว่า มี 7segment 4digit และมีไฟแอลอีดีแสดงการทำงานอีกประมาณ13ตำแหน่ง บวกกับปุ่มกดอีก7ตัว ทั้งหมดนี้สามารถถูกแสดงและถูกอ่านปุ่มด้วย tm1637เพียงไอซีตัวเดียวเท่านั้น ซึ่งมันมีความสามารถมากจริงๆ ไมโครคอนโทรลเลอร์ปัจจุบันจึงแทบไม่ต้องทำหน้าที่เหล่านี้อีกต่อไป
-ข้อความด้านล่างต่อไปนี้ส่วนใหญ่จะตัดจาก datasheet ของผู้ผลิต IC [TM1637 pdf-google] และ [TM1638 pdf-google] ผลิตโดย บริษัท Titan MicroElectronics ถ้าท่านผู้อ่านสนใจแบบรวบรัด ของแนะนำที่นี่เลยครับ ทั้งข้อมูลและการเขียนโปรแกรมภาษาC ครบครันครับ ส่วนใหญ่ผมจะอิงข้อมูลจากแหล่งเหล่านี้แล้วนำมาต่อยอดเขียนบันทึกต่อไป
1. cpre.kmutnb.ac.th/esl/learning/index.php?article=four-digit-7seg-tm1637
feature IC TM1637
- เป็นICประเภท CMOS
- สามารถ ขับตัวเลข LED commond anode 8จุดได้มากถึง6ตัว
- สแกนปุ่ม หลังจากการขับled จะวนมาอ่านปุ่มได้มากถึง 16ปุ่ม
- ปรับความสว่างได้ 8 ระดับ ในวงจรLEDหรือ7segที่ใช้ไม่ต้องมีRหรือความต้านทานที่ต่อเพื่อจำกัดกระแสไฟหรือความสว่างในLED เข้าใจว่ามีตัวต้านอยู่ภายในไอซีอยู่แล้ว
- ใช้ระบบสั่งการแบบ2สายคล้ายI2C เพียงแต่ไม่มีการเรียกชื่ออุปกรณ์ในตอนแรกของการติดต่อเหมือนกับอุปกรณ์I2Cอื่นๆโดยทั่วไป ส่งข้อมูลผ่านขาDIO(ขา17) และต้องมีการให้สัญญาณนาฬิกาจากMCUผ่านขาCLK(18) การสั่งการให้tm1637ทำงานต้องมีรหัสคำสั่งของมันโดยเฉพาะ
- ภายในมีตัวสร้างความถี่ส่วนตัวชนิดRC ประมาณ450kHz ,มีระบบpower on reset -ลบข้อมูลเก่าหลังรีเซท
- มีหน่วยความจำพิเศษที่เก็บค่ารหัส7segment ทั้ง6ดิจิต เป็นรีจิสเตอร์ขนาด8bit จำนวน6ไบท์ จัดเก็บจากที่MCUส่งมา และการนำไปใช้แสดงก็ทำหรือยิงเข้า7segmentแต่ละดิจิตโดยตรงโดยไม่ได้ผ่านการแปลข้อมูลจึงสามารถแสดงสัญลักษณ์แปลกๆได้ตามที่ผู้เขียนโปรแกรมต้องการ (ต่างจาก7segmentที่ทำจากไอซีmax7219 ซึ่ง จะแปลด้วยการถอดรหัสBCD จึงมีได้แต่ตัวเลขและตัวอักษรH,E,L,P เท่านั้น) ภาพขาของ tm1637 ตัดจากดาต้าชีทผู้ผลิต
การขับ 7 segment (เซเว่นเซ็กเม้นส่วนใหญ่เป็นตัวเลขที่ประกอบด้วย 8 led รวมจุดท้ายตัวเลข) ได้ 8segmet*6bit ชนิด commond anode LED รูปแบบของ คอมมอนแอโหนด คือขาgrid1-6 ทำหน้าที่จ่ายไฟ5V หรือsource สมมติว่าเป็น digit ที่1 ตามตัวเลขด้วยล่าง ผ่านขาไอซีGRID1 ไปยัง แอลอีดีแต่ละตัวตามเซ็กเม้นต่างๆเช่น A,B,C,D,E,F,G,dp รวม8ตำแหน่งแอลอีดี ผ่านกลับเข้ามายังขาของไอซีที่ตำแหน่งขาSEG1-8 รวม8ตำแหน่งเหมือนกันซึ่งทำหน้าsinkคือรับกระแสให้ผ่านขามันลงกราวด์ภายในไอซีเอง ถ้าทำอย่างนี้ซ้ำๆไปdigitที่2-3-4 ผ่านการสลับการจ่ายไฟ จากขาGRID1 ไป2-3-4 สลับกันอย่างรวดเร็วทำให้เหมือนกับตัวเลขแสดงขึ้นพร้อมๆกัน ในที่นี้ถ้าใช้แค่4ตัวเลขทำให้มี GRID5,6เหลือเอาไปขับLED ได้อีก16ตัวพร้อมกัน ตัวเลข LED 7 segment ภาพ Wikipedia CC-SA3.0 by h2g2bob
.รูปข้างบนเป็นวงจรที่TM1637ต่อเข้าไปขับ7segment4digit
.
.รูปข้างบนตัดมาจากpdfของผู้ผลิต แสดงตัวอย่างวงจรในการต่อ tm1637 กับ 7seg 6ชุด และปุ่ม 16 ปุ่ม ซึ่งเข้าใจว่าโมดูล1637ก็ต่อแบบนี้เช่นกันเพียงแต่มี7seg 4ชุดและไม่มีปุ่มกด ที่เหลือRกับCก็คงต่อเหมือนกัน
.
.ปุ่มภาพตัดจากดาต้าชีทผู้ผลิตtm1637 แสดงการออกแบบวงจรปุ่ม16ปุ่มการอ่านค่าคีย์แสกน อยู่ๆเขาก็ให้ตารางการอ่านค่ามาและบอกว่าถ้าไม่มีการกดปุ่มควรต้องอ่านได้ 1111_1111 และมีคำว่าwith forward low level and backward high level ซึ่งไม่รู้แปลว่าอะไร สรุปยังงงๆว่าข้อมูล16key ใช้1ไบท์ระบุว่ากดปุ่มไหนใช่หรือไม่ ซึ่งถ้าไม่สามารถกด2ปุ่มพร้อมกันได้แสดงว่าข้อมูล1ไบท์นี้ก่อนนำไปใช้เมื่อMCUรับข้อมูลไปแล้วต้องไปแปลอีกที
- ปุ่ม โดยระบุว่าสามารถทำkey scanได้ เข้าใจว่าจ่ายไฟผ่านK1,K2ทำทีละขา แล้วอาศัยกาสแกนปุ่มอินพุททีละ8ตำแหน่ง โดยรับอินพุทผ่านขา SEG1-SEG8 แล้วจึงเข้ารหัสเก็บค่าเอาไว้ในรีจีสเตอร์ของมันเอง(เดาๆ) จากนั้นจึงสลับเป็นจ่ายK2ทำซ้ำอีกครั้งๆ รวมๆแล้วสามารถสแกนปุ่มว่าถูกกดหรือไม่ ถึง16ปุ่ม แล้วแต่จะออกแบบวงจร แต่การเข้ารหัสดังกล่าวน่าจะเก็บข้อมูลทั้งหมดของ16ปุ่มใน1ไบท์ ในดาต้าชีทไม่ได้บอกอะไรทำให้ค่อนข้างงงๆ
เมื่ออ่านดาต้าชีทเพิ่มเติมพบว่าระบบการกดปุ่มมีระบบป้องกันการรบกวนจากเครื่องใช้ไฟฟ้าป้องการคีย์กระโดดและtm1637 ไม่รองรับการกดปุ่ม2ปุ่มพร้อมๆกัน
-
-
-
ทวนความจำเรื่อง หลักการวิธีการรับ-ส่งข้อมูล I2C
การส่งข้อมูลชนิด 2 สาย สายหนึ่งเป็นการให้สัญญาณนาฬิกา SCL, สายclk และอีกสายหนึ่งเป็นสายข้อมูล คือ SDA ,สายdata ,dio
1. SCL สายคล็อก จะกำหนดขาMCUให้เป็น output อย่างเดียว และส่งสัญญาณจาก MCU ซึ่งเรียกว่า master เป็นผู้กำหนดสัญญาณในการส่ง
2. SDA สายข้อมูล ถ้าMCU ต้องการ
2.1 ส่งข้อมูล จะให้ขาMCUเป็น output
2.2 รับข้อมูลจาก slave หรืออุปกรณ์I2Cที่ต้องการติดต่อ จะให้ขาของ MCU เป็นอินพุท ใช้รับข้อมูลอื่นๆรวมทั้ง acknowledgement จาก slave
หลักการวิธีการรับ/ส่ง ในระบบ I2C
1 การส่งสภาวะเริ่มต้น หรือบิท start จากMCU เนื่องจากมีการติดต่อเพียงสองสายจำเป็นต้องกำหนดวิธีการเพื่อบอกให้slaveหรือทาสทั้งหลายในระบบI2C รู้ว่าขณะนี้ MCU ส่งสัญญาณให้slaveตื่นตัวและเริ่มต้นทำงานรับส่งข้อมูล เรียกว่า เงื่อนไขstart เรียกย่อๆว่าบิทstart ก็พอได้ เงื่อนไขคือ ขณะที่ SCL= 1 แล้ว SDA มีการเปลี่ยนจาก1เป็น0
2 การส่งสภาวะสิ้นสุด หรือบิท stop จากMCU จะมีผลตรงข้ามคือ slaveทุกตัวจะเข้าใจว่าสิ้นสุดและหยุดการติดต่อและจะอยู่ในสถานะรอการกระตุ้นต่อไป เงื่อนไขคือ ขณะที่ SCL=1 แล้ว SDA มีการเปลี่ยนจาก 0เป็น1
3 หลังจากมีการรับรู้บิทstartแล้ว ต่อไปคือการส่งข้อมูลถึงกัน ถ้าเรา(MCU)ต้องการส่งข้อมูล หรือถ้า(MCU)ต้องการรับข้อมูล มีหลักการสำคัญคือถ้า clk กำลัง=0 จะสามารถเปลี่ยนแปลงข้อมูลdioก่อนส่งได้โดยที่ slave จะไม่สนใจอ่านข้อมูลใดๆในขณะนั้น การที่clk =1 เป็นการยืนยันให้รับส่งข้อมูล ข้อมูลdio ขณะที่ clk=1 ถือว่าเป็นข้อมูลที่นำไปใช้ได้ทั้งการอ่านและเขียน โดยมีเวลาในการรอclkของMCUให้นานพอที่อุปกรณ์I2Cจะทำงานได้ทัน โดยทั่วๆไปMCUจะส่งข้อมูลทีละ8บิท รวม8คล็อก ส่วนบิทที่9หรือclockที่9 เป็นบิทรับรู้จากslaveที่ส่งกลับไปหาmaster ที่เรียกว่า acknowledgement
เวลาในการรอนี้แตกต่างกันในแต่ละอุปกรณ์ซึ่งอุปกรณ์ต่างๆจะกำหนดเวลาอย่างน้อยที่สุดที่มันทำงานได้ในดาต้าชีท ซึ่งมีคำที่สำคัญที่เกียวข้องกับเวลารอดังนี้
- Clock Pulse Width (PWCLK) ความกว้างสัญญาณนาฬิกาขั้นต่ำ 1ลูกคลื่น(ขึ้นและลง) อย่างน้อยหรืออย่างเร็วที่สุดที่ slaveสามารถให้บริการได้
- Data setup time (tSETUP) เวลาอย่างน้อยที่slaveใช้ในการเซทอัพ คือช่วงเวลาเปลี่ยนข้อมูลของSLAVE หรือรอให้slaveเปลี่ยนแปลงข้อมูล ในขณะที่clk=0
- Data hold time (tHOLD) คือเวลาอย่างน้อยที่สุดที่ slaveใช้ในการอ่านข้อมูลที่ส่งมา
-
ขั้นตอน --การส่งI2C 1ไบท์ จากMCU
1. ส่งบิท start จาก master
2. การส่งข้อมูล 1ไบท์ 8บิท (เช่น 0b0100 1000) จากmaster
ส่งทีละบิทเริ่มจากบิทต่ำ พร้อมกับการให้สัญญาณclk
จากMCUที่ละคร้้งจำนวน 8 clock
3. รับ ACK จาก slave (ส่วนใหญ่ clock ที่9)
4. บิท stop จาก master
---
---
รูปแบบคำสั่งในการติดต่อ TM1637
0xC0 - 0xC5 , Display Register Address (ที่อยู่สำหรับ 7seg แต่ละดิจิต) | ||||||||
ขา | SEG 8 | SEG 7 | SEG 6 | SEG 5 | SEG 4 | SEG 3 | SEG 2 | SEG 1 |
7seg | dp | G | F | E | D | C | B | A |
ขา/bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
GRID1 | address 0xC0 (digit1) | |||||||
GRID2 | 0xC1 (digit2) | |||||||
GRID3 | 0xC2 (digit3) | |||||||
GRID4 | 0xC3 (digit4) | |||||||
GRID5 | 0xC4 (digit5) | |||||||
GRID6 | 0xC5 (digit6) | |||||||
access | W | W | W | W | W | W | W | W |
reset | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
CMD1 , คำสั่ง1 Data Command Setting (คำสั่งที่ให้อ่านหรือเขียนข้อมูล) | ||||||||
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
คำสั่ง1 | 0 | 1 | 0 | 0 | โหมด ปรกติ |
ที่อยู่ fix ,ต่อเนื่อง | อ่านคีย์ /เขียน7seg | 0 |
access | 01 = คือคำสั่งที่เกียวกับข้อมูล | ควรใส่ 00 ไม่มีนัยสำคัญ | โหมดการทำงาน 1 = normal 0= test |
การระบุที่อยู่ 1 = fix 0 = เพิ่มค่าที่อยู่ต่อเนื่องเพื่อส่งข้อมูล7seg 2-6 ไบท์ |
1= อ่านคีย์ 0=เขียน7seg |
ต้องใส่ 0 เท่านั้น |
CMD2 , 0xC0 - 0xC5 , คำสั่ง2 Address Command Setting (คำสั่งระบุที่อยู่ในการเขียน7seg) | ||||||||
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
คำสั่ง2 | 1 | 1 | 0 | 0 | 0 | addr2 | addr1 | addr0 |
access | 11 = คำสั่งที่ tm1637 เข้าใจว่าเป็นที่อยู่ 7seg |
ควรใส่ 00 ไม่มีนัยสำคัญ | ต้องใส่ 0 เท่านั้น | ที่อยู่สัมพันธ์ของหน่วยความจำ 7seg 6ไบท์ 000 , 001 , 010 ,011, 100 ,101 |
||||
C0H-C5H | bit7654 = 1100 = 0xC (สีบิทบน) | bit3210 = 0x1 - 0x5 (สี่บิทล่าง) |
CMD3 , คำสั่ง3 Display Control Command Setting (คำสั่งควบคุมความสว่าง เปิด-ปิดจอ) | ||||||||
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
คำสั่ง3 | 1 | 0 | 0 | 0 | เปิดจอ | สว่าง2 | สว่าง1 | สว่าง0 |
access | 10 = การคุมจอ | ควรใส่ 00 ไม่มีนัยสำคัญ | 1 = เปิดจอ 0 = ปิดจอ |
ความสว่างจอ มี 8 ระดับ bit210=xxx ระบุเป็นpulse width =1/16-14/16 000 = 1/16 100 = 11/16 001 = 2/16 101 = 12/16 010 = 4/16 110 = 13/16 011 = 10/16 111 = 14/16 |
ลำดับการติดต่อกับTM1637 ด้วยI2C มีดังนี้
8858---
// โค๊ดไฟล์จาก http://cpre.kmutnb.ac.th/esl/learning/index.php?article=four-digit-7seg-tm1637
// C++ for Arduino uno (ATmega328P, 5V, 16MHz) , Arduino IDE v 1.0.5 ,
Module "Catalex 4-digit display" สร้างขึ้นจาก TM1637
// คอมเม้นและเปลี่ยนตัวแปรเพื่อการศึกษาและทำความเข้าใจส่วนตัวเท่านั้น by pui108diy
// ไม่รับประกันความถูกต้อง โปรดไปคัดลอกใช้ซอฟแวร์หรือโค๊ดแท้ที่เว็บลิ้งค์ดังกล่าวเท่านั้น
// เนื่องจากต้องการนำโค๊ดเหล่านี้ไปใช้กับ TM1638 จึงต้องนำมาทำความเข้าใจและอธิบายส่วนตัว
//ตัวอักษรสีแดง เช่น _250ns_4clk_of_16Mhz คือตัวแปรที่ถูกดัดแปลงชื่อให้ยาวขึ้นจากเดิม
#define CLK_PIN (2)
#define DIO_PIN (3)
#define bit_delay_250ns_4clk_of_16Mhz() asm("nop\n nop\n nop\n nop\n")
#define TM1637_CMD1_write_auto_inc_addr (0x40)
#define TM1637_CMD2_1st_mem_addr_7seg_1xxx (0xC0) // หลักพันในโมดูล
#define TM1637_CMD3_ctrl_screen_head (0x80) //มีแต่หัวคำสั่งต้องเอาไปรวมกับค่าอื่นอีก
const uint8_t SEVEN_SEG_DIGITS[] = {
// gfedcba
0b00111111, // 0
0b00000110, // 1
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111101, // 6
0b00000111, // 7
0b01111111, // 8
0b01101111, // 9
};
void tm1637_init_pin_for_sent_I2C() {
pinMode( CLK_PIN, OUTPUT );
pinMode( DIO_PIN, OUTPUT );
digitalWrite( CLK_PIN, HIGH );
digitalWrite( DIO_PIN, HIGH );
}
void tm1637_start_bit_I2C() {
digitalWrite( DIO_PIN, LOW );
bit_delay_250ns_4clk_of_16Mhz();
digitalWrite( CLK_PIN, LOW );
bit_delay_250ns_4clk_of_16Mhz();
}
void tm1637_stop_bit_I2C() {
digitalWrite( CLK_PIN, HIGH );
bit_delay_250ns_4clk_of_16Mhz();
digitalWrite( DIO_PIN, HIGH );
bit_delay_250ns_4clk_of_16Mhz();
}
int tm1637_send_1byte_I2C_ack( uint8_t data ) {
uint8_t ack;
for( uint8_t i = 0; i < 8; i++ ) { // Send 8-bit data, LSB first
digitalWrite( CLK_PIN, LOW );
digitalWrite( DIO_PIN, ( data & 0x01 ) ? HIGH : 0 ); // ????????????????
digitalWrite( CLK_PIN, HIGH );
data >>= 1; // shift bit to the right
}
digitalWrite( CLK_PIN, LOW );
// I2C acknowledgement process , read ack in clolck9
pinMode( DIO_PIN, INPUT ); // make DIO pin floating (input)
digitalWrite( DIO_PIN, HIGH ); // enable pull-up
digitalWrite( CLK_PIN, HIGH ); // start clock9
ack = digitalRead( DIO_PIN ); // read ACK bit ถ้าไม่มีการรับรู้ต้องเขียนโค๊ดเพิ่มเอาเอง
// make DIO pin to output again
digitalWrite( DIO_PIN, LOW );
pinMode( DIO_PIN, OUTPUT );
digitalWrite( CLK_PIN, LOW );
return (ack==0); // ถ้าเข้าใจไม่ผิด จะไม่มีโค๊ดที่รองรับต่อ ถ้า ack=1
}
boolean showDigits( uint8_t digits[], boolean colon=false, uint8_t brightness=7 ) {
// send the first command-----------------------
tm1637_start_bit_I2C();
tm1637_send_1byte_I2C_ack( TM1637_CMD1_write_auto_inc_addr );
tm1637_stop_bit_I2C();
// send the second command-------------------
tm1637_start_bit_I2C();
tm1637_send_1byte_I2C_ack( TM1637_CMD2_1st_mem_addr_7seg_1xxx );
for ( uint8_t i=0, value; i < 4; i++ ) {
value = SEVEN_SEG_DIGITS[ digits[i] ];
if ( (i == 1) && colon ) {
value |= 0x80; // turn on the colon on the display ,x1xx digit ,hundreds digit
}
tm1637_send_1byte_I2C_ack( value );
}
tm1637_stop_bit_I2C();
// send the third command---------------------- option send only 1 time is OK----
tm1637_start_bit_I2C();
tm1637_send_1byte_I2C_ack( TM1637_CMD3_ctrl_screen_head | (brightness & 0x07) | 0x08 );
// brightness [0-7] , &0x07 filter to correct brightness value (before OR with CMD3)
// 0x08 (0b00001000) , 1 is bit cmd for open 7seg screen ,0= close screen
tm1637_stop_bit_I2C();
}
////////////////////////////////////////////////////////////////////////
uint32_t ts;
void setup() {
tm1637_init_pin_for_sent_I2C();
ts = millis(); // millis() is arduino function
// return: Number of milliseconds since the program started (unsigned long)
// ts=mills() คือเอาค่าเวลานับมิลลิเซกในขณะนั้นมาเก็บเอาไว้ในตัวแปร ts
}
// show time (hour and minute)
void showTime( uint8_t hh, uint8_t mm, boolean colon=false ) {
static uint8_t data[4];
data[0] = hh/10;
data[1] = hh%10;
data[2] = mm/10;
data[3] = mm%10;
showDigits( data, colon );
}
void testDigitalWatch() { //โปรแกรมนาฬิกาดิจิตอล
static boolean colon=false;
static uint8_t hh=12, mm=0, ss=0; // Start at 12:00:00(hours, minutes and seconds)
if ( millis() - ts >= 500 ) { // check every 500 msec
showTime( hh, mm, colon );
colon = !colon; // เป็นการให้โคล่อนกระพริบในครั้งๆต่อไป
if (colon) { //ทุกครั้งที่โคล่อน=1 จะ
ss = (ss+1)%60; // ssเพิ่มเวลา1วินาที ?????
if (ss == 0) {
mm = (mm+1)%60;
if (mm == 0) {
hh = (hh+1)%24;
}
}
}
ts += 500;
}
}
void testTimer() {
static uint8_t data[4];
static uint16_t count = 0, temp;
if ( millis() - ts >= 100 ) { // check every 100 msec
temp = count;
count = (count+1) % 10000;
for (uint8_t i=0; i < 4; i++) {
data[3-i] = temp%10;
temp /= 10;
}
showDigits( data );
ts += 100;
}
}
void loop() {
testTimer();
//testDigitalWatch();
}
/////////////////////////////////////////////////////////////////////
---
---
---
---
---
---
---
---
---
โมดูล 7seg และปุ่มกดที่สร้างจาก TM1638
-รูปข้างล่างเป็นโมดูล7segชนิด8ตัวเลข พร้อมLEDด้านบน8ตัว และปุ่มกด8ปุ่ม ซึ่งเป็นโมดูลอินเตอร์เฟสที่ติดต่อกับมนุษย์ขับจากไอซี TM1638 เพียงตัวเดียว
เข้าใจว่าแต่เดิมIC TM1638 สร้างขึ้นเพื่อรองรับการใช้งานเครื่องเล่นDVD ซึ่งส่วนใหญ่จะมีตัวเลขอย่างน้อย 6 หลัก LEDแสดงสถานการทำงานเล่นวีดีโอและปุ่มกดบนเครื่องเล่นอีกจำนวนหนึ่ง ซึ่งไอซีสามารถทำงานวนแสดงLED หรือ 7segment ตามหลักการแสดงทีละดิจิตวนไปจนครบด้วยความเร็วสูงกว่าตามนุษย์เล็กน้อย หรือเรียกว่าการแสดงผล7segแบบมัลติเพลกซ์ ทำให้เห็นภาพว่ามันแสดงต่อเนื่องพร้อมๆกัน นอกจากนี้ไอซีTM1638ยังสามารถทำงานโดยวนไปอ่านปุ่มที่มีผู้ใช้งานกดหรือไม่ได้กดอยู่โดยนำข้อมูลการกดมาเก็บไว้ในหน่วยความจำของตนเองรอการติดต่อส่งไปยัง MCU หรือไมโครคอนโทรลเลอร์เพื่อแสดงผลต่อไป ไมโครคอนโทรลเลอร์ปัจจุบันจึงแทบไม่ต้องทำหน้าที่เหล่านี้อีกต่อไป
-ข้อความรูปภาพต่อไปนี้ตัดจาก pdf ผู้ผลิตIC [TM1638 pdf-google] ผลิตโดย บริษัท Titan MicroElectronics ข้อความส่วนใหญ่ถูกแปลและเรียบเรียงใหม่ เพื่อให้สามารถเข้าใจการทำงานและการติดต่อกับ TM1638 ผ่านไมโครคอนโทรลเลอร์ได้
feature IC TM1638
- เป็นไอซี ประเภท CMOS
- ขับdisplay 10seg x 8grid (ถ้านำมาขับ 7 segment LED ได้8ตัวอักษร ที่เหลืออีก 16จุด นำมาขับไฟLED แสดงผลได้ สามารถวนแสดงผลได้พร้อมๆกัน)
- สแกนปุ่ม หลังแสดงLED แล้วสามารถอ่านปุ่มกดได้ 8x3 bit หรือ24ปุ่ม
- ปรับความสว่างได้ 8 ระดับโดยใช้คำสั่ง สามารถต่อกับLED หรือ 7segment ได้โดยตรงโดยไม่ต้องต่อR เข้าใจว่ามีRอยู่ภายในIC
- ใช้ระบบสั่งการ3สาย (CLK , STB ,DIO)
- ภายในมีตัวสร้างความถี่ส่วนตัวชนิดRC ประมาณ450kHz ,มีระบบpower on reset -ลบข้อมูลเก่าหลังรีเซท
---
---
---
---
---
-กำลังดำน้ำอยู่ครับ--
---
0xC0 - 0xC5 , Display Register Address (ที่อยู่สำหรับ 7seg แต่ละดิจิต) | ||||||||
ขา | SEG 8 | SEG 7 | SEG 6 | SEG 5 | SEG 4 | SEG 3 | SEG 2 | SEG 1 |
7seg | dp | G | F | E | D | C | B | A |
ขา/bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
GRID1 | address 0xC0 (digit1) | |||||||
GRID2 | 0xC1 (digit2) | |||||||
GRID3 | 0xC2 (digit3) | |||||||
GRID4 | 0xC3 (digit4) | |||||||
GRID5 | 0xC4 (digit5) | |||||||
GRID6 | 0xC5 (digit6) | |||||||
access | W | W | W | W | W | W | W | W |
reset | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
CMD1 , คำสั่ง1 Data Command Setting (คำสั่งที่ให้อ่านหรือเขียนข้อมูล) | ||||||||
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
คำสั่ง1 | 0 | 1 | 0 | 0 | โหมด ปรกติ |
ที่อยู่ fix ,ต่อเนื่อง | อ่านคีย์ /เขียน7seg | 0 |
access | 01 = คือคำสั่งที่เกียวกับข้อมูล | ควรใส่ 00 ไม่มีนัยสำคัญ | โหมดการทำงาน 1 = normal 0= test |
การระบุที่อยู่ 1 = fix 0 = เพิ่มค่าที่อยู่ต่อเนื่องเพื่อส่งข้อมูล7seg 2-6 ไบท์ |
1= อ่านคีย์ 0=เขียน7seg |
ต้องใส่ 0 เท่านั้น |
CMD2 , 0xC0 - 0xC5 , คำสั่ง2 Address Command Setting (คำสั่งระบุที่อยู่ในการเขียน7seg) | ||||||||
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
คำสั่ง2 | 1 | 1 | 0 | 0 | 0 | addr2 | addr1 | addr0 |
access | 11 = คำสั่งที่ tm1637 เข้าใจว่าเป็นที่อยู่ 7seg |
ควรใส่ 00 ไม่มีนัยสำคัญ | ต้องใส่ 0 เท่านั้น | ที่อยู่สัมพันธ์ของหน่วยความจำ 7seg 6ไบท์ 000 , 001 , 010 ,011, 100 ,101 |
||||
C0H-C5H | bit7654 = 1100 = 0xC (สีบิทบน) | bit3210 = 0x1 - 0x5 (สี่บิทล่าง) |
CMD3 , คำสั่ง3 Display Control Command Setting (คำสั่งควบคุมความสว่าง เปิด-ปิดจอ) | ||||||||
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
คำสั่ง3 | 1 | 0 | 0 | 0 | เปิดจอ | สว่าง2 | สว่าง1 | สว่าง0 |
access | 10 = การคุมจอ | ควรใส่ 00 ไม่มีนัยสำคัญ | 1 = เปิดจอ 0 = ปิดจอ |
ความสว่างจอ มี 8 ระดับ bit210=xxx ระบุเป็นpulse width =1/16-14/16 000 = 1/16 100 = 11/16 001 = 2/16 101 = 12/16 010 = 4/16 110 = 13/16 011 = 10/16 111 = 14/16 |
---
---
---
---
---
---
---
---
---
---
---
---
---
---
---
-
คลิ๊ก> หมวดหมู่ความรู้
Email :
. . pui108108@yahoo.com
Line ID :
. . pui108diy
โทร: .. 089-797-9411
blog word press :
. . . pui108diy.com/wp/
รูป Flickr :
. . . ./photos/pui108diy/
รูป Wiki commons :
. . ./wiki/User:Pui108108
Pinterest :
. . . ./pui108108/
Youtube :
. . . ./user/p108108
หน้าที่เข้าชม | 214,168 ครั้ง |
ผู้ชมทั้งหมด | 167,913 ครั้ง |
เปิดร้าน | 17 ก.ย. 2558 |
ร้านค้าอัพเดท | 15 ก.ย. 2568 |