LCD 步進馬達程式  LCD 按鍵程式

實習十          以I/O八位元介面方式控制LCD(字元型)

 

目的    :   
                    瞭解8051微電腦以I/O八位元介面方式控制LCD原理及方法。

使用材料    :

                                 PC    *    1         8051模擬板    *    1

功能說明    :    
                                  程式執行後,LCD顯示出" LCD   TEST   O . K . ! "兩列字形,按 Reset 鈕,則

                                    清除LCD 再重新顯示一次。

電路圖    : 

程式及說明    :

;****************************************************************

ENABLE        REG         P3.4                        ;define LCD Enable pin = P3.4

R_W               REG         P3.3                        ;define LCD R/W pin = P3.3

RS                   REG         P3.2                        ;define LCD RS pin = P3.2

                       ORG         0H                          ;code address

START:                                                          ;reset start here

                       CLR          ENABLE               ;set E = 0, disable LCD

;STEP0:           reset LCD                               ;

                       CALL        LCD_RESET         ;soft reset LCD

;STEP1:           function set                               ;

                        MOV        A,#00111000B      ;function set: 8-bit operation

                                                                        ; & dual line

                         CALL       RS0                        ;send out data & cotrol signal

                                                                         ;

;STEP2:            turn on display                          ;

                         MOV        A,#00001110B      ;display on (D = C = 1, B = 0):

                         CALL        RS0                       ;send out data & cotrol signal

                                                                         ;

;STEP3:            set entry mode                          ;

                        MOV         A,#00000110B      ;cursor shift right

                        CALL         RS0                       ;send out data & cotrol signal

                                                                         ;

;STEP4:            display/cursor return home

                        MOV         A,#00000010B      ;display/cursor return home

                        CALL         RS0                        ;send out data & cotrol signal

                                                                          ;

;STEP5:           clear display                                ;

                        MOV         A,#00000001B       ;clear display

                        CALL          RS0                        ;send out data & cotrol signal

                                                                           ;

;STEP6:            set Display Data RAM address (for 1st line)

                        MOV           A,#10000101B       ;set Display Data RAM address = 5

                        CALL          RS0                         ;send out data & cotrol signal

                                                                            ;

                        MOV          R3,#03                     ;3 characters on first line

                         MOV          DPTR,#LINE1         ;load data pointer with LINE1

NEXT1:            MOV          A,#0                         ;load index A = 0

                         MOVC       A,@A+DPTR           ;get ASCII code of the character

                                                                              ;

;STEP7:            write data to DD RAM (for 1st line)

                         CALL          RS1                           ;send out data & cotrol signal

                          INC            DPTR                        ;increase data pointer

                          DJNZ          R3,NEXT1                ;at the end of the 1st line?

                                                                               ; if no, jump to NEXT1

                                                                                ;

;STEP8:              set Display Data RAM address (for 2nd line)

                         MOV            A,#11000000B          ;set Display Data RAM address = 40H

                         CALL            RS0                           ;send out data & cotrol signal

                                                                                 ;

                          MOV            R3,#10                      ;10 characters on second line

                          MOV            DPTR,#LINE2          ;load data pointer with LINE2

NEXT2:             MOV            A,#0                          ;load index A = 0

                          MOVC          A,@A+DPTR           ;get ASCII code of the character

                                                                                 ;

;STEP9:              write data to DD RAM (for 2nd line)

                           CALL            RS1                         ;send out data & cotrol signal

                            INC              DPTR                      ;increase data pointer

                            DJNZ            R3,NEXT2              ;at the end of the 2nd line?

                                                                                  ;

                             JMP             $                               ;pseudo halt, jmp self

                                                                                  ;

LINE1                  DB                "LCD"                      ; "     LCD           (1st line)

LINE2                  DB                "TEST O.K.!"           ;  TEST O.K.!  "      (2nd line)

;subroutine RS0: set RS(P3.2) = 0 & make a E(P3.4) positive pulse

;and R/W(P3.3)=0 for write to LCD, then send out data(P1) to LCD

RS0:                    CALL            CHECK_BUSY       ;wait, until LCD non-busy

                             MOV             P1,A                        ;send out data to LCD data bus

                             CLR               RS                           ;set RS = 0

                             CLR               R_W                        ;set R/W = 0,(write) to LCD

                             SETB             ENABLE                 ;set E = 1, high pulse, enable

                             CLR               ENABLE                 ;set E = 0, return normal low

                              RET                                               ;

;subroutine RS1: set RS(P3.2) = 1 & make a E(P3.4) positive pulse

;and R/W(P3.3)=0 for write to LCD, then send out data(P1) to LCD

RS1:                      CALL            CHECK_BUSY        ;wait, until LCD non-busy

                             MOV              P1,A                         ;send out data to LCD data bus

                             SETB              RS                            ;set RS = 1

                             CLR                R_W                        ;set R/W = 0,(write) to LCD

                             SETB              ENABLE                  ;set E = 1, high pulse, enable

                             CLR                ENABLE                  ;set E = 0, return normal low

                             RET                                                  ;

;read busy flag and check, until LCD non-busy

CHECK_BUSY:                                                            ;

                             MOV               P1,#0FFH                 ;trun off output driver FET

                              CLR                RS                             ;set RS = 0

                              SETB               R_W                         ;set R/W = 1,(read) from LCD

                              SETB               ENABLE                  ;set E = 1, high pulse, enable

                              MOV               C,P1.7                      ;load C with busy flag(bit 7)

                              CLR                 ENABLE                  ;set E = 0, return normal low

                               JC                   CHECK_BUSY        ;if BF = 1,keep checking_busy

                               RET                                                   ;

LCD_RESET:

                                MOV              A,#00110000B          ;function set

                                CALL              RS0                           ;send out data & cotrol signal

                                MOV               R2,#41                      ;delay parameter

$1:                            MOV               R1,#50                      ;delay parameter

                                 DJNZ               R1,$                          ; about 41*50*2 us = 4.1 ms

                                 DJNZ               R2,$1                         ;

                                 MOV               A,#00110000B           ;function set

                                 CALL               RS0                            ;send out data & cotrol signal

                                  MOV               R1,#50                       ;delay parameter

                                   DJNZ              R1,$                           ; about 50*2 us = 100 us

                                   MOV              A,#00110000B          ;function set

                                   CALL              RS0                           ;send out data & cotrol signal

                                   RET

                                   END                                                  ;end of program

1. 3~5行 : 符號定義,控制LCD之三支腳分別為Enable,Read/Write及Register  select。

2. 7~9行 : 因E角為high及下緣動作,故未動作期間應設low(第八行指令)。第九行LCD Reset,此行不加入則

                第二次 Reset鈕時(暖開機),LCD可能動作不確定。

3. 11~61行 : 程式中使LCD出現兩列字 ,共分為九個STEP,流程甚明顯易懂,不在贅述。

4. 63~64行 : 存放字串ASCII碼之處。

5. 65~73行 : 寫入指令暫存器(RS=0)之副程式,E腳要升high再降為low。

6. 74~82行 : 寫入資料暫存器(RS=1)之副程式,與寫入指令暫存器之副程式類似,一開始先讀取Busy  flag 

                     到BF=0才寫入。兩個副程式只有RS為0為1之不同。

7. 83~92行 : 讀取BF,再RS=0時讀位元7,8051有單位元處理指令(第89行),非常方便。若BF=1,表示正忙

                     著,在迴圈讀取測試直到不忙。

8. 93~106行 : 8位元之LCD重置程序。

2、LCD 按鍵程式

目的:

如何驅瞭解鍵盤掃瞄之方法和如何驅動液晶顯示器.

 二.使用材料:

             16字X2列的LCD一片(20字X2列亦可),5K歐姆可變電阻一個,8051微電腦一 片,按鈕開關16個.排線3條,模擬版一片。

 三.功能說明:

                程式執行後,LCD顯示一閃爍游標並開始掃瞄是否有按鈕被按下,如有被按下顯示出該按鈕所對應之16進制數字1.2.3.E.F,,由左至右依次顯示出來。

 四.說明:

             本程式以按鈕是否被按下的高低電位來判斷是那一個按鈕,其中P1.0-P1.3送出訊號,此為"掃瞄訊號",而由P1.4-P1.7回收訊!號此為"按鈕訊號",藉由此種方式 ,可找出 4*4 鍵盤上任何一顆按鈕所對應之位置,並把輸入之訊號所對應的資料由暫存器中拿出,由P0.1-P0.7輸入到LCD顯示器上。

五、流程圖:

 

 

 

六、電路圖:

 

七、程式:

ENABLE    REG     P3.2

R_W          REG   P3.1

RS              REG     P3.0

                  ORG     0H

START:

                   CLR     ENABLE       ;清除致能

                   CALL    LCD_RESET    ;清除LCD

                   MOV     A,#00111000B ;8bit,雙列,5*7

                   CALL   RS0

                   MOV    A,#00001110B ;顯示游標且不閃爍

                   CALL   RS0

                   MOV    A,#00000110B ;向右顯示,顯示幕不移動

                   CALL   RS0

                   MOV    A,#00000010B  ;游標回到左上角

                   CALL   RS0

                   MOV    A,#00000001B  ;清除顯示器

                   CALL   RS0

                   MOV   A,#10000000B ;00H開始顯示

         CALL   RS0

                   MOV    DPTR,#TABLE

 

AGAIN: 

                    ACALL   IN

                    MOV     A,R0

                    XRL     A,#0FFH ;將鍵值資料送至LCD模組

                    JZ      AGAIN

                    MOV     A,R0

                    MOVC    A,@A+DPTR

                    CALL    RS1

              JMP     AGAIN

 

IN:      

                      MOV     R0,#0

                      MOV    R1,#4

                      MOV     R2,#F7H

 

COL:

                        MOV    A,R2

                       MOV     P2,A

                       MOV     A,P2

                        ANL     A,#F0H

                        MOV     R3,A

                        MOV     R4,#4

 

ROW:

       SETB    C

                         RLC     A

                         JNC     S1

                         INC     R0

                         DJNZ    R4,ROW

                         MOV     A,R2

                          RR     A   ;將掃瞄鍵值存入A累積器

                          MOV     R2,A

                          DJNZ    R1,COL

                          MOV     R0,#0FFH

                          SJMP    EXIT

 

S1:   

               MOV    P2,#0F0H

                           CALL    DEL0

                           MOV     A,P2

                           ANL     A,#0F0H

                           XRL     A,R3

                           JZ      S1

 

EXIT:

          RET

 

DEL0:

          MOV    R7,#255

                            DJNZ    R7,$     ;反彈跳

                             RET

                             ORG     100H

TABLE:

             DB   30H

                              DB   31H

                              DB   32H

                              DB   33H

                              DB   34H

                              DB   35H      ;設定鍵值

                              DB   36H

                              DB   37H

                           DB   38H

                              DB   39H

                              DB   41H

                              DB   42H

                              DB   43H

                              DB   44H

                              DB   45H

                              DB   46H

RS0:

             CALL    CHECK_BUSY

                               MOV     P1,A

                               CLR     RS        ;指令碼送入LCD

                               CLR     R_W

                               SETB    ENABLE

                               CLR     ENABLE

RET

  RS1:

        CALL   CHECK_BUSY

                                MOV     P1,A

                                SETB    RS

                                CLR     R_W   ;資料送入LCD模組

                                SETB    ENABLE

                                CLR     ENABLE

                                RET

 

CHECK_BUSY:

                                MOV     P1,#0FFH

                                CLR     RS

                                SETB    R_W

                                SETB    ENABLE    ;檢查LCD是否忙碌

                                MOV     C,P1.7

            CLR     ENABLE

                                JC      CHECK_BUSY

                                RET

LCD_RESET:

                                MOV     A,#00110000B

                             CALL    RS0

                                MOV     R2,#41

$1: 

                    MOV    R1,#50

                                DJNZ    R1,$

                                DJNZ    R2,$1

                                MOV     A,#00110000B

                                CALL    RS0

                                MOV     R1,#50   ;清除LCD

            DJNZ    R1,$

                                MOV     A,#00110000B

                                CALL    RS0

                                RET

                                END

三、  LCD 步進馬達程式

        

 一.目的:

         瞭解步進馬達之驅動方法和計算馬達所轉之步數.

 二.使用材料:

             16字X2列的LCD一片(20字X2列亦可) ,5K歐姆可變電阻一個,8051微電腦一片,按鈕開關16個,步進馬達一顆.

 三.功能說明:

             程式執行後,LCD顯示一正轉/反轉並開始掃瞄是否有按鈕被按下,如有被按下顯示出該馬達所轉之圈數.

 四.說明:                             

         本程式以按鈕是否被按下的高低電位來判斷是那一個按鈕,其中P1.0-P1.3送出訊號,此為"掃瞄訊號",而由 P1.4-P1.7回收訊!號此為"按鈕訊號",並把所輸入之訊號傳到步進馬達,讓馬達轉動.

 

五、流程圖:

 

 

六、電路圖:

 

七、程式:

ROTATE    EQU   20H

BUFFER  EQU   21H

ENABLE  REG   P3.2

R_W       REG   P3.1

RS       REG   P3.0

             ORG   0H

             MOV   SP,#60H

START:

              CLR      ENABLE

;STEP0:     

               CALL LCD_RESET

;STEP1:

                MOV   A,#00111000B

                CALL  RS0

;STEP2: 

                 MOV  A,#00001110B

                 CALL LCD_RESET

;STEP3:

                 MOV   A,#00000110B

                CALL  RS0

;STEP4:

                  MOV   A,#00000010B

                  CALL  RS0

;STEP5:

                    MOV   A,#00000001B

                    CALL RS0

;STEP6: 

                    MOV   A,#10000000B

                    CALL   RS0

                    MOV   R3,#04

                    MOV   DPTR,#LINE1

NEXT1:

                    MOV    A,#0

                    MOVC   A,@A+DPTR

                    CALL    RS1

                    INC      DPTR

                    DJNZ     R3,NEXT1

AGAIN:        

ACALL IN

                     MOV       A,R0

                     XRL          A,#0FFH

                      JZ       AGAIN

                      CJNE      R0,#45H,KEY1

                      AJMP     START

KEY1:

                       CJNE     R0,#41H,KEY2

                       MOV          ROTATE,#52H

                        SJMP      LIST

KEY2:

                        CJNE    R0,#42H,KEY3

                        MOV        ROTATE,#4CH

                        SJMP       LIST

KEY3:     

                         SJMP     AGAIN

LIST:  

                         MOV      A,ROTATE

                         CALL    RS1

                         MOV     R3,#5

                         MOV     DPTR,#LINE2

NEXT2: 

                          MOV     A,#0

                          MOVC  A,@A+DPTR

                          CALL     RS1

                          INC     DPTR

                          DJNZ      R3,NEXT2

                          MOV        R6,#2

AGAIN2:

                           ACALL  IN

                           MOV          A,#0FFH

                            JZ        AGAIN2

                           CJNE       R0,#45H,KEY4

                           AJMP      START

KEY4:

                            MOV         A,R0

                            ANL    A,#0F0H

                            CJNE     A,#30H,AGAIN2

                            DEC     R6

                            CJNE        R6,#0,KEY5

                           MOV    BUFFER+1,R0

                             MOV         A,R0

                             CALL     RS1

                             SJMP     AGAIN3

KEY5:

                             MOV         BUFFER,R0

                              MOV         A,R0

                              CALL     RS1

                              AJMP     AGAIN2

AGAIN3:

                              ACALL  IN

                              MOV         A,#0FFH

                               JZ           AGAIN3

                               CJNE        R0,#45H,KEY6

                               AJMP        START

KEY6:

                                CJNE      R0,#43H,AGAIN3

                                MOV          A ,#11000000B

                                CALL      RS0

                                MOV          R3,#13

                                MOV         DPTR    

                                MOV    A,#0

                                MOVC   A,@A+DPTR

        

NEXTE:       

                                  MOV    A,#0

                                  MOVC     A,@A+DPTR

                                  CALL   RS1

                                  INC       DPTR

                                  DJNZ   R3,NEXTE

                                  SJMP    $

 

LINE2                        DB     "CYc="

LINEE                        DB     "START ROTATE!"

IN:                              MOV     R0,#0

                                   MOV     R1,#4

                                   MOV     R2,#0F7H

COL:                           MOV     A,R2

                                    MOV     P2,A

                                    MOV     A,P2

                                    ANL      A,#0F0H

                                    MOV      R3,A

                                    MOV      R4,#4

ROW:                          SETB      C

                                     R LC        A

                                     JNC          S1

                                     INC     R0

                                     DJNZ    R4,ROW

                                     MOV          A,R2

        RR      A

                                     MOV      R2,A

                                     DJNZ     R1,COL

                                     MOV      R0,#0FFH

                                     SJMP      EXIT

S1:                               MOV      P2,#0F0H

                                    CALL     DEL0

                                    MOV      A,P2

                                     ANL         A,#0F0H

                                     XRL         A,R3

                                      JZ           S1

                                     MOV        A,R0

                                     MOV        DPTR,#TABLE

                                     MOVC     A,@A+DPTR

                                     MOV        R0,A

EXIT:                            RET

DEL0:

                                      MOV     R7,#255

                                      DJNZ        R7,4

                                      RET

TABLE:   

                                       DB      30H

                                       DB      31H

                                       DB      32H

                                       DB      33H

                                       DB      34H

                                       DB      35H

                                       DB      36H

                                       DB      37H

                                       DB      38H

                                      DB      39H

                                      DB      41H

        DB      42H

                                      DB      43H

                                      DB      44H

                                      DB      45H

                                      DB      46H

RS0:   

                                      CALL   CHECK_BUSY

                                      MOV        P1,A

                                      CLR   RS

                                      CLR   R_W

         SETB       ENABLE

                                       CLR   ENABLE

                   RET

RS1: 

                                        CALL    CHECK_BUSY

                                        MOV    P1,A

                                        SETB   RS

                                        CLR        R_W

                                        SETB   ENABLE

                                        CLR        ENABLE

                                        RET

CHECK_BUSY:

                                        MOV    P1,#0FFH

                                        CLR        RS

                                        SETB   R_W

                                         SETB   ENABLE

                                        MOV  C,P1.7

                                        CLR   ENABLE

                                         JC          CHECK_BUSY

                                         RET

LCD_RESET:

                                         MOV  A,#00110000B

                                         CALL       RS0

                                          MOV    R2,#41                                   

$1:            

MOV   R1,#50H

                                          DJNZ R1,$

                                          DJNZ R2,$1

                                          MOV  A,#00110000B

                                          CALL       RS0

                                          MOV  R1,#50

                                          DJNZ R1,$

                                          MOV  A,#00110000B

                                          CALL       RS0

                                          RET

                                           END