Sử dụng LCD với AVR ATmega8 với thư viện Header rút gọn

Màn hình LCD đuợc sử dụng rộng rãi vì giá thành rẻ và có thể hiển thị nhiều thông tin hơn LED bảy đoạn hoặc ma trận. Hiện nay đã có mạch giao tiếp chuyển sang I2C nhưng học cách làm việc trực tiếp với LCD giúp chúng ta có thể hiểu rõ cách thức điều khiển. Ngoài ra, chúng ta có thể tự xây dựng thư viện cho riêng mình.

LCD loại phổ biến nhất là 16×2, tức là 16 cột 2 hàng. Nó được gắn sẵn chip giao tiếp HD44780.

Thông thường chúng ta sử dụng chế độ truyền nibble để tiết kiệm chân.

Chi tiết về các lệnh xem thêm tại tài liệu hướng dẫn sử dụng HD44780.

Chương trình chính thực hiện việc khởi tạo LCD, hiển thị thông tin ban đầu và sau đó hiển thị thông số. Khi ứng dụng, chúng ta đọc thông số và cập nhật theo chu kỳ lên màn hình LCD theo yêu cầu thực tế.

#define F_CPU 1000000UL

#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <string.h>

#include "lcd16x2.h"

char temp_a[4];
char humid_a[4];

uint8_t d_temp = 30;
uint8_t d_hum = 50;

int main(void)
{
	DDRB = 0xFF;
	PORTB = 0x00;
	//
	_delay_ms(100);
	display_init();		//Initialize LCD
	_delay_ms(100);
	//
	display_clr();
	display("System ",1,0);
	display("Initializing...",2,0);
	//
	
    _delay_ms(500);
	display_clr();
    while (1) 
    {
		display("Temperature:", 1, 1);
		display("Humidity: ", 2, 1);
		//Convert d_tem; d_hum
		itoa(d_temp,temp_a,10);
		//
		itoa(d_hum,humid_a,10);
		//
		display(temp_a,1,13);
		display(humid_a,2,13);
		
		_delay_ms(500);
    }
}

Tạo thư viện

Thư viện sẽ chứa các tập tin header .c và .h nhằm hỗ trợ việc viết chương trình.

Thêm header trong chương trình
  • Chương trình Header .h có nhiệm vụ khai báo thông tin, biến và tên hàm.
#ifndef LCD16X2_H_
#define LCD16X2_H_

#include <avr/io.h>
#include <util/delay.h>
#include <string.h>
//
#define RS PB4
#define E PB5
//
extern volatile uint16_t delay;
extern volatile char string[16];
extern volatile char line;
extern volatile char column;
extern volatile char d;

void display_init(void);

void display(char string[16], char line, char column);

void displaybyte(char d);

void epulse(void);

void display_clr(void);

#endif /* LCD16X2_H_ */
  • Tạo tập tin .h và .c rồi bổ sung vào chương trình chính.
  • Chương trình Header .c là nơi chứa các lệnh thực thi của hàm đuợc khai báo trong tập tin header .h đã khai báo ở trên.
#include "lcd16x2.h"

//
void display_init(void)
{
	uint8_t count;
	//Return home
	//Function set 4bit 2 lines
	//Clear display
	//Display control
	//Entry mode set
	//Move cursor
	char init[]={0x02,0x28,0x01,0x0C,0x06,0x80};
	
	PORTB &= ~(1<<RS);           // RS=0
	for (count = 0; count <= 5; count++)
	{
		displaybyte(init[count]);
	}
	PORTB |= 1<<RS;				//RS=1
	
}
void display(char string[16], char line, char column)
{
	uint8_t len,count;
	char position;

	PORTB &= ~(1<<RS);           // RS=0 Command Mode
	//
	if(line==1)
	{
		position = 0x80 | column;
		displaybyte(position);   //Move Cursor to Line 1
	}
	else
	{
		position = 0xC0 | column;
		displaybyte(position);   //Move Cursor to Line 2
	}
	
	PORTB |= (1<<RS);           // RS=1 Data Mode

	len = strlen(string);
	for (count = 0; count < len; count++)
	{
		displaybyte(string[count]);
	}
	
}
void displaybyte(char d)
{
	//data is in Temp Register
	char C;
	C = d;
	C = C & 0xF0;
	C = C >> 4;
	//Send MSB
	PORTB &= 0xF0;
	PORTB |= C;
	epulse();

	C = d;
	//Send LSB
	C = C & 0x0F;
	PORTB &= 0xF0;
	PORTB |= C;
	epulse();
}
//
void epulse(void)
{
	PORTB |= 1<<E;
	_delay_ms(2); 
	PORTB &= ~(1<<E);
	_delay_ms(2); 
}
//
void display_clr(void)
{
	//Clear display
	PORTB &= ~(1<<RS);			// RS=0 Command Mode
	displaybyte(0x01);			// Clear display
	PORTB |= (1<<RS);			// RS=1 Data Mode
	
}

Sơ đồ kết nối đơn giản như hình sau.

Chú ý viết lưu đồ thuật toán cho từng phần của chương trình.

Leave a Reply

Your email address will not be published. Required fields are marked *