Thông báo

Collapse
No announcement yet.

Giao tiếp với LCD

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Giao tiếp với LCD

    Giao tiếp với LCD là phần ứng dụng quan trọng trong lập trình với PIC



    Có 2 chế độ làm việc với LCD
    - Chế độ 8 bit
    - Chế độ 4 bit : ta thường làm cách này để tiết kiệm chân cho VĐK. Nhược điểm : tốc độ chậm hơn so với chế độ 8 bit.

    LCD có 3 đường điều khiển:

    Đường E cho phép hay không việc giao tiếp với LCD.
    Nếu E=1 cho phép, sau đó kiểm tra trạng thái chân RS và RW.
    Nếu E=0 cấm.
    E khởi tạo quá trình truyền dữ liệu từ VĐK tới LCD.

    Đường RS qui định dữ liệu/ lệnh được gửi tới LCD.
    RS=1 Dữ liệu (kí tự) đang được viết lên LCD
    RS=0 Lệnh đang được viết lên LCD

    Đường RW - Qui định hướng truyền dữ liệu giữa LCD và VĐK.
    Nếu RW=0 VĐK viết dữ liệu lên LCD.
    RW=1 VĐK đọc dữ liệu từ LCD.

    Để viết dữ liệu lên LCD cần thực hiện các bước theo trình tự như sau:

    1.Kéo dây R/W =0
    2.Đặt RS=0 hay RS=1 tùy mục đích gửi lệnh hay dữ liệu.
    3.Đặt dữ liệu vào bus dữ liệu (RB4-RB7) (Nếu là quá trình viết).
    4.Kéo E lên 1.
    5.Kéo E xuống 0.
    6.Đọc dữ liệu tại Bus dữ liệu (nếu là quá trình đọc).
    Việc đọc dữ liệu từ LCD thực hiện tương tự như trên (Trường hợp này ít dùng).

    Các kí tự được hiển thị trên LCD được lưu trong DDRAM (Display Data RAM).
    Địa chỉ của các kí tự


    Ta có thể định nghĩa các kí tự, các kí tự này được lưu trong CG RAM (Character
    Generated RAM). CGRAM 64 bytes. Mỗi kí tự 8 bytes--> ta định nghĩa được
    tối đa 8 kí tự.

    Việc đọc/viết kí tự lên LCD tốn khoảng 40 us đến 120us. Trong khoảng thời gian này LCD "bận" , VĐK bó tay!
    Do vậy trong chương trình ta cần thực hiện delay để LCD thực hiện công việc của mình.

    Khởi tạo làm việc với LCD theo chế độ 4 bit.
    1. Đợi 15ms sau khi cấp nguồn.
    2. Viết 0x03 vào LCD và đợi 5ms để hoàn thành việc viết lệnh.
    3. Viết 0x03 vào LCD và đợi 160us
    4. Viết 0x03 vào LCD và đợi 160us.

    5. Viết 0x02 vào LCD để chọn chế độ 4 bit.
    Viết set interface length
    Viết 0x010 để tắt hiển thị.
    Viết 0x001 để xóa màn hình.
    Đặt chế độ làm việc cho con trỏ(tùy bạn)

    Để viết kí tự lên LCD các bạn cần có driver cho LCD. Ghi file này lcd_lib.c
    [code:1]
    #define LCD_RS PIN_A1
    #define LCD_EN PIN_A0
    #define LCD_D4 PIN_B4
    #define LCD_D5 PIN_B5
    #define LCD_D6 PIN_B6
    #define LCD_D7 PIN_B7


    // misc display defines-
    #define Line_1 0x00
    #define Line_2 0x40
    #define Clear_Scr 0x01


    // prototype statements
    #separate void LCD_Init ( void );// ham khoi tao LCD
    #separate void LCD_SetPosition ( unsigned int cX );//Thiet lap vi tri con tro
    #separate void LCD_PutChar ( unsigned int cX );// Ham viet1kitu/1chuoi len LCD
    #separate void LCD_PutCmd ( unsigned int cX) ;// Ham gui lenh len LCD
    #separate void LCD_PulseEnable ( void );// Xung kich hoat
    #separate void LCD_SetData ( unsigned int cX );// Dat du lieu len chan Data

    // D/n Cong

    #use standard_io ( B )
    #use standard_io (A)


    //khoi tao LCD**********************************************
    #separate void LCD_Init ( void )
    {
    LCD_SetData ( 0x00 );
    delay_ms(200); /* wait enough time after Vdd rise >> 15ms */
    output_low ( LCD_RS );// che do gui lenh
    LCD_SetData ( 0x03 ); /* init with specific nibbles to start 4-bit mode */
    LCD_PulseEnable();
    LCD_PulseEnable();
    LCD_PulseEnable();
    LCD_SetData ( 0x02 ); /* set 4-bit interface */
    LCD_PulseEnable(); /* send dual nibbles hereafter, MSN first */
    LCD_PutCmd ( 0x2C ); /* function set (all lines, 5x7 characters) */
    LCD_PutCmd ( 0x0C ); /* display ON, cursor off, no blink */
    LCD_PutCmd ( 0x01 ); /* clear display */
    LCD_PutCmd ( 0x06 ); /* entry mode set, increment & scroll left */
    }

    #separate void LCD_SetPosition ( unsigned int cX )
    {
    /* this subroutine works specifically for 4-bit Port A */
    LCD_SetData ( swap ( cX ) | 0x08 );
    LCD_PulseEnable();
    LCD_SetData ( swap ( cX ) );
    LCD_PulseEnable();
    }

    #separate void LCD_PutChar ( unsigned int cX )
    {
    /* this subroutine works specifically for 4-bit Port A */
    output_high ( LCD_RS );
    LCD_PutCmd( cX );
    output_low ( LCD_RS );
    }

    #separate void LCD_PutCmd ( unsigned int cX )
    {
    /* this subroutine works specifically for 4-bit Port A */
    LCD_SetData ( swap ( cX ) ); /* send high nibble */
    LCD_PulseEnable();
    LCD_SetData ( swap ( cX ) ); /* send low nibble */
    LCD_PulseEnable();
    }

    #separate void LCD_PulseEnable ( void )
    {
    output_high ( LCD_EN );
    delay_us ( 3 ); // was 10
    output_low ( LCD_EN );
    delay_ms ( 3 ); // was 5
    }

    #separate void LCD_SetData ( unsigned int cX )
    {
    output_bit ( LCD_D4, cX & 0x01 );
    output_bit ( LCD_D5, cX & 0x02 );
    output_bit ( LCD_D6, cX & 0x04 );
    output_bit ( LCD_D7, cX & 0x08 );
    }

    [/code:1]

    Sơ đồ:

    [code:1]
    //************************************************** ***
    //CHUONG TRINH HIEN THI CHU LEN LCD
    //date:29/07/2005
    //typewriter:noisepic@gmail.com
    //status: Hien thi chu len LCD+OK
    //Mo ta:A1 noi voi RS
    // A0 noi voi Enable
    // B4,B5,B6,B7 noi voi D4,D5,D6,D7 tuong ung
    //************************************************** ****
    #include<16f84a.h>
    #use delay(clock=4000000)
    #fuses NOWDT,PUT,HS,NOPROTECT
    #include<lcd_lib.c>
    main()
    {
    lcd_init();
    while(1)
    {
    lcd_PutCmd(Clear_Scr);

    lcd_setposition(LINE_1+3);
    printf(lcd_putchar,"noisepic");

    lcd_SetPosition(LINE_2+1);
    printf(lcd_PutChar,"PICVIETNAM") ;

    }
    }
    //*************************************************
    [/code:1]

    Xung giao tiếp giữa LCD và PIC trong chế độ 4 bit


    Phần này noisepic không hiểu lắm!
    Learn more...

  • #2
    Các bạn xem phần bôi đậm. noisepic vẫn không hiểu tại sao viết 3 lần giá trị 0x03 vào LCD?
    Learn more...

    Comment


    • #3
      Chi minh voi

      Muon viet duoc may doan code nhu vay thi ta phai tham khao sach Lap trinh C nao vay huynh . Theo de duoc biet thi may Sach lap trinh chi day may cac can ban thoi . Tren mang cung co day source code nhung de van muon tu minh viet .

      Comment


      • #4
        Nguyên văn bởi noisepic
        Các bạn xem phần bôi đậm. noisepic vẫn không hiểu tại sao viết 3 lần giá trị 0x03 vào LCD?
        Ko hiểu bác noispic đọc datasheet kỹ chưa? nhưng đó là quy định của nhà sản xuất, thủ tục init() bắt buộc phải có những dòng lênh đó, mình phải làm đúng giản đồ xung, bạn download tài liệu về đọc lại. Đó là sự bắt buộc khi khi cài đặt.. Có vẻ như bạn hơi quá lạm dụng Code mẫu có sẵn mà ko đọc datasheet nên dễ gây ra trường hợp kiểu như vậy
        -------------------

        Comment


        • #5
          Vấn đề mà noisepic hỏi ở chỗ tại sao nó lại viết 3 lần cùng một giá trị 0x03 vào LCD ...nếu như chibang nói có lẽ nhà sản xuất bảo làm thế! nên mình cũng không cần hiểu nhiều lắm. Viết chương trình cứ theo nó là đuợc.
          Mình lạm dụng code thật! bắt đầu một ứng dụng mình chưa thể tự viết code được nên hay tìm code về đọc ! (trả lời luôn câu hỏi cho dungsidietquy). Điều này rất nguy hiểm...và mình cũng đang trogn quá trình luyện tập.

          Còn câu hỏi của dungsidietquy thì phải nhờ các cao thủ trả lời.
          Learn more...

          Comment


          • #6
            Re: Chi minh voi

            Nguyên văn bởi dungsidietquy
            Muon viet duoc may doan code nhu vay thi ta phai tham khao sach Lap trinh C nao vay huynh . Theo de duoc biet thi may Sach lap trinh chi day may cac can ban thoi . Tren mang cung co day source code nhung de van muon tu minh viet .
            Ngôn ngữ C mình học trên lớp là ANSI C. Về cú pháp và các câu lệnh điều khiển là hoàn toàn giống nhau. Chỉ khác nhau ở các thanh ghi mà thôi.
            Ví dụ: trong PC thì nó là AX, BX, CX, SI,...còn trong PIC là : OPTION, TRISA, TRISB, TRISC,... Máy tính hay vi điều khiển nó không hiểu nhưng cái đó là gì đâu mà chỉ biết là thanh ghi bao nhiêu bít và có địa chỉ xác định thôi.

            Vì vậy mà chỉ cần đọc datasheet là chúng ta có thể viết được những chương trình như vậy rồi. :o

            Comment


            • #7
              Các bác cho em hỏi với. Khi làm việc với chế độ 4 bít thì phải đưa dữ liệu ra bus 2 lần phải không? Bác noisepic đã làm mạch thật chưa? Em hỏi câu này vì em chưa làm mạch thật mà em dùng phần mềm proteus để thử. Đoạn code thì em copy từ code có sẵn giống bác noisepic nhưng không hiểu tại sao không chạy. Hix em mất mấy ngày với con LCD này rồi.

              Comment


              • #8
                To quangnv_bk:
                Mình làm mạch thật rồi! Chạy tốt bạn ah! (cắm trên test board)
                Với cả khi đưa dữ liệu theo chế độ 4 bit(Bạn xem hàm của nó) sẽ thấy nó gửi từng nhóm 4 bit (nible), cách này để tiết kiệm chân cho VDK.
                Mình post bài này với mục đích những ai dùng code đỡ phải mất công tìm.
                Hi vọng trả lời được câu hỏi của bạn.
                noisepic
                Learn more...

                Comment


                • #9
                  Re

                  Có bạn nào có tài liệu cụ thể về LCD không?

                  Comment


                  • #10
                    http://www.myke.com/lcd.htm

                    Trang này khá đầy đủ và chi tiết về LCD.
                    Learn more...

                    Comment


                    • #11
                      Các huynh đài tiện đây cho hỏi có cái lcd nào hiển thị đồ họa được không, tức là mình có thể điều khiển được từng điểm ảnh. Hoặc có cái lcd nào có thể hiển thị được tiếng việt có dấu ko? xin chỉ dùm cho đệ tài liệu và chỗ mua. Đệ là người mới đến !

                      Comment


                      • #12
                        Nguyên văn bởi noisepic
                        Vấn đề mà noisepic hỏi ở chỗ tại sao nó lại viết 3 lần cùng một giá trị 0x03 vào LCD ...nếu như chibang nói có lẽ nhà sản xuất bảo làm thế! nên mình cũng không cần hiểu nhiều lắm. Viết chương trình cứ theo nó là đuợc.
                        Mình lạm dụng code thật! bắt đầu một ứng dụng mình chưa thể tự viết code được nên hay tìm code về đọc ! (trả lời luôn câu hỏi cho dungsidietquy). Điều này rất nguy hiểm...và mình cũng đang trogn quá trình luyện tập.

                        Còn câu hỏi của dungsidietquy thì phải nhờ các cao thủ trả lời.
                        Ê noipic ơi...tìm code như nào vậy nhỉ??? ví dụ tìm code sử dụng HTPIC dùng cho LCD hay DSPIC thì tìm ở đâu vậy??? cái khoản nét niéc này tui giốt quá ông a`...tôi đồng ý với noisepic là nên xem opcode...không thì viết lần đâu biết đâu mà lần hihi...
                        sở thích: Ngắm gái
                        Em xinh thế , em đi @

                        Comment


                        • #13
                          printf()

                          hi all,
                          thấy anh em hứng thú PIC quá,mình nhảy vô 1 chút.Chắc vấn đề này nhiều cao thủ biết rồi nhưng tôi nghĩ nó sẽ giúp cho nhiều bạn mới học

                          Giả sử mình muốn sử dụng hàm printf() của C đề hiên thị lên LCD thì trong hàm putchar() (printf() và putchar() là các hàm chuẩn trong stdio.h)
                          mình sẽ gọi hàm hiển thi ra 1 kí tự lên LCD tương ứng ,ví dụ lcdwritechar() .Vì hàm printf() nó sẽ tham chiếu tới hàm putchar()

                          Đôi khi,tùy compiler mà ko phải hàm printf() nó sẽ tham chiếu tới hàm putchar().Ví dụ Thằng C30 ,hàm printf() nó lại tham chiếu tới hàm write() ,do đó trong hàm write() mình sẽ gọi lcdwritechar().
                          Tương tự các bạn có thể áp dụng hàm printf() để xuất ra cổng nối tiếp,LED,...tùy theo mình viết hàm putchar()(hay write()) cho mục đích tương ứng.Tuy nhiên khi sử dụng hàm printf() bộ nhớ chương trình tốn thêm nhiều đó,đặc biệt khi in ra cac số floating point
                          Các bạn thử test coi.
                          Hy vọng có nhiều cao thủ giải thích tường tận hơn những điều mình nói.Mình không có khả năng sư phạm để làm cho người ta hiểu.
                          Hope this helps!
                          Last edited by anthrax; 29-09-2005, 23:10.

                          Comment


                          • #14
                            Vì sao lại thế

                            Tôi đã chép đoạn Code trên vào 2 file :

                            //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxx
                            //File TestLCD.c

                            #include <16f84a.h>
                            #use delay(clock=4000000)
                            #fuses NOWDT,PUT,HS,NOPROTECT
                            #include <lcd_lib.c>
                            main()
                            {
                            lcd_init();
                            while(1)
                            {
                            lcd_PutCmd(Clear_Scr);

                            lcd_setposition(LINE_1+3);
                            printf(lcd_putchar,&quot;noisepic&quot;

                            lcd_SetPosition(LINE_2+1);
                            printf(lcd_PutChar,&quot;PICVIETNAM&quot;

                            }
                            }



                            //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxx
                            //File lcd_lib.c

                            #define LCD_RS PIN_A1
                            #define LCD_EN PIN_A0
                            #define LCD_D4 PIN_B4
                            #define LCD_D5 PIN_B5
                            #define LCD_D6 PIN_B6
                            #define LCD_D7 PIN_B7


                            // misc display defines-
                            #define Line_1 0x00
                            #define Line_2 0x40
                            #define Clear_Scr 0x01


                            // prototype statements
                            #separate void LCD_Init ( void );// ham khoi tao LCD
                            #separate void LCD_SetPosition ( unsigned int cX );//Thiet lap vi tri con tro
                            #separate void LCD_PutChar ( unsigned int cX );// Ham viet1kitu/1chuoi len LCD
                            #separate void LCD_PutCmd ( unsigned int cX) ;// Ham gui lenh len LCD
                            #separate void LCD_PulseEnable ( void );// Xung kich hoat
                            #separate void LCD_SetData ( unsigned int cX );// Dat du lieu len chan Data

                            // D/n Cong

                            #use standard_io ( B )
                            #use standard_io (A)


                            //khoi tao LCD**********************************************
                            #separate void LCD_Init ( void )
                            {
                            LCD_SetData ( 0x00 );
                            delay_ms(200); /* wait enough time after Vdd rise >> 15ms */
                            output_low ( LCD_RS );// che do gui lenh
                            LCD_SetData ( 0x03 ); /* init with specific nibbles to start 4-bit mode */
                            LCD_PulseEnable();
                            LCD_PulseEnable();
                            LCD_PulseEnable();
                            LCD_SetData ( 0x02 ); /* set 4-bit interface */
                            LCD_PulseEnable(); /* send dual nibbles hereafter, MSN first */
                            LCD_PutCmd ( 0x2C ); /* function set (all lines, 5x7 characters) */
                            LCD_PutCmd ( 0x0C ); /* display ON, cursor off, no blink */
                            LCD_PutCmd ( 0x01 ); /* clear display */
                            LCD_PutCmd ( 0x06 ); /* entry mode set, increment &amp; scroll left */
                            }

                            #separate void LCD_SetPosition ( unsigned int cX )
                            {
                            /* this subroutine works specifically for 4-bit Port A */
                            LCD_SetData ( swap ( cX ) | 0x08 );
                            LCD_PulseEnable();
                            LCD_SetData ( swap ( cX ) );
                            LCD_PulseEnable();
                            }

                            #separate void LCD_PutChar ( unsigned int cX )
                            {
                            /* this subroutine works specifically for 4-bit Port A */
                            output_high ( LCD_RS );
                            LCD_PutCmd( cX );
                            output_low ( LCD_RS );
                            }

                            #separate void LCD_PutCmd ( unsigned int cX )
                            {
                            /* this subroutine works specifically for 4-bit Port A */
                            LCD_SetData ( swap ( cX ) ); /* send high nibble */
                            LCD_PulseEnable();
                            LCD_SetData ( swap ( cX ) ); /* send low nibble */
                            LCD_PulseEnable();
                            }

                            #separate void LCD_PulseEnable ( void )
                            {
                            output_high ( LCD_EN );
                            delay_us ( 3 ); // was 10
                            output_low ( LCD_EN );
                            delay_ms ( 3 ); // was 5
                            }

                            #separate void LCD_SetData ( unsigned int cX )
                            {
                            output_bit ( LCD_D4, cX &amp; 0x01 );
                            output_bit ( LCD_D5, cX &amp; 0x02 );
                            output_bit ( LCD_D6, cX &amp; 0x04 );
                            output_bit ( LCD_D7, cX &amp; 0x08 );
                            }

                            //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxx


                            Tôi dùng CCS 3.249 , máy báo lỗi "Undefine Indentifier amp " ở ngay dòng gần cuối cùng : "output_bit ( LCD_D4, cX &amp; 0x01 ); ",
                            các bác có giải thích được "amp" là cái gì và nên khai báo nó là gì không vậy ?

                            Comment


                            • #15
                              Để tìm LCD bạn vào
                              www.minhhaco.com

                              lệnh ghi 3 lần giá trị 0x03 là để RESET LCD đó. RESET mềm.
                              Nhà sản xuất chuyên nghiệp các sản phẩm OEM cho gia dụng và công nghiệp.

                              Biến tần
                              Máy giặt
                              Lò vi sóng
                              Bếp từ.
                              Tủ lạnh.
                              Điều hòa

                              Comment

                              Về tác giả

                              Collapse

                              noisepic Tìm hiểu thêm về noisepic

                              Bài viết mới nhất

                              Collapse

                              Đang tải...
                              X