PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   Các ngôn ngữ lập trình khác (CCS C, HT PIC,...) (http://www.picvietnam.com/forum/forumdisplay.php?f=12)
-   -   Điều khiển LCD16x2 bằng MPLABC18 (http://www.picvietnam.com/forum/showthread.php?t=11541)

rocket42 25-10-2011 03:50 PM

Điều khiển LCD16x2 bằng MPLABC18
 
1 Attachment(s)
Điều khiển LCD là ứng dụng thông thường khi học Pic cũng như bất cứ loại VDK nào. Và khi đã điều khiển được nó rồi ta sẽ thấy nó rất tiện dụng trong hiển thị dữ liệu. Tuy nhiên hơi đắt...
dưới đây là Chương trình lập trình điều khiển LCD16x2 bằng ngôn ngữ C18
có mô phỏng Proteus kèm theo.
good luck!

hc.coltech 04-11-2011 11:51 AM

anh ơi anh xem lại file mplab.code file hex ban đầu thì mô phỏng ok rồi nhưng sao cứ buil là nó bị lỗi vậy nó báo :"putsxlcd.c:20:Warning [2058] call of function without prototype " và ko mô phỏng được bằng proteus nữa vậy

rocket42 04-11-2011 07:26 PM

1 Attachment(s)
a kiểm tra lại thấy OK mà
em dowload lại file dưới rồi buil lại xem nhé
Nếu vẫn lỗi thì chụp hẳn cái cửa sổ Output lại rồi gửi cho a xem

delta21 09-11-2011 10:32 AM

anh R hướng dẫn cho em về mấy cái hàm LCD anh dùng trong ct của anh dc ko?

rocket42 09-11-2011 10:26 PM

OK!
hàm OpenXLCD(unsigned char lcdtype): Cấu hình chế độ làm việc cho LCD
lcdtype bạn có thể cấu hình LCD 4bit hoặc 8bit, hiển thị 1 dòng hay 2, ma trận hiển thị 5x7 hoặc 5x10. Ví dụ như trong file ví dụ R chọn LCD8bit và ma trận 5x7, hiển thị 2 dòng.
hàm BusyXLCD(): kiểm tra cờ bận, nếu bận trả về 1, ko bận trả về 0
hàm WriteCmdXLCD(unsigned char cmd): ghi lệnh tới LCD
hàm SetDDRamAddr(unsigned char DDaddr): đưa con trỏ tới vị trí có địa chỉ DDaddr trong DDRAM để hiển thị
putsXLCD(char *buffer): ghi dữ liệu String tới LCD, cho tới kí tự 'null'
WriteDataXLCD(char data): ghi dữ liệu 'data' tới LCD
chúc thành công!

delta21 12-11-2011 12:00 AM

em vẫn chưa biết làm thế nào để xuất là 1 biến (không phải kiểu string)
trước em có dùng trình dịch HTPIC cho 16f887 nó có 2 file thư viện LCD như này(cái này là em sưu tầm trên mạng)
lcd.h:
Code:

#ifndef _LCD_H_
#define _LCD_H_

#include <htc.h>

#ifndef _XTAL_FREQ
#define _XTAL_FREQ        4000000
#endif


/* Display ON/OFF Control defines */
#define DON        0b00001111  /* Display on      */
#define DOFF        0b00001011  /* Display off    */
#define CURSOR_ON  0b00001111  /* Cursor on      */
#define CURSOR_OFF  0b00001101  /* Cursor off      */
#define BLINK_ON    0b00001111  /* Cursor Blink    */
#define BLINK_OFF  0b00001110  /* Cursor No Blink */

/* Cursor or Display Shift defines */
#define SHIFT_CUR_LEFT    0b00000100  /* Cursor shifts to the left  */
#define SHIFT_CUR_RIGHT  0b00000101  /* Cursor shifts to the right  */
#define SHIFT_DISP_LEFT  0b00000110  /* Display shifts to the left  */
#define SHIFT_DISP_RIGHT  0b00000111  /* Display shifts to the right */

/* Function Set defines */
#define FOUR_BIT  0b00101100  /* 4-bit Interface              */
#define EIGHT_BIT  0b00111100  /* 8-bit Interface              */
#define LINE_5X7  0b00110000  /* 5x7 characters, single line  */
#define LINE_5X10  0b00110100  /* 5x10 characters              */
#define LINES_5X7  0b00111000  /* 5x7 characters, multiple line */


/* Pins mapping */
#ifndef                LCD_RS
#define        LCD_RS                RD1
#define        LCD_EN                RD3
#define        LCD_RW                RD2
#define        LCD_DATA4        RD4
#define        LCD_DATA5        RD5
#define        LCD_DATA6        RD6
#define        LCD_DATA7        RD7

#define        LCD_RS_TRIS                TRISD1
#define        LCD_EN_TRIS                TRISD3
#define        LCD_RW_TRIS                TRISD2
#define        LCD_DATA4_TRIS        TRISD4
#define        LCD_DATA5_TRIS        TRISD5
#define        LCD_DATA6_TRIS        TRISD6
#define        LCD_DATA7_TRIS        TRISD7
#endif

//typedef unsigned char                unsigned char;                                // 8-bit unsigned

typedef union _BYTE_VAL
{
    unsigned char Val;
    struct
    {
        unsigned char b0:1;
        unsigned char b1:1;
        unsigned char b2:1;
        unsigned char b3:1;
        unsigned char b4:1;
        unsigned char b5:1;
        unsigned char b6:1;
        unsigned char b7:1;
    } bits;
} BYTE_VAL;

void lcd_init();
unsigned char lcd_busy();
unsigned char lcd_get_byte(unsigned char rs);
void lcd_put_byte(unsigned char a,unsigned char b);
void lcd_gotoxy(unsigned char col, unsigned char row);
void lcd_putc(char c);
void lcd_puts(const char* s);
#endif


lcd.c
Code:

#include <stdlib.h>
#include <ctype.h>
#include "lcd.h"

void lcd_init(){
        unsigned char i;
        LCD_EN_TRIS = 0;
        LCD_RS_TRIS = 0;
        LCD_RW_TRIS = 0;
        LCD_DATA4_TRIS = 0;
        LCD_DATA5_TRIS = 0;
        LCD_DATA6_TRIS = 0;
        LCD_DATA7_TRIS = 0;
        LCD_EN = 0;
        LCD_RS = 0;
        LCD_RW = 0;

        __delay_ms(100);                                // delay for power on
       
        // reset LCD
        lcd_put_byte(0,0x30);
        __delay_ms(50);
        lcd_put_byte(0,0x30);
        __delay_ms(50);
        lcd_put_byte(0,0x32);
        __delay_ms(100);                                // delay for LCD reset
        __delay_ms(100);                                // delay for LCD reset
        __delay_ms(100);                                // delay for LCD reset
       
        while(lcd_busy());
        lcd_put_byte(0,FOUR_BIT & LINES_5X7);                        // Set LCD type
        while(lcd_busy());
       
        lcd_put_byte(0,DOFF&CURSOR_OFF&BLINK_OFF);                // display off
        while(lcd_busy());
        lcd_put_byte(0,DON&CURSOR_OFF&BLINK_OFF);                // display on
        while(lcd_busy());
       
        lcd_put_byte(0,0x01);                                                        // clear display and move cursor to home
        while(lcd_busy());
        lcd_put_byte(0,SHIFT_CUR_LEFT);                                // cursor shift mode
        while(lcd_busy());
        lcd_put_byte(0,0x01);                                                        // clear display and move cursor to home
        while(lcd_busy());
}
unsigned char lcd_busy()
{
        unsigned char busy;
       
        LCD_DATA4_TRIS = 1;
        LCD_DATA5_TRIS = 1;
        LCD_DATA6_TRIS = 1;
        LCD_DATA7_TRIS = 1;
       
        LCD_RW = 1;
        LCD_RS = 0;
        __delay_us(20);
        LCD_EN = 1;
        __delay_us(20);
       
        busy = LCD_DATA7;
       
        LCD_EN = 0;
        __delay_us(20);
        LCD_EN = 1;
        __delay_us(20);
        LCD_EN = 0;

       
        return busy;
}
unsigned char lcd_get_byte(unsigned char rs)
{
        BYTE_VAL b;
       
        LCD_DATA4_TRIS = 1;
        LCD_DATA5_TRIS = 1;
        LCD_DATA6_TRIS = 1;
        LCD_DATA7_TRIS = 1;
       
        LCD_RW = 1;
        LCD_RS = 0;
        if(rs) LCD_RS = 1;
        __delay_us(20);
        LCD_EN = 1;
        __delay_us(20);
       
        b.bits.b7 = LCD_DATA7;
        b.bits.b6 = LCD_DATA6;
        b.bits.b5 = LCD_DATA5;
        b.bits.b4 = LCD_DATA4;
       
        LCD_EN = 0;
        __delay_us(20);
        LCD_EN = 1;
        __delay_us(20);
        b.bits.b3 = LCD_DATA7;
        b.bits.b2 = LCD_DATA6;
        b.bits.b1 = LCD_DATA5;
        b.bits.b0 = LCD_DATA4;
        LCD_EN = 0;
       
        return b.Val;
}
void lcd_put_byte(unsigned char rs, unsigned char b)
{
        BYTE_VAL temp;
       
        LCD_DATA4_TRIS = 0;
        LCD_DATA5_TRIS = 0;
        LCD_DATA6_TRIS = 0;
        LCD_DATA7_TRIS = 0;
       
        LCD_RS = 0;
        if(rs) LCD_RS = 1;
       
        __delay_us(20);
        LCD_RW = 0;
        __delay_us(20);
        LCD_EN = 0;
       
        temp.Val = b;
       
        // send the high nibble
        LCD_DATA4 = temp.bits.b4;
        LCD_DATA5 = temp.bits.b5;
        LCD_DATA6 = temp.bits.b6;
        LCD_DATA7 = temp.bits.b7;
        __delay_us(20);
        LCD_EN =  1;
        __delay_us(20);
        LCD_EN = 0;
        // send the low nibble
        LCD_DATA4 = temp.bits.b0;
        LCD_DATA5 = temp.bits.b1;
        LCD_DATA6 = temp.bits.b2;
        LCD_DATA7 = temp.bits.b3;
        __delay_us(20);
        LCD_EN =  1;
        __delay_us(20);
        LCD_EN = 0;
}
void lcd_putc(char c){
        switch(c){
                case '\f':
                        lcd_put_byte(0, 1);
                        while(lcd_busy());
                        break;
                case '\n':
                        lcd_gotoxy(0, 1);
                        break;
                default:
                        if(isprint(c)){
                                lcd_put_byte(1, c);
                                while(lcd_busy());
                        }
                        break;
        }
}

void lcd_gotoxy(unsigned char col, unsigned char row)
{
        unsigned char address;
       
        if(row!=0)
                address=0x40;
        else
                address=0;
       
        address += col;
        lcd_put_byte(0,0x80|address);
        while(lcd_busy());
}
void lcd_puts(const char* s)
{
        while(*s){
                lcd_putc(*s++);
        }
}

với 2 file này em có thể dùng LCD khá dễ dang với lệnh printf ,như trong C chuẩn.
Anh R có thể chỉ cho em cách sửa 2 file này để dùng cho pic 18 dc ko ??
hoặc làm sao để dùng dc với thư viện Lcd của anh!!
thanks anh!!

rocket42 12-11-2011 12:30 AM

hj!
thư viện này hỗ trợ bạn tới tận chân răng rồi. chỉ cần sử dụng thôi
bạn sử dụng nó bằng cách:
- tạo Project như bình thường
- tạo file mới rồi copy nôi dung của file lcd.h bạn có vào rồi lưu file đó là lcd.h
- tao file mới rồi copy nội dung của file lcd.c bạn có vào rồi lưu file đó là lcd.c
- rồi add lcd.h vào thư mục header, lcd.c vào source
- nhưng quan trọng là chỉnh options project: bạn vào project/build options/project
nó sẽ ra cửa sổ option. ở đây trong Directories category bạn xóa thư mục mặc định hoặc dùng thư mục bạn lưu 2 file ở trên lên mức ưu tiên cao nhất
- Rồi.Ok. giờ bạn có thể sử dụng các hàm này thoải mái
chúc may mắn!

delta21 12-11-2011 01:02 AM

thanks anh,nhưng ý em là em muốn dùng 2 file này cho pic 18,cụ thể ở đây là lập trình bằng C18 chứ ko pải HT pic!!

yukul 21-02-2012 02:10 AM

a rocket nhiều bài hay quá.cố gắng phát huy về c18 a nhé.e cũng đang nghiên cứu e này

vipboypro891 29-02-2012 01:36 AM

em bild nó báo lỗi là could not find definition of symbol 'DelayFor18TCY' in file 'busyxlcd.o'

ninhxuanthuan 11-06-2012 04:53 PM

add thêm file busyxlcd.c vào source file là ok nhé vipboy.
Nhân tiện cho em hỏi bác R là sao khi sử dụng file hex nạp thì mô phỏng ok.Nhưng khi sử dụng mplab built ode LCD.c báo success nhưng nạp vào pic thì mô phỏng ko có hiện tượng j là sao vậy?
Thanks!!

minhtan001 28-06-2012 02:12 PM

mình cũng bị lỗi giống hc.coltech đó nó báo thế là sao
LCD8BIT\putrxlcd.c:16:Error [1109] type mismatch in redeclaration of 'putrsXLCD'
nó bị sao mà hok hiểu hàm 'putrsXLCD'

trienst 15-11-2012 02:18 PM

Trích:

Nguyên văn bởi rocket42 (Post 51292)
OK!
hàm OpenXLCD(unsigned char lcdtype): Cấu hình chế độ làm việc cho LCD
lcdtype bạn có thể cấu hình LCD 4bit hoặc 8bit, hiển thị 1 dòng hay 2, ma trận hiển thị 5x7 hoặc 5x10. Ví dụ như trong file ví dụ R chọn LCD8bit và ma trận 5x7, hiển thị 2 dòng.
hàm BusyXLCD(): kiểm tra cờ bận, nếu bận trả về 1, ko bận trả về 0
hàm WriteCmdXLCD(unsigned char cmd): ghi lệnh tới LCD
hàm SetDDRamAddr(unsigned char DDaddr): đưa con trỏ tới vị trí có địa chỉ DDaddr trong DDRAM để hiển thị
putsXLCD(char *buffer): ghi dữ liệu String tới LCD, cho tới kí tự 'null'
WriteDataXLCD(char data): ghi dữ liệu 'data' tới LCD
chúc thành công!

sao mình ko thấy lênh xóa lcd trong xlcd.h
xin lỗi, mình mới tìm hiểu PIC:(


Múi giờ GMT. Hiện tại là 09:20 AM.

Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam