Title: รบกวนขอวิธีการต่อจอ LCD 20x4 กับ PIC16F877 ด้วยครับ
Post by: pakapong16 on September 18, 2009, 07:38:45 PM
พอดีจะทำโครงงาน
จึงลบกวนขอวิธีการต่อจอ LCD 20x4 กับ PIC16F877 และ code การประกาศฟังก์ชันเชื่อมต่อกับจอด้วยครับ
ขอบคุณล่วงหน้าครับ
Title: Re: รบกวนขอวิธีการต่อจอ LCD 20x4 กับ PIC16F877 ด้วยครับ
Post by: s_engine on September 20, 2009, 05:42:01 PM
ต่อเหมือนกัน LCD 16x2 หละครับ ตัวอย่าง แบบ 4 บิต ใช้แค่ขา D4-D7 และ RS RW E
#define LCD_DB4 PIN_D4 #define LCD_DB5 PIN_D5 #define LCD_DB6 PIN_D6 #define LCD_DB7 PIN_D7 #define LCD_RS PIN_E0 #define LCD_RW PIN_E1 #define LCD_E PIN_E2
หรือ
#define LCD_DB4 PIN_D4 #define LCD_DB5 PIN_B1 #define LCD_DB6 PIN_C5 #define LCD_DB7 PIN_B5
#define LCD_RS PIN_E2 #define LCD_RW PIN_B2 #define LCD_E PIN_D6
Title: LCD 20x4 กับ PIC16F877
Post by: pakapong16 on September 21, 2009, 04:06:53 AM
เวลาจะให้มันไปแสดงบรรทัดที่สามและสี่อ่ะคับ
ทำงัย ผมทำไม่เป็น
Title: Re: รบกวนขอวิธีการต่อจอ LCD 20x4 กับ PIC16F877 ด้วยครับ
Post by: s_engine on September 21, 2009, 08:43:20 AM
อยากได้โค้ด ว่างั้น ผมมีโค้ดจาก www.ccsinfo.com credit ท่าน PCM programmer ก้อปมาทั้งดู้น เลย #include <16F877.H> #fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP #use delay(clock = 4000000)
#include <Flex_LCD420.c>
//=================================== void main() { int8 i; int8 b1, b2, b3, b4;
// The lcd_init() function should always be called once, // near the start of your program. lcd_init();
// Clear the LCD. printf(lcd_putc, "\f"); delay_ms(500);
while(1) { // Test the clear screen and newline commands. // Also test that we can write to all 4 lines. printf(lcd_putc, "\fThis is the 1st line"); printf(lcd_putc, "\nNext is the 2nd line"); printf(lcd_putc, "\nThis is the 3rd line"); printf(lcd_putc, "\nFinally the 4th line"); delay_ms(3000);
// Test some additional characters. printf(lcd_putc, "\fABCDEFGHIJKLMNOPQRST"); printf(lcd_putc, "\nabcdefghijklmnopqrst"); printf(lcd_putc, "\n12345678901234567890"); printf(lcd_putc, "\n!@#$^&*(){}[]:;<>?/="); delay_ms(3000);
// Clear the LCD. printf(lcd_putc, "\f"); delay_ms(500);
// Test that lcd_gotoxy() works. Go to each of // the four corners and put a number in each one, // in a clockwise direction, starting with the upper // left corner. lcd_gotoxy(4, 2); printf(lcd_putc, "Put a number in"); lcd_gotoxy(4, 3); printf(lcd_putc, "each corner."); lcd_gotoxy(1, 1); printf(lcd_putc, "1"); lcd_gotoxy(20, 1); printf(lcd_putc, "2"); lcd_gotoxy(20, 4); printf(lcd_putc, "3"); lcd_gotoxy(1, 4); printf(lcd_putc, "4"); delay_ms(3000);
// Read the character that was written in each corner // of the LCD and display it. This tests the lcd_getc() // function. // The following test can only be done if we can read // from the LCD. If the RW pin is not used, then the // LCD is in write-only mode, and we can't do this test. // The #ifdef statement will prevent the code from // being compiled, in that case.
#ifdef USE_RW_PIN // Test if lcd_getc() can read // a byte from each corner. b1 = lcd_getc(1,1); b2 = lcd_getc(20,1); b3 = lcd_getc(20,4); b4 = lcd_getc(1,4); lcd_gotoxy(1, 1); printf(lcd_putc, "\fRead these bytes\n"); printf(lcd_putc, "from the 4 corners:\n\n"); printf(lcd_putc, " %c %c %c %c", b1, b2, b3, b4); delay_ms(3000); #endif
// Type some characters and backspace over them. printf(lcd_putc, "\fType characters and\n"); printf(lcd_putc, "backspace over them."); delay_ms(2000);
// Go to end of 2nd line. lcd_gotoxy(20, 2);
// Backspace over 2nd line. for(i = 0; i < 20; i++) { printf(lcd_putc," \b\b"); delay_ms(150); }
// Go to end of first line. lcd_gotoxy(20, 1);
// Backspace over first line. for(i = 0; i < 20; i++) { printf(lcd_putc," \b\b"); delay_ms(150); }
}
}
// Flex_LCD420.c
// These pins are for my Microchip PicDem2-Plus board, // which I used to test this driver. // An external 20x4 LCD is connected to these pins. // Change these pins to match your own board's connections.
#define LCD_DB4 PIN_D4 #define LCD_DB5 PIN_D5 #define LCD_DB6 PIN_D6 #define LCD_DB7 PIN_D7
#define LCD_RS PIN_E0 #define LCD_RW PIN_E1 #define LCD_E PIN_E2
/* // To prove that the driver can be used with random // pins, I also tested it with these pins: #define LCD_DB4 PIN_D4 #define LCD_DB5 PIN_B1 #define LCD_DB6 PIN_C5 #define LCD_DB7 PIN_B5
#define LCD_RS PIN_E2 #define LCD_RW PIN_B2 #define LCD_E PIN_D6 */
// If you want only a 6-pin interface to your LCD, then // connect the R/W pin on the LCD to ground, and comment // out the following line. Doing so will save one PIC // pin, but at the cost of losing the ability to read from // the LCD. It also makes the write time a little longer // because a static delay must be used, instead of polling // the LCD's busy bit. Normally a 6-pin interface is only // used if you are running out of PIC pins, and you need // to use as few as possible for the LCD. #define USE_RW_PIN 1
// These are the line addresses for most 4x20 LCDs. #define LCD_LINE_1_ADDRESS 0x00 #define LCD_LINE_2_ADDRESS 0x40 #define LCD_LINE_3_ADDRESS 0x14 #define LCD_LINE_4_ADDRESS 0x54
// These are the line addresses for LCD's which use // the Hitachi HD66712U controller chip. /* #define LCD_LINE_1_ADDRESS 0x00 #define LCD_LINE_2_ADDRESS 0x20 #define LCD_LINE_3_ADDRESS 0x40 #define LCD_LINE_4_ADDRESS 0x60 */
//========================================
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines(or more)
int8 lcd_line;
int8 const LCD_INIT_STRING[4] = { 0x20 | (lcd_type << 2), // Set mode: 4-bit, 2+ lines, 5x8 dots 0xc, // Display on 1, // Clear display 6 // Increment cursor };
//------------------------------------- void lcd_send_nibble(int8 nibble) { // Note: !! converts an integer expression // to a boolean (1 or 0). output_bit(LCD_DB4, !!(nibble & 1)); output_bit(LCD_DB5, !!(nibble & 2)); output_bit(LCD_DB6, !!(nibble & 4)); output_bit(LCD_DB7, !!(nibble & 8));
delay_cycles(1); output_high(LCD_E); delay_us(2); output_low(LCD_E); }
//----------------------------------- // This sub-routine is only called by lcd_read_byte(). // It's not a stand-alone routine. For example, the // R/W signal is set high by lcd_read_byte() before // this routine is called.
#ifdef USE_RW_PIN int8 lcd_read_nibble(void) { int8 retval; // Create bit variables so that we can easily set // individual bits in the retval variable. #bit retval_0 = retval.0 #bit retval_1 = retval.1 #bit retval_2 = retval.2 #bit retval_3 = retval.3
retval = 0; output_high(LCD_E); delay_us(1);
retval_0 = input(LCD_DB4); retval_1 = input(LCD_DB5); retval_2 = input(LCD_DB6); retval_3 = input(LCD_DB7); output_low(LCD_E); delay_us(1); return(retval); } #endif
//--------------------------------------- // Read a byte from the LCD and return it.
#ifdef USE_RW_PIN int8 lcd_read_byte(void) { int8 low; int8 high;
output_high(LCD_RW); delay_cycles(1);
high = lcd_read_nibble();
low = lcd_read_nibble();
return( (high<<4) | low); } #endif
//---------------------------------------- // Send a byte to the LCD. void lcd_send_byte(int8 address, int8 n) { output_low(LCD_RS);
#ifdef USE_RW_PIN while(bit_test(lcd_read_byte(),7)) ; #else delay_us(60); #endif
if(address) output_high(LCD_RS); else output_low(LCD_RS); delay_cycles(1);
#ifdef USE_RW_PIN output_low(LCD_RW); delay_cycles(1); #endif
output_low(LCD_E);
lcd_send_nibble(n >> 4); lcd_send_nibble(n & 0xf); } //----------------------------
void lcd_init(void) { int8 i;
lcd_line = 1;
output_low(LCD_RS);
#ifdef USE_RW_PIN output_low(LCD_RW); #endif
output_low(LCD_E);
// Some LCDs require 15 ms minimum delay after // power-up. Others require 30 ms. I'm going // to set it to 35 ms, so it should work with // all of them. delay_ms(35);
for(i=0 ;i < 3; i++) { lcd_send_nibble(0x03); delay_ms(5); }
lcd_send_nibble(0x02);
for(i=0; i < sizeof(LCD_INIT_STRING); i++) { lcd_send_byte(0, LCD_INIT_STRING[i]); // If the R/W signal is not used, then // the busy bit can't be polled. One of // the init commands takes longer than // the hard-coded delay of 50 us, so in // that case, lets just do a 5 ms delay // after all four of them. #ifndef USE_RW_PIN delay_ms(5); #endif }
}
//----------------------------
void lcd_gotoxy(int8 x, int8 y) { int8 address;
switch(y) { case 1: address = LCD_LINE_1_ADDRESS; break;
case 2: address = LCD_LINE_2_ADDRESS; break;
case 3: address = LCD_LINE_3_ADDRESS; break;
case 4: address = LCD_LINE_4_ADDRESS; break;
default: address = LCD_LINE_1_ADDRESS; break; }
address += x-1; lcd_send_byte(0, 0x80 | address); }
//----------------------------- void lcd_putc(char c) { switch(c) { case '\f': lcd_send_byte(0,1); lcd_line = 1; delay_ms(2); break; case '\n': lcd_gotoxy(1, ++lcd_line); break; case '\b': lcd_send_byte(0,0x10); break; default: lcd_send_byte(1,c); break; } }
//------------------------------ #ifdef USE_RW_PIN char lcd_getc(int8 x, int8 y) { char value;
lcd_gotoxy(x,y);
// Wait until busy flag is low. while(bit_test(lcd_read_byte(),7));
output_high(LCD_RS); value = lcd_read_byte(); output_low(LCD_RS);
return(value); } #endif
Title: Re: รบกวนขอวิธีการต่อจอ LCD 20x4 กับ PIC16F877 ด้วยครับ
Post by: gundam on September 21, 2009, 09:07:34 AM
ในเวปนี้ก็มีรายละเอียดเกี่ยวกับ LCD นะครับ การระบุบรรทัดลองดูที่ เซ็ทต่ำแหน่งใน DD-RAM (Set DD-RAM Address) http://www.thaimicrotron.com/Referrence/LCD/LCD-Module2.htm
Title: Re: รบกวนขอวิธีการต่อจอ LCD 20x4 กับ PIC16F877 ด้วยครับ
Post by: pakapong16 on September 21, 2009, 05:58:51 PM
ต่อทดสอบแล้วไม่แสดงอะไรเลย
ช่วยแนะนำด้วยครับ
ผมมีความรู้เรื่อง PIC ไม่มาก
รึว่าผมต่อวงจรผิด ขอคำแนะนำรูปการต่อวงจรจอด้วยครับ
Title: Re: รบกวนขอวิธีการต่อจอ LCD 20x4 กับ PIC16F877 ด้วยครับ
Post by: s_engine on September 22, 2009, 03:34:45 PM
(http://upload.siamza.com/file_upload/modify/220909/283345.jpg) (http://upload.siamza.com/showpic.php?id=283345)
ผม ซิมได้อยุ่นะ
Title: Re: รบกวนขอวิธีการต่อจอ LCD 20x4 กับ PIC16F877 ด้วยครับ
Post by: pakapong16 on September 22, 2009, 05:02:26 PM
ผมก้อต่อตามพี่แล้วครับ
ให้ out put ที่ port c
เพราะปกติผมต่อแบบนี้อ่ะครับ http://upload.siamza.com/showpic.php?id=283577
มันก้อไม่ออก
Title: Re: รบกวนขอวิธีการต่อจอ LCD 20x4 กับ PIC16F877 ด้วยครับ
Post by: s_engine on September 24, 2009, 07:48:57 PM
ต่อฮาร์ดแวร์ จริงใช่ไหมครับ หรือ ซิมเอา RD0 ต่อกับ RS RD1 ต่อกับ RW RD2 ต่อกับ E RD3 ไม่ใช้ RD4 ต่อกับ D4 RD5 ต่อกับ D5 RD6 ต่อกับ D6 RD7 ต่อกับ D7
ลองดูอีกทีนะ
ถ้าต่อ ฮาร์ดแวร์จริง ลองจ่ายไฟเลี้ยง ดูยัง แล้วปรับ VR ให้ มี สีตรงส่วนที่จะแสดงผล เข้ม ขึ้นมา 20x4 ผมไม่มีของจริง แต่16x2 เวลาจ่ายไฟเลี้ยง ปรับ VR บรรทัดแรกมันจะ ค่อยๆทึบ โดยบรรทัดที่2 ยังเหมือนเดิม 20x4 ก็ น่าจะเหมือนกัน
Title: Re: รบกวนขอวิธีการต่อจอ LCD 20x4 กับ PIC16F877 ด้วยครับ
Post by: pakapong16 on September 25, 2009, 02:49:48 PM
ต่อใช้งานจริงครับ
ต่อครบทุกอันแล้วครับ
มันขึ้นเส้นทึบบรรทัดที่ 1และ3 ไม่มีข้อมูลแสดงเลยครับ
Title: Re: รบกวนขอวิธีการต่อจอ LCD 20x4 กับ PIC16F877 ด้วยครับ
Post by: s_engine on September 26, 2009, 09:40:23 PM
แล้วการทำงานอย่างอื่นทำได้อยุ่ไหม เช่น เขียนโค้ดเพิ่มไปว่า กดสวิตช์ แล้วled ติด กดสวิตช์อีกตัว led ดับ โดยเพิ่มไปในโค้ดที่สั่งโชว์ LCD เพื่อดูว่า pic ยังทำงานอยุ่ไหม พวกคริสตั้นใช้ความถี่เท่าไหร่ R reset ต่อถูกต้องแล้วนะ
Title: Re: รบกวนขอวิธีการต่อจอ LCD 20x4 กับ PIC16F877 ด้วยครับ
Post by: pakapong16 on October 01, 2009, 02:37:36 AM
ผมใช้โค๊ดนี้ออก แต่ออกสองบรรทัด
#use delay (clock = 20000000)
struct lcd_pin_map { BOOLEAN rs; // on to an I/O port to gain PIN_D0 BOOLEAN enable; // access to the LCD pins. PIN_D1 BOOLEAN rw; // The bits are allocated from PIN_D2 BOOLEAN unused; // low order up. ENABLE will PIN_D3 int data : 4; // PIN_D4-7 } lcd;
#byte lcd = 8 //portd
#define set_tris_lcd(x) set_tris_d(x)
#define lcd_type 2 // 0=5x7 1 line, 1=5x10 1 line, 2=5x7 2 line #define lcd_line_two 0x40 // LCD RAM address for the second line
byte const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0x0c, 1, 6}; // Initial LCD
struct lcd_pin_map const LCD_WRITE = {0, 0}; struct lcd_pin_map const LCD_READ = {0, 15}; // 15 = 1111 // Setting the I/O port direction register.
void lcd_send_nibble( byte n ) { lcd.data = n; delay_cycles(1); lcd.enable = 1;
delay_us(2); lcd.enable = 0;
}
void lcd_send_byte( byte address, byte n) { lcd.rs = 0; delay_us(500); lcd.rs = address; delay_cycles(1);
lcd_send_nibble(n >> 4); lcd_send_nibble(n & 0x0f); }
void lcd_gotoxy( byte x, byte y) { byte address; if(y != 1) address = lcd_line_two; else address = 0; address += x-1; lcd_send_byte(0,0x80|address); }
void lcd_init() { byte i; set_tris_lcd(LCD_WRITE); set_tris_d(0B00000000); lcd.rs = 0;
delay_ms(15); for (i=1; i<=3; ++i) { lcd_send_nibble(3); delay_ms(5); } lcd_send_nibble(2); for (i=0; i<=3; ++i) lcd_send_byte(0,LCD_INIT_STRING); }
void lcd_putc( char c ) { switch (c) { case '\f' : lcd_send_byte(0, 1); delay_ms(2); break; case '\n' : lcd_gotoxy(1,2); break; case '\b' : lcd_send_byte(0,0x10); break; case '\p' : lcd_gotoxy(9,2); break; default : lcd_send_byte(1,c); break; } }
Title: Re: รบกวนขอวิธีการต่อจอ LCD 20x4 กับ PIC16F877 ด้วยครับ
Post by: s_engine on October 01, 2009, 11:49:41 PM
ลองใช้ // Test some additional characters. printf(lcd_putc, "\fABCDEFGHIJKLMNOPQRST"); printf(lcd_putc, "\nabcdefghijklmnopqrst"); printf(lcd_putc, "\n12345678901234567890"); printf(lcd_putc, "\n!@#$^&*(){}[]:;<>?/="); delay_ms(3000); ส่งดู มันจะโชว์ 4 บรรทัด ที่คุณเขียนมา มันเป็นไดร์เวอร์ ของ 16*2 จาก #define lcd_line_two 0x40 // LCD RAM address for the second line เลยแสดงได้แค่ 2 บรรทัด การแสดง 4 บรรทัด ต้องกำหนดแอดเดรส ให้กับแต่ละบรรทัดด้วย ลอง include lcd420 ของ ccs มาใช้ดู ต่อขาตามเขา
Title: Re: รบกวนขอวิธีการต่อจอ LCD 20x4 กับ PIC16F877 ด้วยครับ
Post by: s_engine on October 05, 2009, 09:14:41 AM
เอาไปลองดูนะครับ http://load1.uploadfile.biz/get.php?file=113i53i52i36date05102009am090012 (http://load1.uploadfile.biz/get.php?file=113i53i52i36date05102009am090012)
ไฟล์ที่อัพ มีทั้ง .c และ .hex ที่ใช้เบิร์นได้เลย และมี proteus v7.4 pack3 verเก่ากว่าจะเปิดไม่ได้ ไว้สำหรับ simulate ต่อขาตามนี้นะ แต่ถ้าอยากเปลี่ยนต่ำแหน่งขาที่ต่อ ก็ให้ไปแก้ใน Flex_LCD420.c ได้เลย
#define LCD_DB4 PIN_C4 #define LCD_DB5 PIN_C5 #define LCD_DB6 PIN_C6 #define LCD_DB7 PIN_C7
#define LCD_RS PIN_C0 #define LCD_RW PIN_C1 #define LCD_E PIN_C2
Title: Re: รบกวนขอวิธีการต่อจอ LCD 20x4 กับ PIC16F877 ด้วยครับ
Post by: pakapong16 on October 05, 2009, 11:20:18 AM
ขอบคุณมากครับ
จะลองเบิร์นดูครับ
Title: Re: รบกวนขอวิธีการต่อจอ LCD 20x4 กับ PIC16F877 ด้วยครับ
Post by: pakapong16 on October 12, 2009, 09:37:03 PM
พยายามแล้วครับ
แต่ก้อสุดจะท้อแร้วครับ
มันไม่ออกเหมือนเดิม
สงสัยต้องจะลองต่อไป เผื่อจะออก
แล้วถ้าดัดแปลงจากตัวนี้พอจะได้ไหมครับ
#use delay (clock = 20000000)
struct lcd_pin_map { BOOLEAN rs; // on to an I/O port to gain PIN_D0 BOOLEAN enable; // access to the LCD pins. PIN_D1 BOOLEAN rw; // The bits are allocated from PIN_D2 BOOLEAN unused; // low order up. ENABLE will PIN_D3 int data : 4; // PIN_D4-7 } lcd;
ต้องดัดแปลงส่วนไหนบ้างครับพี่
Title: Re: รบกวนขอวิธีการต่อจอ LCD 20x4 กับ PIC16F877 ด้วยครับ
Post by: s_engine on October 14, 2009, 01:53:48 PM
ยังไม่ได้อีกหรอ ลอง include lcd420.c ที่ ccs ให้มาเป็น driver แล้วเปิด ไฟล์ lcd420 มาดูว่าเขากด หนดขายังไง แล้วลองสั่งโชว์ แบบง่ายๆ ลองเอาโค้ดทั้งหมด มาแปะให้ดูหน่อย
|