วันศุกร์ที่ 20 พฤษภาคม พ.ศ. 2559

AVR C - เขียนโปรแกรมแสดงผลทาง LED 7 Segments

LED 7 Segments เป็นอุปกรณ์พื้นฐานอีกชิ้นหนึ่งที่คนเขียนโปรแกรมด้านไมโครคอนโทรลเลอร์ต้องเรียนรู้ เพราะเป็นพื้นฐานของการทำงานระดับบิตที่ชัดเจนตรงไปตรงมาที่สุด เพราะตัว LED มี 7 bit ในการแสดงผล เพื่อให้เป็นตัวเลข และสามารถใช้แสดงผลตัวอักษรได้ แต่ไม่ครบทุกตัว

LED แบบ 7 Segments สังเกตที่ตัวเลขจะมีขีด 7 ขีดเพื่อสร้างตัวเลข หรือตัวอักษร
จากรูปที่แสดงไว้ข้างบน มี 4 หลัก หรือ 4 Digits และระหว่างหลักจะมี จุด และ : รวมถึง จุดที่ใช้แสดงองศา 

หลักการทำงานของ LED


LED 4 Digits 7 Segment แบบ Anode ร่วม สังเกตที่หมายเลขจะเป็น 3492BW แบบ B คือ Anode Common

Types 7 segment displays
หลักการทำงานแบบ A คือ Common Cathode และ แบบ B คือ Common Anode

LED แบบ A เป็น Common Cathode โดย LED ทั้ง 7 Segments จะใช้ขา Cathode ร่วมกัน ดังนั้นไฟที่จ่ายออกจากขาตัวคอนโทรลเลอร์จะจ่ายไฟ เข้ากับ LED ทั้ง 7 Segments เพื่อให้ไฟติด

LED แบบ B เป็น Common Anode โดย LED ทั้ง 7 Segments จะใช้ขา Anode ร่วมกัน ดังนั้นที่ขา LED ทั้ง 7 ด้านที่เป็น Cathode ซึ่งต่อเข้ากับขาคอนโทรลเลอร์จะเป็น 0 ถึงไฟ LED ถึงจะติด


ตำแหน่งแต่ละ Segments
ผังแสดงการเชื่อมต่อแบบ อาโนดร่วม


การต่อใช้งานขา enable จะกำหนดเป็น HIGH และขา a-g และ dp จะเป็น LOW
การใช้งาน LED แบบ Common Anode จะกำหนดให้ขา enable หรือขาควบคุมซึ่งเป็นขาร่วม ในที่นี้เป็นขา Anode ซึ่งรับไฟบวก หรือ HIGH ดังนั้นขานี้จะกำหนดให้เป็น 1 หรือ HIGH เพื่อจ่ายไฟเข้ามายัง LED

และที่ขา a-g และ dp นั้นจะรับไฟ 0 หรือ LOW เพื่อให้ LED ติด ปกติแล้วจะกำหนดให้เป็น 1 หรือ HIGH เช่นกัน และถ้าต้องการให้หลอดไหนติด ก็กำหนดให้ขานั้นๆ เป็น 0 หรือ LOW

หลักการเชื่อมต่อที่ใช้ในบทความนี้เป็นหลักการง่ายๆ ที่ทดลองให้เห็นภาพ หากนำไปใช้งานจริงต้องออกแบบวงจรใหม่เพื่อป้องกัน LED และ IC ไม่ให้ทำงานหนักเกิน โดยจำกัดกระแสด้วย R และหาก LED ที่ใช้กระแสมากก็ควรใช้แหล่งจากภายนอก และให้ต่อขา a-g และ dp ลงกราวน์โดยผ่านทรานซิสเตอร์ แล้วที่ขา PORTB ก็จะเปลี่ยนไปจ่ายไฟออกมาเพื่อจ่ายไบแอสให้กับขาเบสของทรานซิสเตอร์แทน

ตัวอย่างการต่อโดยใช้ Transistor เป็นตัวขับ (ภาพจาก electronicscircuit.com)

ตัวอย่างโปรแกรมและผลที่ได้

#define F_CPU 8000000l
#include <avr/io.h>
#include <util/delay.h>

#define DIGIT1 0
#define DIGIT2 1
#define DIGIT3 2
#define DIGIT4 3

#define D12 2
#define D3 3


int main(void)
{
  DDRB = 0xFF;
  DDRC = 0xFF;
  DDRD = 0xFF;

  PORTB = 0x00;
  PORTD |= ((0<<D12) | (0<<D3));
  //Turn LED on and off 2 times.
  for (int i = 0; i < 2; i++){
    //Test all segments, by turn enable pins to HIGH.
    PORTC |= ((1<<DIGIT1) | (1<<DIGIT2) | (1<<DIGIT3) | (1<<DIGIT4));
    _delay_ms(300);
    //Turn of all segments by turn enable pins to LOW.
    PORTC &= ((0<<DIGIT1) | (0<<DIGIT2) | (0<<DIGIT3) | (0<<DIGIT4));
    _delay_ms(300);
  }

  int num[11] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90, 0x7F};
  while (1){
    for (int n = 3; n >=0; n--){
      PORTC = (1<<n);
      for (int i = 0; i < 11; i++){
        PORTB = num[i];
        _delay_ms(100);
      }
      PORTB = 0xff;
      _delay_ms(500);
    }
  }
}



ตัวอย่างข้างบนเป็นตัวอย่างที่กำหนดให้แสดงตัวเลข 0-9 และเรียงจากหลักที่ 1, 2, 3 และ 4 จากซ้ายไปขวา ซึ่งดูจะซับซ้อนพอควร แต่ผู้เขียนจะขอลงตัวอย่างง่ายๆ สำหรับทดสอบเพียง 1 หลัก ดังนี้


#define F_CPU 8000000l
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
  DDRB = 0b11111111;
  DDRC = 0b11111111;
  DDRD = 0b11111111;

  PORTB = 0b00000000; //กำหนดให้ PORTB เป็นสถานะ LOW เพื่อกำหนดเป็นไฟ 0V
  PORTD = 0b00000000; //กำหนดให้ PORTD เป็นสถานะ LOW เพื่อกำหนดเป็นไฟ 0V

  PORTC = 0b00000001; //กำหนดให้ PORTC.0 เป็นสถานะ HIGH เพื่อจ่ายไฟ 5V 

}


สัญญานที่ส่งออจากขา PORTB และ PORTC 



ไม่มีความคิดเห็น:

แสดงความคิดเห็น

Gtk4 ตอนที่ 6 Defining a Child object

Defining a Child object A Very Simple Editor ในบทความที่ผ่านมาเราสร้างโปรแกรมอ่านไฟล์ชนิดข้อความ และในบทความนี้ก็จะมาปรับแต่งโปรแกรมกันสักหน...