ETT :: Article :: ARM:STM32:STM8 :: Arduino STM32: EP5 7-Segment

© 2020,จารุต บุศราทิจ


ครั้งก่อนเราได้ใช้บอร์ด ET-STM32F103 เชื่อต่อกับเซ็นเซอร์อุณหภูมิ DS18x20 จากชุด PROBE DS18B20 HAT เพื่ออ่านค่าอุณหภูมิแลพแสดงผลที่ LCD 16x2 I2C เป็นที่เรียบร้อยแล้ว ... คราวนี้บทความรอบนี้ไม่เกี่ยวอะไนกับก่อนหน้านี้เลยครับ (แฮร่) ... วันนี้เรามาเรียนรูปใช้งานเจ้า 7-Segment กันครับ โดยใช้โมดูล ET-mini SEG-A ซึ่งเป็น LED 7-Segment สีแดงขนาด 1 หลัก พร้อมวงจรตัวต้านทานพร้อมสรรพเป็นที่เรียบร้อย และใช้ขั้วต่อแบบ 10 ขาของอีทีที ทำให้สามารถนำมาเสียบโป๊ะบนบอร์ดคอนโทรลเลอร์ได้เลยอย่างนี้ครับ

เป้าหมาย

อุปกรณ์ที่ต้องใช้

มาทำความรู้จัก ET-mini SEG-A

รูปร่างหน้าตาของ 7-Segment ที่เราเลือกใช้กันเป็น ET-mini SEG-A ใช้ 7-SEGMENT เบอร์ TOS-5161B COMMOND ANODE ต่อวงจรเข้ากับ PORT แบบ SINK กระแสซึ่งมีรูปร่างหน้าตาด้านหน้าและหลังดังภาพต่อไปนี้

จะพบว่าบน 7-Segment มีแอลอีดีทั้งสิ้น 8 ดวง สำหรับเป็นส่วนต่าง ๆ เรียกชื่อว่า A, B, C, D, E, F และ DP ดังภาพอ้างอิงต่อไปนี้

นั่นหมายความว่า หน้าที่ของเราคือสั่งเปิด/ปิดการเปล่งแสงของแอลอีดีและมันก็จะส่งผลให้ดูเป็นตัวเลขต่าง ๆ ได้ และคราวนี้จะสั่งอย่างไรแล้วหลอดติดสว่าง และสั่งอย่างไรแล้วดับล่ะ ... มาดูภาพการต่อวงจรของเจ้าตัวนี้กันครับ

พบข้อสังเกตอะไรไหมครับ ... เจ้าขาร่วมเป็น Vdd ซึ่งเป็นขารับแรงดันไฟฟ้ากระแสตรง ก็แปลว่า การจะให้หลอดติดตต้องให้ครบวงจรไฟฟ้า มีไฟเข้า ผ่านโหลด และลงกราวด์ โหลดถึงจะทำงานหรือติด ...​ตามหลักการนี้ หมายความว่าอะไรเอ่ย ....​ติ๊ก ต่อก ติ๊ก ต่อก อ้อก อ่อก ... ถ้าเราให้ขาที่เชื่อมต่อกับหลอด A ดึง DP เป็น 0 หมายความว่าเปลี่ยนสถานะที่พอร์ตให้เป็นกราวด์ ไฟ้าฟ้าไหลผ่านโหลดได้ หลอดก็ติด ... ทางกลับกัน ถ้าเรากำหนดให้ขาของพอร์ตมีสถานะเป็น 1 ซึ่งคือเป็นไฟเหมือนกัน มันก็ไม่มีกราวด์ โหลดไม่ทำงาน หรือ หลอดไม่ติด (อธิบายแบบไม่นักไฟฟ้าและนักิเล็กทรอนิกส์น่อ ...) ... ฮั่นแน่ ...​มองออกแล้วเนอะ ส่ง 0 ติด ส่ง 1 ดับ!!!

เอาล่ะคราวนี้ผมได้ออกแบบตัวแปรเพื่อเก็บข้อมูลการติดและดับของแต่ละหลอดเพื่อให้ได้ผลลัพธ์ตามภาพแสดง 0 1 2 3 4 5 6 7 8 9 a b c d e และ f โดยตัวแปร segment ผมสร้างเป็นแถวลำดับ 2 มิติ คือ มี 16 แถว แถวละ 8 ข้อมูล เจ้า 8 ข้อมูล คือ ใช้แทนสถานะดิจิทัลที่ขา a b c d e f g และ dp ตามหลัก 0 ติด 1 ดับ และเรามีตัวเลข 16 ตัว จึงต้องสร้างเป็น 16 แถว และเลือกประเภทข้อมูลเป็น unsigned char เพราะประหนัดที่สุดทำหรับการเขียนแบบเจ้าใจหลักการ ... จริง ๆ ประหยัดกว่านี้อีกเยอะมากครับ ให้มองเป็นเลขฐาน 2 ซะ เราก็จะเหลือข้อมูล unsigned char เพียง 16 ตัวเท่านั้น ประหยัดไหมหนอ ... ลองคิดตามนะครับ ตอนนี้เราใช้ 1 ข้อมูล 1 ไบต์ เราต้องใช้ 16x8 ข้อมูล ...​กับอีกวิธีเราใช้ 16 ข้อมูล ... เรียกได้ว่าที่เรากำลังเขียนตอนนี้กินหน่วยความจำเยอะกว่าถึง 8 เท่า ... แต่อย่างว่าครับ เอาเข้าใจง่ายไว้ก่อน โปรแกรมทีดีและเร็ว ๆ มักเขียนด้วยวิธีการซับซ้อน (คร่อก ยาก... เนอะ)

unsigned char segment[16][8] = {
// a b c d e f g dp
{0,0,0,0,0,0,1,1}, // 0
{1,0,0,1,1,1,1,1}, // 1
{0,0,1,0,0,1,0,1}, // 2
{0,0,0,0,1,1,0,1}, // 3
{1,0,0,1,1,0,0,1}, // 4
{0,1,0,0,1,0,0,1}, // 5
{0,1,0,0,0,0,0,1}, // 6
{0,0,0,1,1,1,1,1}, // 7
{0,0,0,0,0,0,0,1}, // 8
{0,0,0,0,1,0,0,1}, // 9
{0,0,0,0,0,1,0,1}, // a
{1,1,0,0,0,0,0,1}, // b
{1,1,1,0,0,1,0,1}, // c
{1,0,0,0,0,1,0,1}, // d
{0,1,1,0,0,0,0,1}, // E
{0,1,1,1,0,0,0,1} // F
};

















คราวนี้เราต่อวงจรอย่างไร ก็อย่างภาพด้านบนครับ โปะแหมะลงไปที่ PB8-PB15 ได้เลย สะดวกมาก

ตัวอย่างที่ 1 : แสดง 0 ถึง f วน ๆ

unsigned char segment[16][8] = {
// a b c d e f g dp
{0,0,0,0,0,0,1,1}, // 0
{1,0,0,1,1,1,1,1}, // 1
{0,0,1,0,0,1,0,1}, // 2
{0,0,0,0,1,1,0,1}, // 3
{1,0,0,1,1,0,0,1}, // 4
{0,1,0,0,1,0,0,1}, // 5
{0,1,0,0,0,0,0,1}, // 6
{0,0,0,1,1,1,1,1}, // 7
{0,0,0,0,0,0,0,1}, // 8
{0,0,0,0,1,0,0,1}, // 9
{0,0,0,0,0,1,0,1}, // a
{1,1,0,0,0,0,0,1}, // b
{1,1,1,0,0,1,0,1}, // c
{1,0,0,0,0,1,0,1}, // d
{0,1,1,0,0,0,0,1}, // E
{0,1,1,1,0,0,0,1} // F
};
int idx=0;
int num=0;
void setup() {
for (idx=PB8; idx<=PB15; idx++) {
pinMode( idx, OUTPUT );
}
}
void showNum(int num) {
for (idx=0; idx<=15; idx++) {
digitalWrite( PB8+idx, segment[num][idx]);
}
}
void loop() {
showNum( num );
delay(1000);
num++;
if (num > 15) num=0;
}

ตัวอย่างที่ 2 : สุ่ม 0 ถึง f วน ๆ ทุก 1 วินาที

unsigned char segment[16][8] = {
// a b c d e f g dp
{0,0,0,0,0,0,1,1}, // 0
{1,0,0,1,1,1,1,1}, // 1
{0,0,1,0,0,1,0,1}, // 2
{0,0,0,0,1,1,0,1}, // 3
{1,0,0,1,1,0,0,1}, // 4
{0,1,0,0,1,0,0,1}, // 5
{0,1,0,0,0,0,0,1}, // 6
{0,0,0,1,1,1,1,1}, // 7
{0,0,0,0,0,0,0,1}, // 8
{0,0,0,0,1,0,0,1}, // 9
{0,0,0,0,0,1,0,1}, // a
{1,1,0,0,0,0,0,1}, // b
{1,1,1,0,0,1,0,1}, // c
{1,0,0,0,0,1,0,1}, // d
{0,1,1,0,0,0,0,1}, // E
{0,1,1,1,0,0,0,1} // F
};
int idx=0;
void setup() {
for (idx=PB8; idx<=PB15; idx++) {
pinMode( idx, OUTPUT );
}
randomSeed( millis() );
}
void showNum(int num) {
for (idx=0; idx<=15; idx++) {
digitalWrite( PB8+idx, segment[num][idx]);
}
}
void loop() {
int num = random(0, 15);
showNum( num );
delay(1000);
}

สรุป

เรียบร้อยครับ ...​จบแระการควบคุม 7-segment ... และขอขอบคุณที่ติดตามอ่านกันครับผม ... แจ๋วหลบ จบแล้ว (ขอใช้คำของคุณคำรณ ^_^)

:----: บทความก่อนหน้านี้ :----: บทความ ARM :----:

--ไม่สามารถเข้าถึงฐานข้อมูลได้--