วันพฤหัสบดีที่ 19 พฤษภาคม พ.ศ. 2559

ATmega16+LCD เริ่มเขียนโปรแกรมติดต่อ LCD

หลังจากที่ทดสอบบอร์ด ATmega16 ได้แล้ว ก็เริ่มศึกษาการใช้งาน เริ่มต้นก็ทำให้ LED กระพริบ และรับค่าทาง input ที่เป็นสวิทช์กดติดปล่อยดับได้แล้ว แต่ก็ยังไม่ค่อยเข้าใจหลักการที่แท้จริง เลยลองต่อ LCD เพื่อแสดงผล โดยปกติในเว็บต่างๆ มักเป็นตัวอย่างการเชื่อมต่อ และเขียนโปรแกรมโดยใช้ lcd.h

แต่ก็ยังไม่เป็นที่พอใจเพราะตัวอย่างยังไม่ทราบหลักการพื้นฐานการติดต่อ และการส่งคำสั่งไปยังอุปกรณ์ (LCD) ดังนั้นจึงค้นหาไปเรื่อยๆ เพื่อหาตัวอย่างง่ายๆ สั้นๆ แต่ครอบคลุมพื้นฐานโดยไม่ต้องใช้ไลบรารีภายนอก

ATmega16+LCD

มีตัวอย่างอยู่ในเว็บแห่ง electronics hub มีตัวอย่างการใช้งาน 16x2 LCD กับ ATmega16 อยู่ด้วย แต่วงจรที่ให้มากับโปรแกรมไม่ตรงกันจึงต้องแก้ไขนิดหน่อย

สำหรับเว็บเรียนรู้เกี่ยวกับเขียนโปรแกรมติดต่อกับ LCD ผ่าน Arduino IDE ก็ลองอ่านจากเว็บของ thaieasyelec นะครับ

และเว็บ www.kanda.com จะมีเรื่อง AVR keypad LCD in WinAVR C จะมีตัวอย่างคำสั่งให้ศึกษาอีกเว็บหนึ่ง


ตัวหนังสือสีแดงที่ขา IC คือ ขาที่ใช้ในโปรแกรมตัวอย่าง

จากรูปข้างบน ขา 1 และ ขา 16 ของ LCD ต่อลงกราวน์ ขา 2 และ 3 ต่อเข้ากับ VR ค่า 10k เพื่อปรับความสว่างของหน้าจอ LCD รุ่นนี้มีไฟแบ็คไลท์ต้องต่อเข้าขา 15 จะให้ปลอดภัยควรต่อ R ค่า 220โอห์ม คั่นไว้สักหน่อยจะดีกว่าเพื่อจำกัดกระแส

ขา 4,5 และ 6 เป็นขาสำหรับควบคุมต่อเข้ากับขา PD0, 1 และ 2


การเชื่อมต่อขากับบอร์ดทดลอง
ส่วนขา data ต่อเข้ากับขา PB0-PB7 ใช้เต็มทั้ง 8 เส้น (ครั้งหน้าจะลดเหลือ 4 เส้น)

ตัวอย่างโปรแกรมเขียนไว้ในไฟล์เดียว

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

#define LCD_DATA PORT //LCD data port
#define ctrl PORTD
#define en PD2 // enable signal
#define rw PD1 // read/write signal
#define rs PD0 // register select signal

void LCD_cmd(unsigned char cmd);
void init_LCD(void);
void LCD_write(unsigned char data);
void LCD_write_string(unsigned char *str);

int main()
{
  DDRB=0xff; // setting the port B
  DDRD=0x07; // setting for port D
  init_LCD(); //   initialization of LCD
  _delay_ms(50); // delay of 50 mili seconds
  LCD_write_string("hello world");// function to print string on LCD
  LCD_cmd(0xC0);  // เพิ่มให้ขึ้นบรรทัดใหม่
  return 0;
}

void init_LCD(void)
{
  LCD_cmd(0x38); // initialization of 16X2 LCD in 8bit mode
  _delay_ms(1);
  LCD_cmd(0x01); // clear LCD
  _delay_ms(1);
  LCD_cmd(0x0E); // cursor ON
  _delay_ms(1);
  LCD_cmd(0x80); // —8 go to first line and –0 is for 0th position
  _delay_ms(1);
  return;
}

void LCD_cmd(unsigned char cmd)
{
  LCD_DATA=cmd;
  ctrl =(0<<rs)|(0<<rw)|(1<<en);
  _delay_ms(1);
  ctrl =(0<<rs)|(0<<rw)|(0<<en);
  _delay_ms(50);
  return;
}

void LCD_write(unsigned char data)
{
  LCD_DATA= data;
  ctrl = (1<<rs)|(0<<rw)|(1<<en);
  _delay_ms(1);
  ctrl = (1<<rs)|(0<<rw)|(0<<en);
  _delay_ms(50);
  return ;
}

void LCD_write_string(unsigned char *str)
{
  int i=0;
  while(str[i]!='\0'){
  // loop will go on till the NULL character in the string
    LCD_write(str[i]); // sending data on LCD byte by byte
    i++;
  }
  return;
}


ข้อมูลทั่วไป
(ส่วนนี้เป็นการอธิบายตามความเข้าใจอาจจะผิดพลาด ซึ่งจะพยายามค้นคว้าและกลับมาแก้ไขเพิ่มเติม)


  • ขา RS จะเป็นขาสำหรับบอกให้ตัวควบคุม LCD ทราบว่ารหัสที่ส่งมาเป็นคำสั่งหรือข้อมูล
  • ขา R/W จะกำหนดว่าเป็นการเขียนหรืออ่าน ปกติแล้วหลายวงจรจะต่อลงกราวน์ เพื่อให้เป็นการเขียน
  • ขา E เป็นขากำหนดการใช้งานถ้ากำหนดให้เป็น 1 คือ การเขียน และถ้ากำหนดเป็น 0 จะไม่รับข้อมูลคำสั่งใดๆ (?)
  • ขา D0-D7 เป็นขาสัญญานเพื่อแสดงผลออกทาง LCD หากใช้ครบเรียกว่า 8bit ถ้าใช้แค่ 4 เส้นคือ D4-D7 เรียกว่าใช้งานแบบ 4bit 



คำสั่งอื่นๆ

#define LCD_CLR 0x01 // clear LCD
#define LCD_8BIT 0x38 // 8-bit mode
#define LCD_INC 0x06  //Increment, display freeze
#define LCD_MOV 0x10  //Cursor move, not shift
#define LCD_ALL  0x0F // LCD On, LCD display on, cursor on and blink on
#define LCD_ON           0x08      // turn lcd/cursor on             
#define LCD_ON_DISPLAY   0x04      // turn display on              
#define LCD_ON_CURSOR    0x02      // turn cursor on               
#define LCD_ON_BLINK     0x01      // cursor blink
#define LCD_LINE1  0x80        // cursor Pos on line 1 (or with column)
#define LCD_LINE2  0xC0        // cursor Pos on line 2 (or with column)

เราสามารถกำหนดค่าคำสั่งเหล่านี้ก่อนที่จะส่งค่าให้กับฟังก์ชัน LCD_cmd ก็จะสะดวกในการใช้งาน เช่น

LCD_cmd(LCD_LINE1);
LCD_write_string("ATmega16 w LCD");
LCD_cmd(LCD_LINE2);
LCD_write_string("ZeroController");

นอกจากนี้คำสั่งเรายังสามารถระบุตำแหน่งเคอร์เซอร์ขณะเลื่อนบรรทัดได้ เช่น

LCD_cmd(LCD_LINE2 | 3);

สั่งเลื่อนไปบรรทัดที่ 2 คอลัมน์ที่ 3

อธิบายโค้ดเพิ่มเติม


  1. #define F_CPU 8000000L
  2. #include <avr/io.h>
  3. #include <util/delay.h>

บรรทัดที่ 1 กำหนดค่า FUSE สำหรับกำหนดความถี่ที่จะทำงานในที่นี้เลือก 8MHz
บรรทัดที่ 2 เรียกใช้งานคำสั่งใน io.h ซึ่งอยู่ในโฟลเดอร์ avr
บรรทัดที่ 3 เรียกใช้งานคำสั่งเกี่ยวกับการหน่วงเวลา ที่อยู่ในไฟล์ delay.h ในโฟลเดอร์ util

โดยปกติแล้วไฟล์ include จะอยู่ใน C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include โดยภายในจะมีโฟลเดอร์ย่อย avr, util และ compact เราสามารถคัดลอกไฟล์ที่จะใช้งานไปไว้ในนี้ เช่น lcd ภายในบรรจุไฟล์ lcd.h เวลาเรียกใช้งานจะเรียกดังนี้

#include <lcd/lcd.h>







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

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

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

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