Hướng dẫn Điều khiển LCD 16x02 dùng AVR cho người mới bắt đầu

tran19957

Học sinh phổ thông
#51
Anh hướng dẫn em cách đấu chân atmaga8 với mạch thu phát quang đo tốc độ của động cơ lên màn hình LCD 162
 

tung_aokiji

Học sinh phổ thông
#52
các tiền bối cho mình hỏi cái!
tại sao khi mô phỏng trên proteus thì ok mà khi hiển thị lcd thực tế thì nó chỉ hiển thị dấu "?" thôi!
 
#53
Trong bài này chúng ta sẽ thực hiện viết một chương trình đơn giản cho người mới tìm hiểu về AVR để điều khiển hoạt động của LCD.

LCD được sử dụng rất phổ biến đảm nhận vai trò hiển thị thông tin được lập trình sẵn hoặc các thông tin đã qua xử lý của bộ điều khiển hoặc vi xử lý. Giúp chúng ta dễ dàng giao tiếp, điều khiển cũng như giám sát hoạt động của hệ thống.

Chúng ta sử dụng loại LCD 16x02, có 2 dòng trên màn hình và mỗi dòng có thể hiển thị 16 ký tự. LCD được nối với PORTD như hình sau:
Xem đính kèm 6345

Trong đó:

Các chân 1,2: Cấp nguồn cho LCD hoạt động.
Chân 3 (VSS): Điều chỉnh độ tương phản.
Chân 15,16: Đây là 2 chân cấp nguồn đèn nền.
Chân 4 đến 14: Các chân điều khiển, truyền dữ liệu.

Chúng ta sẽ sử dụng CodeVisionAVR để lập trình phần mềm cho vi điều khiển.

Về cơ bản:
1. Vào menu File/New.
2. Chọn File Type là Project.
Xem đính kèm 6346


3. Chọn YES để dùng CodeWizard.

Xem đính kèm 6347

4. Chọn Atmega8, thạch anh 8MHz
Xem đính kèm 6348


5. Ở tab LCD, chọn sử dụng PORTD.

Xem đính kèm 6349

6. Chọn File Generate, Save and Exit. Lưu project và các file liên quan vào thư mục bạn muốn.
7. Trong vòng while(1) ở hàm main() ta viết các câu lệnh như sau:
Mã:
while (1)

{

lcd_clear();

lcd_putsf("Hello world");

lcd_gotoxy(0,1);

lcd_putsf("dangsonbk");

delay_ms(1000);

};
Hoặc bạn có thể xóa vòng while(1) và thay bằng:
Mã:
lcd_clear();

lcd_putsf("Hello world");

lcd_gotoxy(0,1);

lcd_putsf("dangsonbk");
Để biên dịch chương trình bạn vừa viết, bạn nhấn Ctrl + F9 hoặc trong menu Project/Build All. Nếu không có lỗi xảy ra, chương trình của bạn đã sẵn sàng để nạp vào vi điều khiển.

Khi bạn đã làm việc quen với AVR, bạn có thể không cần dùng tới CodeWizard nữa, khi đó bạn sẽ phải tự khai báo các thanh ghi, các hàm ngắt cần thiết. Dĩ nhiên đó là khi bạn đã hiểu về cấu trúc của AVR và sử dụng khá thành thạo CodeVisionAVR.
Tiếp theo bạn sẽ làm việc với Proteus để vẽ và mô phỏng.
Xem đính kèm 6345


Bạn cần chọn các linh kiện và vẽ mạch như hình trên. Gồm có vi điều khiển Atmega8 và LCD 16x2. Bạn có thể download file đính kèm ở bài viết và sử dụng nếu chưa quen với việc sử dụng Proteus.
Tiếp đó, bạn double click vào con chíp, chọn như hình dưới:

Xem đính kèm 6350

Bấm nút chạy:
Xem đính kèm 6351

Kết quả chương trình của chúng ta:
Xem đính kèm 6344

Ngoài ra để lập trình cho AVR bạn có thể sử dụng trình biên dịch AVR Studio do chính hãng Atmel cung cấp miễn phí trên trang chủ.

>> Hiển thị số trên LCD.
>> Hiển thị số thập phân. Bởi: mta_cdt
Chúc các bạn thành công!
Em có 1 thắc mắc là,nếu quá trình thiết lập như vậy thì đối với 1 AVR ta chỉ có thể điều khiển được 1 lcd,vấn đề đặt ra là muốn gắn 2 lcd vào 2 PORT
 

kingh3

Học sinh phổ thông
#54
Cảm ơn 2 bạn, :)
Để hiển thị số, chúng ta có thể tạo thêm hàm sau:
Mã:
void lcd_putnum( int number)
{
    if(number/1000!=0)  lcd_putchar((number/1000)+48);
    if(number/100!=0)  lcd_putchar((number%1000)/100+48);
    if(number/10!=0)    lcd_putchar((number%100)/10+48);
    lcd_putchar((number%10)+48);
}
Mục đích là để tách các hàng phần nghìn, chục, đơn vị của một số, sau đó chuyển số qua thành ký tự bằng cách cộng thêm vào đó 48 (mở bảng ASCII ra bạn sẽ hiểu ngay vấn đề) và cuối cùng xuất ra LCD giống như khi ta xuất ký tự bình thường bằng hàm lcd_putchar();
Tiếng Việt thì phải tự tạo font thôi, sau đó dùng nốt mấy chân còn lại của LCD để truyền. Nếu mình nhớ không nhầm thì chỉ dùng 4 chân để truyền dữ liệu thì không truyền được font tự tạo.
Có một cách đơn giản hơn đó là viết không dấu. :P
anh cho em hỏi nếu mình muốn hiển thị hai thông số khác nhau lên lcd thì làm thế nào ạ, em thử mãi mà không được. cảm ơn ạ.
 

dangsonbk

I'm aimin' right at you!
Thành viên BQT
#55
anh cho em hỏi nếu mình muốn hiển thị hai thông số khác nhau lên lcd thì làm thế nào ạ, em thử mãi mà không được. cảm ơn ạ.
Mình không hiểu ý bạn: "hiển thị hai thông số khác nhau " nghĩa là thế nào
 

kingh3

Học sinh phổ thông
#56
Mình không hiểu ý bạn: "hiển thị hai thông số khác nhau " nghĩa là thế nào
nghĩa là trên lcd mình cho hiển thị hai loại thông số khác nhau ví dụ như là Udk của động cơ và số xung Encoder báo về (trong bài toán điều khiển vị trí động cơ), hai thông số này nó biến đổi theo thời gian. em viết nó cứ nhảy lẫn lộn hai thông số mình muốn hiển thị không nhìn được cái gì.
 

mta_cdt

Super Moderator
Thành viên BQT
#57
nghĩa là trên lcd mình cho hiển thị hai loại thông số khác nhau ví dụ như là Udk của động cơ và số xung Encoder báo về (trong bài toán điều khiển vị trí động cơ), hai thông số này nó biến đổi theo thời gian. em viết nó cứ nhảy lẫn lộn hai thông số mình muốn hiển thị không nhìn được cái gì.
Cái này thì không thiếu gì cách cả.
vd hai thông số udk và encoder của bạn là số int nhé thì mình viết thế này là ok luôn
unsigned char buff[10];
sprintf(buff,"%u %u",udk,encoder);
lcd_gotoxy(0,0);
lcd_puts(buff);
thế là ok thôi.
 

kingh3

Học sinh phổ thông
#58
Cái này thì không thiếu gì cách cả.
vd hai thông số udk và encoder của bạn là số int nhé thì mình viết thế này là ok luôn
unsigned char buff[10];
sprintf(buff,"%u %u",udk,encoder);
lcd_gotoxy(0,0);
lcd_puts(buff);
thế là ok thôi.
cảm ơn giáo sư Đức Lành nhiều.
 

nmc12345

Học sinh trung cấp
#59
các bạn cho mình hỏi cách viết hàm chờ LCD rảnh bằng avrstudio, mình viết mãi nó toàn báo sai
thanks
 

codientu98

Học sinh trung cấp
#60
giúp mình với,mach đo nhiệt độ của mình dùng ds18b20 và atmega8 hiển thị lcd16x2. lcd chỉ hiển thị -9999.000 mình đã, kiểm tra hết rồi, chân cẳn đều đúng như khai báo, cả ds mình cũng nhờ chỗ mình mua kiểm tra rồi vẫn còn sống. lạ 1 cái nữa là trên mô phỏng, mình mở 2 file có thể nói là nối chân như nhau, nạp cùng 1 chương trình nhưng 1 bên thì hiển thị nhiệt độ được một bên thì -9999.000. mạch mình cắm trên test board cũng -9999.000... mình hết cách rồi (đau đầu với nó lắm rồi.....@-)), cầu cứu các bạn.

mình không chèn tập tin lên được, còn đây là code
Mã:
/*****************************************************
This program was produced by the
CodeWizardAVR V2.05.0 Professional
Automatic Program Generator
© Copyright 1998-2010 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project :
Version :
Date    : 25-08-2015
Author  : NeVaDa
Company :
Comments:


Chip type               : ATmega8
Program type            : Application
AVR Core Clock frequency: 8.000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 256
*****************************************************/

#include <mega8.h>

// 1 Wire Bus interface functions
#include <1wire.h>

// DS1820 Temperature Sensor functions
#include <ds18b20.h>
#include <delay.h>
#include <stdio.h>
// Alphanumeric LCD Module functions
#include <alcd.h>

// Declare your global variables here

void main(void)
{
// Declare your local variables here
   char LCD_Buffer[15];
   unsigned char *T=0;
   float nhiet_do;
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// USART initialization
// USART disabled
UCSRB=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC disabled
ADCSRA=0x00;

// SPI initialization
// SPI disabled
SPCR=0x00;

// TWI initialization
// TWI disabled
TWCR=0x00;

// 1 Wire Bus initialization
// 1 Wire Data port: PORTB
// 1 Wire Data bit: 3
// Note: 1 Wire port settings must be specified in the
// Project|Configure|C Compiler|Libraries|1 Wire IDE menu.
w1_init();

// Alphanumeric LCD initialization
// Connections specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTB Bit 0
// RD - PORTB Bit 1
// EN - PORTB Bit 2
// D4 - PORTB Bit 4
// D5 - PORTB Bit 5
// D6 - PORTC Bit 0
// D7 - PORTC Bit 1
// Characters/line: 16
lcd_init(16);

while (1)
      {
      // Place your code here
     
      nhiet_do=ds18b20_temperature(T);
      sprintf(LCD_Buffer, "temp: %f2.2",nhiet_do);
      lcd_gotoxy(0,1);
      lcd_puts(LCD_Buffer);
      delay_ms(500);
      }
}
 
Sửa lần cuối:

Quảng cáo Google