Thông báo

Collapse
No announcement yet.

Lập trình hiển thị LCD bằng Assembler ( tutorial)

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

  • Lập trình hiển thị LCD bằng Assembler ( tutorial)

    Thời gian qua em tìm hiểu lập trình LCD bằng Assembler và đã thu được một số kết quả khả quan cho nên em muốn post lên cho mọi nguời xem

    Với nhưng ai chưa lập trình LCD bao giờ có thể coi đây là một bài Tutorial cũng đuợc, còn đối với những người đã có kinh nghiệm làm về LCD rồi thì có thể góp ý và chỉ ra cho em những thiếu sót trong bài viết và chuơng trình

    Tất cả kiến thức về LCD của em là từ hai bài viết ở( viết rất cơ bản về LCD)

    http://www.8052.com/tutlcd.phtml
    http://www.8052.com/tutlcd2.phtml

    Về code chương trình em lấy ở trang wed trên và đã phát triển nó lên từng module một và ở topic này muốn post lên các module

    Trước khi post lên em xin muốn nói em chỉ là sinh viên chưa được tiếp xúc về thực tế, những kinh nghiệm của em là toàn trên giấy vở, va các bài viết trên diễn đàn cho nên kiến thức còn rất hạn chế, nên em ko dám khoe khoang gì cả mà chỉ mong nó có ích gì đó cho các bạn mới học vdk va cũng lập trình Assembler như em
    Dia chi cho cac Fan muon hoc Pic

  • #2
    những kiến thức chung nhất về LCD

    Ở bài viết này tôi xin nói qua về những kiến thức chung nhất về LCD

    Về phân loại: LCD có nhiều loại :
    8 character *1 line
    16 character *1 line (2 line hoặc 4 line)
    20 character * .....
    Trong bài viết này tôi xin đề cập đến loại 16*2 là một loại khá thông dụng
    Cũng xin đề cập đến giá cả luôn: 100k ( mua ở Hàng Trống) bác nào biết chỗ nào bán rẻ hơn thì cho anh em biết

    Về cấu tạo: LCD có 14 chân + 2 chan A,K ( tôi cũng chưa dùng chân này bao giờ và cũng chưa biết nó có tác dụng gì cả)

    Trước khi đề cập đến chi tiết từng chân một tôi muốn các bạn biết đến con IC 44780 mọi biến điều khiển hay dữ liệu từ VDK đều phải thông qua con IC nay. Con IC này có tác dụng giải mã để hiển thị dự liệu ( là các ký tự) hay thực thi các biến điều khiển như : di chuyển con trỏ hay xoá màn hinh v.v.v........
    data sheet của nó các bạn có thể tra tại đây
    http://www.datasheetcatalog.com/data...HD44780U.shtml

    LCD có cả thảy là 14 chân: 8 chân dữ liệu D0-> D7
    3 chân điều khiển E, RS,R/W
    3 chân nguồn Vss,Vdd,Vo

    Chân E (enable) : chân này cho IC 44780 biết là vdk đang liên lạc với nó, mức tich cực là mức 1 Chân này dùng để điều khiển trạng thái đường truyền dữ liệu

    Chân RS : báo cho LCD biết bước sắp tới là hiển thị dữ liệu hay thực thi các lệnh điều khiển( mức 0: lệnh , mức 1 : hiển thị dữ liệu)

    Chân R/W : có tác dụng báo cho LCD biết là VDK muốn đọc hay ghi( 1: read, 0: write)
    Chắc các bạn sẽ thắc mắc là LCD dùng để ghi dữ liệu, tại sao lại cần đến đọc nữa. Đọc dữ liệu cần thiết vì khi đọc dữ liệu từ LCD thì VDK mới biết lúc nào LCD thực thi xong lênh mà nó gửi truớc đó để còn thực thi lệnh tiếp theo

    Chân Vss, Vdd là chân nguồn ( Vss nối đất)

    Còn chân Vo là điều chỉnh độ tưông phản , tức là độ sáng của LCD, Nếu các bạn mới làm quen đến LCD như tôi thì hãy nối nó xuống đất ( Còn để điều chỉnh độ tương phản thì nối chân này với biến trở 10k, một đầu nối dất một đầu nối với dương nguôn)

    Đến đây chúng ta đã nắm được phần nào các chân của LCD rồi đó.
    Đến bài tiếp tôi sẽ giới thiệu cách gửi dữ liệu và thực thi lệnh từ VDK
    Attached Files
    Dia chi cho cac Fan muon hoc Pic

    Comment


    • #3
      Cách gửi dữ liệu và thực thi lênh từ VDK

      Cách gửi dữ liệu và thực thi lênh từ VDK

      Để gửi dữ liệu và thực thi lênh từ VDK có hai cách Dùng 8 chân D0=>D7 cách thứ hai là chỉ dung 4 chan D7,D6,D5,D4
      Như vậy có nghĩa là với cách thứ nhât các bạn cần 8 + 3( chân điều khiển E,RS,R/W)=11 chân. Cach này có ưu điểm là dễ lập trình hơn, nhưng tốn nhiều chân

      Cách thứ hai Chỉ dung 4+3 = 7 chân
      Cách này có ưu điểm là tốn ít chân hơn, nhưng lập trình phức tạp hơn và tốn nhiều dòng lệnh hơn

      Với cách thứ nhất các bạn có thể tham khảo ở tài liệu « Cấu trúc và lập trinh họ VDK 8051 » của tác giả Nguyễn Tăng Cương hay tại
      http://www.8052.com/tutlcd.phtml

      Còn trong bài viết này tôi chi đề cập đến cách thứ hai tức là chỉ dùng 4 chân D7=>D4
      Trước khi đi vào chi tiết tôi muốn đề cập đến cách nối mạch
      Chân D7,D6,D5,D4 nối với các chân P1.7, P1.6, P1.5, P1.4 tương ứng
      Chân EN nối với P3.7
      Chân RS nối với P3.6
      Chân R/W P3.5
      Chân Vdd nối dương nguồn
      Chân Vss, Vo nối xuống đất
      (
      DB4 EQU P1.4
      DB5 EQU P1.5
      DB6 EQU P1.6
      DB7 EQU P1.7
      EN EQU P3.7
      RS EQU P3.6
      RW EQU P3.5
      DATA1 EQU P1
      ; đặt tên các chân
      )
      Cách gửi dữ liệu và thực thi lệnh tới LCD dung 4 chân
      Cung như với lập trình cho 8051,bước đầu tiên chúng ta phải thiết lập trạng thái ban đầu cho LCD tức là phải báo cho nó là ta dang dùng chế độ 4 chân , dot 8*5...... rồi sau đó mới gủi dữ liệu hiển thị hay lệnh điều khiển lên lcd.

      Trước khi đề cập đến cách thiết lập trạng thái ban đầu cho LCD tôi muốn đề cập đến cách Read và Write lên LCD. Do chúng ta chỉ dùng 4 chân dữ liệu cho nên để Read, Write từng byte một ( 8bit) cho nên chúng ta phải nhận hay gửi hai lần: lần thứ nhất là 4bit high lần tiếp theo là 4bit low

      Luu ý để phân cách giữa các lần gửi hay nhận ta phải
      Setb EN
      Clr EN ; Gửi một xung cao xuống thấp ở chân EN
      Hai câu lệnh này để cho 44780 phân biệt được hai lần gửi khác nhau


      1).Read
      Trước khi đọc dữ liệu phải Setb RW
      Cách đọc dữ liệu các bạn có thể xem đoạn Code sau
      ;===============================================
      READ_2_NIBBLES:
      ORL DATA1,#0F0H ;Be sure to release datalines (set outputlatches
      ;to '1') so we can read the LCD
      SETB EN
      MOV A,DATA1 ;Read first part of the return value (high nibble)
      CLR EN
      ANL A,#0F0h ;Only high nibble is usable
      PUSH ACC
      SETB EN
      MOV A,DATA1 ;Read second part of the return value (lownibble)
      CLR EN
      ANL A,#0F0h ;Only high nibble is usable
      SWAP A ;Last received is actually low nibble, so put it in place
      MOV R7,A
      POP ACC
      ORL A,R7 ;And combine it with low nibble
      RET
      ;===============================================


      2).Write
      Trước khi viết dữ liệu phải Clear RW
      Cách viết dữ liệu xem đoạn code
      ;===============================================
      WRITE_2_NIBBLES:
      PUSH ACC ;Save A for low nibble
      ORL DATA1,#0F0h ;Bits 4..7 <- 1
      ORL A,#0Fh ;Don't affect bits 0-3
      ANL DATA1,A ;High nibble to display
      SETB EN
      CLR EN
      POP ACC ;Prepare to send
      SWAP A ;...second nibble
      ORL DATA1,#0F0h ; Bits 4...7 <- 1
      ORL A,#0Fh ; Don't affect bits 0...3
      ANL DATA1,A ;Low nibble to display
      SETB EN
      CLR EN
      RET
      ;===============================================

      Lưu ý trong hai Function trên ko dùng gì đến Setb, hay Clear R/W , ta chỉ dùng hai câu lệnh này trước khi gọi hàm
      EXP:
      CLR RW
      LCALL WRITE_2_NIBBLES

      3).WAIT_LCD
      Như tôi đã nói ở trên khi gửi một byte dư liêu đến LCD , trước khi gửi một byte tiếp theo ta phải kiểm tra xem LCD đà xử lý xong byte trước đó chưa, nếu ko sẽ dẫn đến tình trạng mất dữ liệu do đó việc kiểm tra là rất cần thiết
      Để kiểm tra co hai cách : Cách thứ nhất là trễ một khoảng thời gian nào đó giữa hai lần gửi( cách này đơn gian nhưng ko tối ưu)
      Cách thứ hai là kiểm tra bit BD7 của LCD nếu BD7=0 có nghĩa là LCD đang rỗi và nó sẵn sàng cho lần nhận ký tự tiếp theo:\
      Đây là đoạn Code của WAIT_LCD
      ;===============================================
      WAIT_LCD:
      CLR RS ;It's a command
      SETB RW ;It's a read command
      LCALL READ_2_NIBBLES ;Take two nibbles from LCD in A
      ORL A,#01111111B
      CJNE A,#01111111B,WAIT_LCD

      CLR RW ;Turn off RW for future commands
      RET
      ;===============================================


      4).CLREAR_LCD:
      Như tôi đã nói dữ liệu gửi tới HD44780 có hai dạng: dữ liệu hiển thị , và dữ liệu điều khiển
      Dữ liệu hiển thị VD: 1,2,3,4,5,6.......
      A,B,C,D,.......
      a,b,c,d,e,........
      !,^,&,*,...........
      Ta chỉ cần gửi LCD mã ASCII tương ưng với ký tự trên(vd: 1(31h) 2(32h) A(41h) a(61h) sẽ hiên thi các ký tự mong muốn

      Còn dữ liệu điều khiển, được nhà sản xuất quy ước
      Trong đó
      00000001b (01h) là xoá màn hình
      0000001xb là chuyển con trỏ về đầu màn hình
      .........................
      (
      Trong thời gian tới tôi sẽ sớm cung cấp cho các bạn bảng lệnh điều khiển của 44780 ( các bạn có thể tra trang 25 datasheet để biết thêm chi tiết)

      Như vậy có nghĩa là để xoá màn hình các bạn cần gửi mã lệnh 01h đến LCD

      Để gửi mã lệnh tới LCD ta phải Clr RS ; 1: du lieu, 0 : ma lenh
      Như vậy để xoá màn hinh LCD ta có đoạn Function
      ;===============================================
      CLEAR_LCD:
      CLR RS
      MOV A,#01h
      LCALL WRITE_2_NIBBLES ;Write A as two separate nibbles to LCD
      LCALL WAIT_LCD
      RET
      ;===============================================


      5.)WRITE_TEXT
      Để gửi dữ liệu hiển thị ta phải SETB RS
      sau đây là Function để gửi một ký tự hiển thị lên LCD
      ;===============================================
      WRITE_TEXT:
      SETB RS
      LCALL WRITE_2_NIBBLES
      LCALL WAIT_LCD
      RET
      ;===============================================


      6).INIT_LCD
      Như tôi đã nói ban đầu trước khi làm việc với LCD chúng ta phải khởi tạo ban đầu cho nó

      Các bước khởi tạo giá trị ban đầu cho LCD (có 5 bước)
      +)Wait 100ms ( thời gian cấp nguồn cho LCD - the internal reset circuit))
      +)Gừi mã lệnh 28h để thông báo cho LCD biết dùng 4 chân
      +)Gửi tiếp mã lệnh 28h để khởi tạo ban đầu cho LCD chế độ dùng 4bit, 2 line, dot 5*8 (luư ý sau quá trình này LCD sẽ ko thay đổi chế độ này nữa)
      +)Gửi mã lệnh 0EH để bật chế độ con trỏ (ko dùng nhấp nháy, nếu bạn muốn con trỏ nhấp nháy như trong chế độ Word, thì thay băng gửi mã lệnh 0FH)đây là mã lệnh Display on/off control
      +)Gửi mã lệnh 06h đây là mã lệnh Entry mode set thiết lập chế độ dịch chuyển con trỏ

      (Ở hàm init này tôi bỏ qua bước1)
      ;===============================================
      INIT_LCD:
      CLR RS
      CLR RW
      CLR EN
      SETB EN
      MOV DATA1,#28h
      CLR EN
      LCALL WAIT_LCD
      MOV A,#28h
      LCALL WRITE_2_NIBBLES ;Write A as two separate nibbles to LCD
      LCALL WAIT_LCD
      MOV A,#0Eh
      LCALL WRITE_2_NIBBLES
      LCALL WAIT_LCD
      MOV A,#06h
      LCALL WRITE_2_NIBBLES
      LCALL WAIT_LCD
      RET
      ;===============================================




      Và đến đây với 6 Function ở trên đó là :
      READ_2_NIBBLES
      WRITE_2_NIBBLES
      WAIT_LCD
      CLEAR_LCD
      INIT_LCD
      WRITE_TEXT

      Chúng ta đã có những công cụ cơ bạn nhất để viết lên màn hình LCD\
      Sau đây là một VD đơn giản: viết lên dòng chữ : HELLO WORLD
      VD1:
      ;=============================================
      main:
      LCALL INIT_LCD
      LCALL CLEAR_LCD
      MOV A,#'H'
      LCALL WRITE_TEXT
      MOV A,#'E'
      LCALL WRITE_TEXT
      MOV A,#'L'
      LCALL WRITE_TEXT
      MOV A,#'L'
      LCALL WRITE_TEXT
      MOV A,#'O'
      LCALL WRITE_TEXT
      MOV A,#' '
      LCALL WRITE_TEXT
      MOV A,#'W'
      LCALL WRITE_TEXT
      MOV A,#'O'
      LCALL WRITE_TEXT
      MOV A,#'R'
      LCALL WRITE_TEXT
      MOV A,#'L'
      LCALL WRITE_TEXT
      MOV A,#'D'
      LCALL WRITE_TEXT
      ljmp $
      ;==============================================

      Tất cả 6 function và đoạn Code trên đều từ trang wed: http://www.8052.com/tutlcd2.phtml
      Các bạn coi tôi dịch ra cũng được,
      Ở bài viết tiếp theo tôi sẽ đề cập đến phần mở rộng trong cach hiển thị LCD
      Dia chi cho cac Fan muon hoc Pic

      Comment


      • #4
        Giới thiệu các Function mở rộng

        Giới thiệu các Function mở rộng

        Function1: GOTOLINE1 & GOTOLINE2
        VD ở bài trước cho ta hiển thị dòng chữ : HELLO WORLD bắt đầu từ trái qua phải và ở dòng đầu tiên vây bây giờ tôi muốn hiển thị chữ trên ở vị trí khác làm thế nào vd HELLO WORLD bắt đầu từ vitri thứ 5 ở dòng hai thì phải làm thế nào??????????

        Làm điều đó rất đơn giản,

        LCD dùng trong Topic này là loại 16*2 16 nghĩa là 16 character trên một dòng, mỗi character trên một dòng có một toạ độ khác nhau nghĩa là bạn muốn ký tự hiển thị ở đâu thì nhảy tới vị trí đó
        Sau đây là các toạ độ:
        ; ........ . 0 1 2 3 4 5 6 .................15
        ; line1: 80 81 82 83 84 85 86 ..... 8F
        ; line2: C0 C1 C2 C3 C4 C5 C6 ... CF
        Các mã 80,81....C0,C1 là các biến điều khiển khi chúng ta gửi một biến điều khiển đến LCD thì con trỏ của LCD sẽ nhảy tới vị trí đó tựa như câu lênh gotoxy trong TurboC hay Pascal vậy VD: tôi gửi 83H tới LCD con trỏ sẽ dich vị trí thư 4 ở dòng đầu tiên, gửi CF thì con trỏ dịch chuyển tới vị trí 16 ở dong thứ hai

        Dựa vào các tính chất trên tôi đưa ra hai Function:
        GOTOLINE1:
        PHP Code:
        ;======================================================================
        GOTOLINE1:                                                      ;dung cho dong dau tien
          CLR   RS
          ADD   A
        ,#080H
          
        LCALL WRITE_2_NIBBLES
          LCALL WAIT_LCD
         RET 

        GOTOLINE2:

        PHP Code:
        GOTOLINE2:                                                 dung cho dong thu hai
          CLR   RS
          ADD   A
        ,#0C0H
          
        LCALL WRITE_2_NIBBLES
          LCALL WAIT_LCD
         RET
        ;======================================================================= 
        Useage:
        bạn mốn di chuyển con trỏ tớivi trí thứ 5 (vị tri thứ 4 tinh cả diểm 0)ở dòng đầu tiên :
        mov A,#4
        lcall gotoline1


        Function2: Sử dung DB 'HELLO WORLD' để hiển thị dữ liệu - Kỹ thuật Bảng
        Vi dụ 1 ở bài trước cho ta thấy để gửi một chuỗi ký tự 'HELLO WORLD' rất vất vả bây giờ tôi sẽ trình bầy cho các bạn cách dùng Kỹ thuật bảng để hiển thị dữ liêu
        lưu ý đến câu lệnh : movc A,@A+DPTR
        Đây là đoạn code mẫu:
        PHP Code:
        ;=======================================================================
        VD2:
        main:
          
        LCALL INIT_LCD
          LCALL CLEAR_LCD
          MOV   A
        ,#0    
          
        ACALL GOTOLINE2            ;hien chu o dong 2 dau tien
          MOV   DPTR
        ,#MYDATA
          
        MOV   R2,#0                         ; R2 dung de dinh vi con tro
          
        MOV   R3,#11;               ; bien R3 xac dinh so lan lap 
         
        JUMP_MAIN:                  ;HIEN CHU
          MOV   A
        ,R2
          MOVC  A
        ,@A+DPTR
          LCALL WRITE_TEXT
          INC   R2                                   
        Tang bien  R2 de tro den ky tu tiep theo
          DJNZ  R3
        ,JUMP_MAIN

        again
        sjmp again            vong lap vo han ket thuc chuong trinh
        mydata 
        :
          
        DB "Hello world"
        END
        ;======================================================================= 
        Function3: define_data_R3
        Hàm này là hàm nâng cấp cho Function2

        Các bạn có để ý đến vai trò Của R3 ở ví dụ trên ko, R3=11 chinh là độ dài của chuỗi 'Hello world''
        biến R3 ở đây xác định số lần lặp và tăng biến R2 lên, ở VD trên R2 sẽ tăng từ 0=>10, ứng với mỗi lần tăng là một lần xuất một ký tứ. Như vây giá trị R3 ở đây đóng vai trò rất quan trọng. Ở VD trên tôi đếm số ký tự rối áp đặt cho nó. Nhưng với nhưng ký tự dài và thay đổi thì phải làm sao
        Đó chình là nguyên nhân của sự ra đời hàm DEFINE_DATA_R3.

        Bạn nào từng lập trình C chắc các bạn biết để xác định cuối một chuôi String có ký tự '\0' , họ thêm vào ký tự này là có ly do của nó . Trên cơ sở đó tôi cho thêm một biến sau chuỗi cần hiển thị có giá trị là : '01'H (ko hiểu sao tôi lại chọn giá trị nầy các bạn có thể thay đổi cũng được )

        mydata:
        DB ''HELLO WORLD''
        DB 01h

        Như vậy hàm DEFINE_DATA_R3 co tác dụng đếm chuỗi này đến khi gặp ký tự 01h thì thôi như vậy là ta đã xác định được độ dài chuỗi rồi đó
        define_data_R3:
        PHP Code:
        ;=======================================================================
         
        define_data_R3:
          
        MOV   R3,#0
         
        AGAIN_DEFINE_DATA_R3:
          
        MOV   A,R3
          MOVC  A
        ,@A+DPTR
          INC   R3
          CJNE  A
        ,#01,AGAIN_DEFINE_DATA_R3
          
        DEC   R3
          RET
          
        ;====================================================================== 
        Useage:
        mov dptr,#mydata ; tro dptr vào vị trí luu dữ liệu
        LcalL define_data_R3


        Return: giá trị sau lcalL cho độ dài của chuỗi mydata được lưu trong R3
        Như vậy vidu 2 cần sửa thành:
        VD3
        PHP Code:
        ;=======================================================================
        main:
          
        LCALL INIT_LCD
          LCALL CLEAR_LCD
          MOV   A
        ,#0    
          
        ACALL GOTOLINE2            ;hien chu o dong 2 dau tien
          MOV   DPTR
        ,#MYDATA
          
        LCALL DEFINE_DATA_R3Xác định độ dài chuỗi
          MOV   R2
        ,#0                         ; R2 dung de dinh vi con tro
           
        JUMP_MAIN:                  ;HIEN CHU
          MOV   A
        ,R2
          MOVC  A
        ,@A+DPTR
          LCALL WRITE_TEXT
          INC   R2                                   
        Tang bien  R2 de tro den ky tu tiep theo
          DJNZ  R3
        ,JUMP_MAIN
        again
        sjmp again            vong lap vo han ket thuc chuong trinh
        mydata 
        :
          
        DB "Hello world"                   thay doi chuoi bat ky de hien thi
          DB 01h
        END
        ;======================================================================= 
        Với Function trên ta có thể xuất bất cứ một dữ liệu nào tuỳ thích
        Last edited by mafd_47; 22-11-2005, 19:56.
        Dia chi cho cac Fan muon hoc Pic

        Comment


        • #5
          Phần mở rộng về LCD và các vấn đề liên quan (tiếp)

          Phần mở rộng về LCD và các vấn đề liên quan (tiếp)
          Function4 write_bcd_8
          LCD dùng để hiển thị các dữ liệu trong các vidụ trên chúng ta đều hiển thịdạng chuỗicó sẵn, giả sử có một giá trị lưu trong r4 là 35 chẳng hạn và ta muốn hiển thị nó ra ngoài LCD thì phải làm như thế nào. Ý tưởng đó cho tôi sự ra đời của hàm write_bcd_8

          R4 là thanh ghi 8 bit giá trị max của nó là 255, tức là giá trị max của nó là số có 3 chữ số, ở hàm write_bcd_8 có sử dụng phép chia div AB thực hiện 2 phep chia ứng với B=100,10, lấy kêt qua và phần dư gán vào 3 giá trị R3,R2,R1( bưoc 1), rồi sau đó chuyển giá trị trong R3,R2,R1 sang mã ASCII ( bươc2);

          write_bcd_8:
          PHP Code:
          ;===============================================
          write_bcd_8:
           
          STEP1:   
             
          MOV   B,#100
             
          DIV   AB                  Execute A to 100 to get firt value
             MOV   R3
          ,A                add Quotient of division to r3firt value
             
          MOV   A,B                 add value B (remainderto A to execute next division
             MOV   B
          ,#10
             
          DIV   AB
             MOV   R2
          ,A                add Quotient of division to r2second value)
             
          MOV   A,B
             MOV   R1
          ,A                add Remainder to R1third value)
           
          Step2:                      ; transfer value of r3,r2,r1 to ASCII
             MOV  A
          ,R3
             ADD  A
          ,#30H
             
          MOV  R3,A
             MOV  A
          ,R2
             ADD  A
          ,#30H
             
          MOV  R2,A
             MOV  A
          ,R1
             ADD  A
          ,#30H
             
          MOV  R1,A
           RET
          ;=============================================== 
          Use age
          mov a,#byte
          lcall write_bcd_8

          return : r3(hang tram),r2 hang chuc,r1 hang don vi
          example:
          mov a,#123
          lcall write_bcd_8
          =>>> step1: r3=1, r2=2, r1=3
          =>>> step2: r3=31h, r2=32h, r1=33h


          Function5: WRITE_BCD_16:
          Tác dụng tương tự như WRITE_BCD_8 nhưng ở đây dùng cho hai thanh ghi tuc là giá trị Max thể hiện là FFFF=65535
          Luu y gia trị In: R1,R0 trong do R1 là byte cao, R0 là byte thấp
          .............. 6 5 5 3 5
          giá trị Out R5,R4,R3,R2,R1
          Trong chương trình tôi có sử dụng phép chia 16bit source from:
          http://www.8052.com/div16.phtml

          WRITE_BCD_16:
          PHP Code:
          ;===============================================
          WRITE_BCD_16
             
          MOV   R3  ,#HIGH(10000)
             
          MOV   R2  ,#LOW(10000)
             
          LCALL DIV16_16
             MOV   A   
          ,R2
             ADD   A   
          ,#30H
             
          PUSH  ACC                   R5
             MOV   R3  
          ,#HIGH(1000)
             
          MOV   R2  ,#LOW(1000)
             
          LCALL DIV16_16
             MOV   A   
          ,R2
             ADD   A   
          ,#30H
             
          PUSH  ACC                   R4
             MOV   R3  
          ,#HIGH(100)
             
          MOV   R2  ,#LOW(100)
             
          LCALL DIV16_16
             MOV   A   
          ,R2
             ADD   A   
          ,#30H
             
          PUSH  ACC                   R3
             MOV   R3  
          ,#HIGH(10)
             
          MOV   R2  ,#LOW(10)
             
          LCALL DIV16_16
             MOV   A   
          ,R2
             ADD   A   
          ,#30H
             
          PUSH  ACC                   R2
             MOV   A   
          ,R0
             ADD   A   
          ,#30H
             
          MOV   R1  ,A                  Value out R1
             POP   ACC
             MOV   R2  
          ,A                  Value out r2
             POP   ACC
             MOV   R3  
          ,A                  Value out r3
             POP   ACC                   
             MOV   R4  
          ,A                  Value out r4
             POP   ACC
             MOV   R5  
          ,A                  Value out r5

          RET 
          Phep chia 16 bit

          PHP Code:
          div16_16:
                             ;
          16-bit division is the division of one 16-bit value by another 16-bit value
                     ;
          returning a 16-bit quotient and a 16-bit remainder
                     ;
          I used r1/r0 for dividend/remainder and r3/r2 for divisor/quotient.
             
          CLR   C         ;Clear carry initially
             MOV   B   
          ,#00h ;Clear B since B will count the number of left-shifted bits
           
          div1:
             
          INC   B         ;Increment counter for each left shift
             MOV   A   
          ,R2   ;Move the current divisor low byte into the accumulator
             RLC   A         
          ;Shift low-byte leftrotate through carry to apply highest bit to high-byte
             MOV   R2  
          ,A    ;Save the updated divisor low-byte
             MOV   A   
          ,R3   ;Move the current divisor high byte into the accumulator
             RLC   A         
          ;Shift high-byte left highrotating in carry from low-byte
             MOV   R3  
          ,A    ;Save the updated divisor high-byte
             JNC   div1      
          ;Repeat until carry flag is set from high-byte
           div2
          :             ;Shift right the divisor
             MOV   A   
          ,R3   ;Move high-byte of divisor into accumulator
             RRC   A         
          ;Rotate high-byte of divisor right and into carry
             MOV   R3  
          ,A    ;Save updated value of high-byte of divisor
             MOV   A   
          ,R2   ;Move low-byte of divisor into accumulator
             RRC   A         
          ;Rotate low-byte of divisor rightwith carry from high-byte
             MOV   R2  
          ,A    ;Save updated value of low-byte of divisor
             CLR   C         
          ;Clear carrywe don't need it anymore
             MOV   07h ,R1   ;Make a safe copy of the dividend high-byte
             MOV   06h ,R0   ;Make a safe copy of the dividend low-byte
             MOV   A   ,R0   ;Move low-byte of dividend into accumulator
             SUBB  A   ,R2   ;Dividend - shifted divisor = result bit (no factor, only 0 or 1)
             MOV   R0  ,A    ;Save updated dividend 
             MOV   A   ,R1   ;Move high-byte of dividend into accumulator
             SUBB  A   ,R3   ;Subtract high-byte of divisor (all together 16-bit substraction)
             MOV   R1  ,A    ;Save updated high-byte back in high-byte of divisor
             JNC   div3      ;If carry flag is NOT set, result is 1
             MOV   R1  ,07h  ;Otherwise result is 0, save copy of divisor to undo subtraction
             MOV   R0  ,06h
          div3:
             CPL   C         ;Invert carry, so it can be directly copied into result
             MOV   A   ,R4 
             RLC   A         ;Shift carry flag into temporary result
             MOV   R4  ,A   
             MOV   A   ,R5
             RLC   A
             MOV   R5  ,A
             DJNZ  B   ,div2 ;Now count backwards and repeat until "B" is zero
             MOV   R3  ,05h  ;Move result to R3/R2
             MOV   R2  ,04h  ;Move result to R3/R2
            RET  
          ;=============================================== 
          useage:

          mov r1,#byte
          mov r2,#byte
          lcall write_bcd_16
          example:
          mov r1,#high(12345)
          mov r0,#low(12345)
          lcall write_bcd_16

          value: r5=31h, r4=32h, r3=33h, r2==34h, r1=35h



          Ở bài viết sau tôi sẽ giới thiệu cách chạy chữ từ trái sang phải
          Attached Files
          Last edited by mafd_47; 22-11-2005, 18:42.
          Dia chi cho cac Fan muon hoc Pic

          Comment


          • #6
            Phần mở rộng về LCD và các vấn đề liên quan (tiếp)

            Ở bài viết này tôi xin đề cập đến chương trình hiển thị một đoạn dữ liệu dịch chuyển từ phải sang trái. Với chương trình này tôi chia ra làm hai module :
            Đoạn dữ liệu có số ký tự >=16( bang kich thước của LCD)
            Đoạn dữ liệu có số ký tự <16

            Trước tiên tôi xin nói nguyên tắc hiện chữ chạy dịch chuyển từ phải sang trái
            Lần đầu xuất hiện 1 ký tự , delay 0,8s, sau đó CLEAR_LCD
            Bước hai: xuất hiện 2 ký tự , delay 0,8s ..............................\
            Bước 3 : xuất hiên3 ký tụ .................................................. ....
            ....
            Tiếp tục thực hiện cho đến khi xuất hiện hết ký tự

            Nguyên lý chỉ đơn giản vậy thôi nhưng tại sao tôi lại phải chia ra hai trương hợp là lớn hơn hay nhỏ hơn 16. Chỉ đơn giản vì hai quá trinh hiện chữ chạy là khác nhau, Bây giờ tôi xin đề cập đến Trường hợp thứ nhất

            1)Đoạn dữ liệu có số ký tự lớn hơn 16

            2)Với kích thước lớn hơn 16 để hiên thị tôi cchia ra làm 3 bước

            Bước thư nhấ:t ( trang thái xuât hiện chuỗi:
            Số lần lặp là 16, mỗi lần lặp tănng lên một ký tự hiển thị,lần thứ nhất một ký tự lần thứ hai hai ký tự hiển thị và............. như vậy khi hoàn thành xong bước thứ nhất 16 ký tự đầu tiên của dữ liệu đC hiển thị

            Bước thứ hai: Số lần lặp là R3-16 ( R3 là thanh ghi lưu kích thước của chuỗi ) , mỗi lần lặp thì có 16 ký tự xuât hiện và dịc chuyển cho đến khi gặp ký tự cuối cùng của chuỗi

            Bước thứ 3: Số lần lặp là 15, sau mỗi lần lặp thì bớt đi mộ ký tự hiển thị như vậy ban đầu có15 ký tự hiển thị và khi kết thúc con 0 ký tự
            Đoạn Code tôi sủ dụng có dùng các module trên các bạn xem lại nhé( lưu ý đến hàm timer0)
            PHP Code:
            ;=============================================
            main:
              
            LCALL INIT_LCD             ;Thiet lap cac trang thai ban dau
              LCALL CLEAR_LCD
             MAIN1
            :
              
            MOV   DPTR,#MYDATA
              
            LCALL DEFINE_DATA_R3
              

            ;=========================== Chu chay =========================================

            ;===========================
            Giai doan 1========================================
              
              
            MOV   R4,#1 
              
            MOV   A,#0EH
              
            PUSH  0E0H
              MOV   R5
            ,#1
             
            step1:                      ; 1->16 buoc dau tien tu 1 den 16 chu se xuat hien
              MOV   R2
            ,#0
              
            POP   0E0H                 Lay du lieu ACC de dinh vi tri cho con tro
              LCALL GOTOLINE1            
            Xac dinh vi tri cua con tro de hien thi chu
              DEC   A
              PUSH  0E0H                 
            Cat A di de cho dung cho dinh vi tri lan sau
             AGAIN_STEP1
            :
              
            MOV   A,R2
              MOVC  A
            ,@A+DPTR
              LCALL WRITE_TEXT
              INC   R2
              DJNZ  R4
            ,AGAIN_STEP1
              INC   R5                   
            tang gia tri R5 
              MOV   A
            ,R5                  
              MOV   R4
            ,A                 gan gia tri R5 cho R4 de dinh so ky tu xuat hien tren LCD
              MOV   A
            ,#8H               ; Dung cho ham delay, tao khoang thoi gian tre la 2s
              
            lCALL TIMER0_100MS_X       ;14H=20 100MS=2S
              LCALL CLEAR_LCD
            ;  MOV   A,#5                 ; Tao khoang thoi gian tre la 500ms
            ;  LCALL TIMER1_100MS_X       
              CJNE  R5
            ,#10H,STEP1

              
            POP   0E0H                 Ket thuc buoc 1


            ;============================giai doan 2=======================================
              
            MOV   R5,#1
              
            MOV   A,R3                 ;Xac dinh so lan lap o buoc 2R3-16)
              
            SUBB  A,#10H
              
            MOV   R3,A

             step2
            :                       ;17=>R3-16 
              MOV   A
            ,R5
              MOV   R2
            ,A                  ;Gan gia tri cua R5 cho R2 de chay chu
              MOV   R4
            ,#10H
              
             
            AGAIN_STEP2:
              
            MOV   A,R2
              MOVC  A
            ,@A+DPTR
              LCALL WRITE_TEXT
              INC   R2
              DJNZ  R4
            ,AGAIN_STEP2
              MOV   A
            ,#8H
              
            LCALL TIMER0_100MS_X       ;Tao khoang thoi gian tre la 2s
              LCALL CLEAR_LCD
            ;  MOV   A,#5
            ;  LCALL TIMER1_100MS_X       ;Tao khoang thoi gian tre la 500ms
              INC   R5
              DJNZ  R3
            ,STEP2             ;Ket thuc buoc 2 tai day

              
            ;=============================Giai doan 3======================================
                                         ;
            Co 15 lan lap gia tri cua R4 giam dan tu 15->1
              MOV   R3
            ,#00Fh
              
             
            step3:
              
            MOV   A,R3
              MOV   R4
            ,A                 ;Gan gia tri R3 cho R4 de gia chi cua R4 giam dan tu 15->1
              MOV   A
            ,R5
              MOV   R2
            ,A
             AGAIN_STEP3
            :                ; can thiet tu buoc 2 de lai
              MOV   A
            ,R2
              MOVC  A
            ,@A+DPTR
              LCALL WRITE_TEXT
              INC   R2
              DJNZ  R4
            ,AGAIN_STEP3
              MOV   A
            ,#8H
              
            LCALL TIMER0_100MS_X       ;Tao khoang thoi gian tre la 2s
              LCALL CLEAR_LCD
             
            MOV   A,#1
             
            LCALL TIMER1_100MS_X       ;Tao khoang thoi gian tre la 500ms
              INC   R5
              DJNZ  R3
            ,STEP3
              
             

              MOV    A
            ,#40
              
            LCALL  TIMER0_100MS_X

             ljmp MAIN1           
            vong lap vo han ket thuc chuong trinh
             

             mydata 
            :
              
            DB    "HELLO WORLD by ManhFD 123456789 THUYCG"
              
            DB    00000001b            00000001 is character of terminate data
                                         
            It use to define the number of character of data
             
            END

            ;============================================================== 

            hàm timer:



            PHP Code:
            timer0_100ms_X:
              
            PUSH  07                   ;Cat gia tri R7 di
              MOV   TMOD
            ,#01H
              
            MOV   R7,A
             AGAIN
            :                      ;TIMER 100ms
              MOV   TH0
            ,#HIGH(-46082)
              
            MOV   TL0,#LOW(-46082)
              
            SETB  TR0
             TEST
            JNB TF0,TEST
              CLR   TF0
              DJNZ  R7
            ,AGAIN              moi lan nhay la mot lan them 100ms nua
              CLR   TR0                   

              
            POP   07                    Lay lai gia tri da bi lay di
             RET
            ;===================================================== 
            2).Đoạn dữ liệu có số ký tự nhỏ hơn 16
            Tôi cũng chia ra làm 3 Step :

            Bước thứ nhất : số lần lặp là R3( R3 là thanh Ghi lưu giá trị kích thước của chuỗi) mỗi lần lặp là một lần tăng một ký tự hiển thị : lần đầu là 1ký tự lần cuối cùng là R3 ký tự

            Bước thứ hai Số lần lặp là 16-R3 , mỗi lần lặp là có R3 ký tự xuất hiện

            Bước thứ 3: Số lần lặp là R3, sau mỗi lần lặp thì số ký tự hiển thị giảm đi một lần

            Sau đây là đoạn Code chương trình
            PHP Code:
            ;=============================================
            main:
              
            LCALL INIT_LCD             ;Thiet lap cac trang thai ban dau
              LCALL CLEAR_LCD
            main1
            :
              
            MOV   DPTR,#MYDATA
              
            LCALL DEFINE_DATA_R3
              

            ;=========================== Chu chay =========================================

            ;===========================
            Giai doan 1========================================
              
              
            MOV   R4,#1 
              
            MOV   R6,#00EH
              
            MOV   R5,#1
             
            step1:                      ; 1->R3 buoc dau tien tu 1 den 16 chu se xuat hien
              MOV   R2
            ,#0
              
            MOV   A,R6
              LCALL GOTOLINE1            
            Xac dinh vi tri cua con tro de hien thi chu
              DEC   R6
             AGAIN_STEP1
            :
              
            MOV   A,R2
              MOVC  A
            ,@A+DPTR
              LCALL WRITE_TEXT
              INC   R2
              DJNZ  R4
            ,AGAIN_STEP1
              INC   R5                   
            tang gia tri R5 
              MOV   A
            ,R5                  
              MOV   R4
            ,A                 gan gia tri R5 cho R4 de dinh so ky tu xuat hien tren LCD
              MOV   A
            ,#8H               ; Dung cho ham delay, tao khoang thoi gian tre la 2s
              
            lCALL TIMER0_100MS_X       ;14H=20 100MS=2S
              LCALL CLEAR_LCD
              
            ;MOV   A,#5                 ; Tao khoang thoi gian tre la 500ms
              
            ;LCALL TIMER1_100MS_X       
              DJNZ  R3
            ,STEP1
             
            ;============================giai doan 2=======================================
              
            LCALL DEFINE_DATA_R3
              MOV   A
            ,#15                 ;Xac dinh so lan lap o buoc 2( R3-16)
              
            SUBB  A,R3
              MOV   R5
            ,A

             step2
            :                       ;R3+1->16Tuc la cho den khi ky tu dau tien tai vi tri 0
              
              
            MOV   R2,#0                 ;Bat dau mot chu ky moi
              
            MOV   A,R3
              MOV   R4
            ,A                  ;Gan gia tri R3 vao R4 de cho hien chu 
              MOV   A
            ,R5                  
              DEC   A                     
            ;Xac dinh vi tri cua con tro hien thi chu(TU 5-4-3-2-1-)
              
            LCALL GOTOLINE1
              
             AGAIN_STEP2
            :
              
            MOV   A,R2
              MOVC  A
            ,@A+DPTR
              LCALL WRITE_TEXT
              INC   R2
              DJNZ  R4
            ,AGAIN_STEP2
              MOV   A
            ,#8H
              
            LCALL TIMER0_100MS_X       ;Tao khoang thoi gian tre la 2s
              LCALL CLEAR_LCD
              
            ;MOV   A,#5
              
            ;LCALL TIMER1_100MS_X       ;Tao khoang thoi gian tre la 500ms
              DJNZ  R5
            ,STEP2             ;Ket thuc buoc 2 tai day
              
            ;=============================Giai doan 3======================================
              
            MOV   R5,#1                
              
            DEC   R3
             step3
            :
              
            MOV   A,R3
              MOV   R4
            ,A                 ;Gan gia tri R3 cho R4 de gia chi cua R4 giam dan tu R3->1
              MOV   A
            ,R5
              MOV   R2
            ,A
             AGAIN_STEP3
            :                ; So ky tu xuat hien giam dan tu r3-1->1
              MOV   A
            ,R2
              MOVC  A
            ,@A+DPTR
              LCALL WRITE_TEXT
              INC   R2
              DJNZ  R4
            ,AGAIN_STEP3
              MOV   A
            ,#8H
              
            LCALL TIMER0_100MS_X       ;Tao khoang thoi gian tre la 2s
              LCALL CLEAR_LCD
             
            MOV   A,#5
             
            LCALL TIMER1_100MS_X       ;Tao khoang thoi gian tre la 500ms
              INC   R5
              DJNZ  R3
            ,STEP3

               

              ljmp main1           
            vong lap vo han ket thuc chuong trinh
             

             mydata 
            :
              
            DB    "HELLO WORLD"
              
            DB    00000001b            00000001 is character of terminate data
                                         
            It use to define the number of character of data

            ;========================================================= 
            Có lẽ tôi đã viết dài quá rồi , chắc các bạn cũng chả đọc được , hy vọng rằng nó sẽ giúp cho các bạn phần nào về cách lập trinh LCD, và cách lập trinh Assembler.

            Hẹn gặp các bạn lần sau
            Attached Files
            Last edited by mafd_47; 22-11-2005, 18:39.
            Dia chi cho cac Fan muon hoc Pic

            Comment


            • #7
              Đây là bài viêt rất đầy đủ, em đã lập trình y như trên và mạch chạy rất ngon. Cam ơn bác nhiều lần

              Comment


              • #8
                Rất hoan nghênh mafd_47 đã post các bài trên. Bài em post dài quá nên mặc dù rất muốn nhưng anh cũng không có đủ thời gian để đọc hết một cách chi tiết, chỉ có thể đọc lướt qua. Cách em viết hợp ngữ khá hay và anh có một số điều góp ý mong em sẽ hiểu thêm về LCD và hoàn thiện thêm "nghệ thuật hợp ngữ" của mình:

                1- Cái này không dính dáng đến hợp ngữ, đó là thắc mắc của em về hai chân A và K của LCD. Đó là các chân Anode và Cathode của các LED backlight. Do bản chất cấu tạo, ta không thể nhìn thấy ký tự trên LCD nếu không có nguồn sáng xung quanh. Trong điều kiện ánh sáng môi trường yếu hoặc không có, LCD muốn hiển thị thì phải tự tạo ánh sáng cho riêng nó. Các LED backlight được thiết kế bên trong LCD để thực hiện nhiệm vụ này. Muốn LCD tự phát sáng, em chỉ việc đặt điện áp phân cực thuận cho hai chân AK này (em có thể dùng transistor để điều khiển tắt bật theo ý muốn).

                2- Cái này cũng không liên quan đến hợp ngữ: theo anh biết thì chân Enable của LCD tích cực mức cao chứ không phải mức thấp. Em check lại xem nhé.

                3- Cũng lại không liên quan đến hợp ngữ: ban đầu ngay sau khi được cấp nguồn, LCD cần có một khoảng thời gian cỡ vài chục ms để tiến hành quá trình khởi tạo bên trong nó. Do đó em nên trễ vài chục ms ban đầu trước khi bắt đầu gửi các lệnh khởi tạo cho LCD.

                4- Bắt đầu dính đến hợp ngữ: Trước hết nói về chương trình hiển thị một chuỗi các ký tự lên LCD. Cái này em viết hay, nhưng theo anh có thể không cần phải có chương trình xác định độ dài chuỗi, làm vậy dài dòng, mình chỉ cần định nghĩa chuỗi có độ dài tùy ý miễn là kết thúc bằng 0, chương trình hiển thị chỉ cần đọc từng byte liên tục và dừng cho đến khi nào đọc được 0. Anh ví dụ mình có thể viết thế này nhé:
                ...
                mov dptr,#my_string
                lcall send_tring_to_lcd
                ...
                send_string_to_lcd:
                clr a
                movc a,@a+dptr
                jz end_of_string
                lcall write_data ;gọi chương trình gửi một ký tự lên LCD
                inc dptr
                sjmp send_string_to_lcd
                end_of_string:
                ret
                ...
                my_string:
                db "Chuc em hoc tot ky thuat vi xu ly",0
                ...

                5- Về chương trình chạy chữ trên LCD, anh chưa đọc kỹ, mới chỉ đọc phần em viết về phương pháp. Theo anh thì mình có thể đơn giản hóa vấn đề bằng cách viết luôn toàn bộ nội dung hiển thị lên vùng RAM hiển thị của LCD. Sau đó sau từng khoảng thời gian em có thể dùng lệnh dịch màn hình (Display Shift) để tạo ra hiệu ứng chạy chữ. Em thử xem thế nào nhé.

                Hẹn em lần sau.

                Comment


                • #9
                  Quả là xứng danh BẮC HIỆP, võ công đạt mức thượng thừa. Với công lực kinh người như vậy, thì môn công phu khác đâu có nghĩa lý gì.. tại hạ tự thấy mình xấu hổ ... xấu hổ... than ôi...
                  -------------------

                  Comment


                  • #10
                    To blackmoon : Phải cảm ơn bác nhiều lắm. Nhờ có sư góp ý của bác em đã đọc kỹ Datasheet của nó và thấy rằng kiến thức về LCD của em thật hổng quá đi mất,
                    Em sẽ sủa lại bài viết trên , Nếu không ko biết sẽ tai hại như thế nào

                    Một lần nữa thank bác, những kinh nghiệm của bác về VDK là rất đáng quý với nhưng ngưới như em :? :? :? :? :?
                    Dia chi cho cac Fan muon hoc Pic

                    Comment


                    • #11
                      không hiểu các bác viết cho LCD thì dung lượng lớn không chứ tui viết riêng một cái driver cho nó hết tới 1.73kbyte luôn mà có cái gì đâu chỉ có mấy cái hàm như: khởi tạo, xóa , settingcursor, xuatLCD,tọa độ , 3 4 cái hiệu ứng chữ chạy gì đấy và một số cái hàm nữa.
                      em dịch bằng ride51
                      không biết mấy bác nghĩ sao
                      Cty TNHH Cơ Điện tử Hiệp Phát.
                      ------------------------------------------
                      Trần Hoàng Giang
                      11-04-1985

                      Mobil: 0905 438 533

                      Comment


                      • #12
                        Mình th2 chuyên đùng ASM để mà lập trình nên file không lớn lắm sau khi biên dịch ! Thông thương nếu dùng C có sử dụng prototye math.h thì biên dịch dù chương trình nhỏ cũng thành lớn ! Nên hạn chế các hàm trong này nếu bạn dùng C

                        Comment


                        • #13
                          vâng tất cả các hàm tui sử dụng tui toàn chế ra đấy chứ mà không hiểu tại sao nó lạ lớn thế
                          Cty TNHH Cơ Điện tử Hiệp Phát.
                          ------------------------------------------
                          Trần Hoàng Giang
                          11-04-1985

                          Mobil: 0905 438 533

                          Comment


                          • #14
                            Nguyên văn bởi irf540
                            vâng tất cả các hàm tui sử dụng tui toàn chế ra đấy chứ mà không hiểu tại sao nó lạ lớn thế
                            Sao bác kô gửi code lên để anh em tham khảo, biết đâu lại có cao kiến gì, chứ bác cứ nói thế này thì làm sao ai giúp gì được!!!!!!!!!
                            Dia chi cho cac Fan muon hoc Pic

                            Comment


                            • #15
                              Có bác nào lập trình vô Gram chưa. Nếu ai có kinh nghiệm thì xem dùm tui làm như vậy

                              Có bác nào lập trình vô Gram chưa. Nếu ai có kinh nghiệm thì xem dùm tui làm như vậy đúng không.giả sử ghi byte đầu tiên:

                              1.khởi động LCD (như hướng dẩn), i=0.
                              2.chọn vị trí của Gram (0x40+ i )
                              3.ghi byte hiển thị vào vị trí này
                              4.tăng i 1 lập lại bước 2 cho đến 8 lần
                              (sau mổi lệnh đều dủng hàm trể để đảm bảo chip của LCD xử lí xong)

                              như vậy sau 8 lần ghi ta được một kí tự có hình dạng như mong muốn xuất hiện lên LCD phải không. tui làm như vậy mà không thấy hiển thị gì cả
                              nhưng không phải làm mạch ở ngoài mà chỉ chạy mô phỏng trên Proteus 6.7 SP3. Tui không biết do Proteus nó không hổ trợ hay tui lập trình sai.
                              Bước 1 LCD tui làm không sai vì sau khi khởi động tui chi vào D Ram thì LCD hiển thị bình thường.
                              Rất mong bà con chỉ giúp.

                              Comment

                              Về tác giả

                              Collapse

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

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

                              Collapse

                              Đang tải...
                              X