This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

LCD help needed

Hello EveryBody, I am working on LCD (16x2) and i have built some of my ideas about LCD programming but i am using Assembly language for my LCD, well as all things was going sweet so as every programmer is having something wrong ... (in starting) my problem specification is that i am using that LCD in 8-bit mode and i have connected my AT89C2051 (with some pull-ups)
P1 DB
P3.7 RS
P3.5 RW
P3.4 E
and i have interfaced my LCD with my MCu but my problem is that i am getting the LCD not working ... (i dont know why) .... i have interfaced my LCD but there only little bit of contrast....i mean to say that there nothing visible... even i move my 10K-ohm-POT to the ground.....

and i have done some programming, so could any one please help me .... (i am really stucked)
any help will be appritiatable.....

<code> ORG 0000H LJMP MAIN ORG 0030H RS EQU P3.7 RW EQU P3.5 EN EQU P3.4
MAIN: LCALL DELAY CLR EN MOV DPTR,#MYCOM LCALL LCD_INI MOV DPTR,#MYDATA LCALL LOOP MOV A,#0C9h LCALL COM LCALL DELAY MOV DPTR,#MYDAT2 LCALL LOOP
AGAIN: SJMP AGAIN
;========================================
COM: MOV P1,A CLR RS CLR RW SETB EN LCALL DELAY CLR EN RET
;========================================
DATAW: MOV P1,A SETB RS CLR RW SETB EN LCALL DELAY CLR EN RET
;========================================
DELAY: MOV R6,#100
HERE2: MOV R7,#250
HERE: DJNZ R7,HERE DJNZ R6,HERE2 RET
;========================================
LCD_INI: CLR A MOVC A,@A+DPTR LCALL COM LCALL DELAY JZ GO_B1 INC DPTR SJMP LCD_INI
GO_B1: RET
;========================================
LOOP: CLR A MOVC A,@A+DPTR LCALL DATAW LCALL DELAY INC DPTR JZ GO_B2 SJMP LOOP
GO_B2: RET
;========================================
MYCOM: DB 38H,0EH,06,01,84H,0
MYDATA: DB "DAREDEVIL",0
MYDAT2: DB "GUNS AND ROSES",0
;======================================== END
</code>

Asif Ali "DareDevil"

Parents
  •                 ORG 0000H
                    LJMP MAIN
                    ORG 0030H
                                        ;initialization
    MAIN:           MOV A,#038H                     ;first time
                    LCALL COM
                    MOV A,#038H             ;second time
                    LCALL COM
                    MOV A,#038H             ;third time
                    LCALL COM
                    MOV A,#038H             ;fourth time
                    LCALL COM
                    MOV A,#00EH
                    LCALL COM
                    MOV A,#001H
                    LCALL COM
                    MOV A,#006H
                    LCALL COM
                    MOV A,#084H
                    LCALL COM                ;initialization End
                    MOV A,#'A'               ;data to write on LCD
                    LCALL DATAW
                    MOV A,#'L'
                    LCALL DATAW
                    MOV A,#'I'              ;data end
                    LCALL DATAW
    AGAIN:          SJMP AGAIN               ;endless loop
    COM:            MOV P1,A                         ;command write sequence
                    CLR P3.7
                    CLR P3.5
                    SETB P3.4
                    CLR P3.4
                    ;LCALL DELAY
                    RET
    DATAW:          MOV P1,A                        ;data write sequence
                    SETB P3.7
                    CLR P3.5
                    SETB P3.4
                    CLR P3.4
                    ;LCALL DELAY
                    RET
    DELAY:          MOV R6,#50              ;simple delay routine
    HERE2:          MOV R7,#255             ;for 0.0124S or 124MS
    HERE:           DJNZ R7,HERE
                    DJNZ R6,HERE2
                    RET
                    END
    
    

Reply
  •                 ORG 0000H
                    LJMP MAIN
                    ORG 0030H
                                        ;initialization
    MAIN:           MOV A,#038H                     ;first time
                    LCALL COM
                    MOV A,#038H             ;second time
                    LCALL COM
                    MOV A,#038H             ;third time
                    LCALL COM
                    MOV A,#038H             ;fourth time
                    LCALL COM
                    MOV A,#00EH
                    LCALL COM
                    MOV A,#001H
                    LCALL COM
                    MOV A,#006H
                    LCALL COM
                    MOV A,#084H
                    LCALL COM                ;initialization End
                    MOV A,#'A'               ;data to write on LCD
                    LCALL DATAW
                    MOV A,#'L'
                    LCALL DATAW
                    MOV A,#'I'              ;data end
                    LCALL DATAW
    AGAIN:          SJMP AGAIN               ;endless loop
    COM:            MOV P1,A                         ;command write sequence
                    CLR P3.7
                    CLR P3.5
                    SETB P3.4
                    CLR P3.4
                    ;LCALL DELAY
                    RET
    DATAW:          MOV P1,A                        ;data write sequence
                    SETB P3.7
                    CLR P3.5
                    SETB P3.4
                    CLR P3.4
                    ;LCALL DELAY
                    RET
    DELAY:          MOV R6,#50              ;simple delay routine
    HERE2:          MOV R7,#255             ;for 0.0124S or 124MS
    HERE:           DJNZ R7,HERE
                    DJNZ R6,HERE2
                    RET
                    END
    
    

Children
  • Hint for initialization - first parameter for DspPutc is the RS signal level:

             DspPutc(0, 0x38); /* FUNCTION_SET - 8-bit interface; 2-line display; 5x7 dots */
             DspPutc(0, 0x0C); /* DISPLAY_MODE - Display ON; Cursor OFF; Blinking OFF */
             DspPutc(0, 0x01); /* DSP_CLR_MODE - Clear display */
             LCD_Wait(1640);   /* wait 1.6 msecs */
             DspPutc(0, 0x06); /* ENTRY_MODE   - Cursor Increments; Display not shifted */
    

    This came fram the display data sheet flow chart and operational table. Check the waveform timing for approxiate delays.

    Why 'C'. Its portable. To port this code, only DspPutc needs to be modified for the I/O pins.

    The above code is only small portion from an Ioctl function that I wrote.

  • Why 'C'. Its portable

    in this case it is not
    1) how does C 'port' to some processor with no p1, no quasi-bidirectionals.
    2) you can not make a 'portable' delay routine in C
    3) C is quite 'portable' in many respoects, but there is no way in hades you can make any I/O function 'portable' between processors whatever language you use.

    Erik

  • There's always code that needs to be changed between processors. The I/O layer. In the Display case, the I/O is in the DspPutc function. In this function, the code can be changed to access the LCD using an 8 or 4 bit bus or by serial means if the LCD supports that mode.

  • you said: Why 'C'. Its portable.
    now you say ... needs to be changed ... be changed to ... or by .. if ... supports

    some portability.

    this is NOT an argument aginst using C (I do it extensively) but the "portability" is very limited in small embedded. In small embedded the ease of coding is the important factor, the likelyhood that a project ever will be moved to another processor family is virtually zero. So, if it works in assembler, let sleeping dogs lie.

    Erik

  • erik malund said: "this is NOT an argument aginst using C (I do it extensively) but the "portability" is very limited in small embedded."

    I agree with erik. In C, often the compiler choices, memory layout and linker scripts are so different from a processor to the next, that major redesign is inevitable.

    For example, writing precise timing loops in C is often a waste of time, because you simply can't control the machine code generated from the C source. A simple change in compiler optimization level can wreck you timings.

    Especially when you need to push the performance, you tend to write a C style that matches the particular processor you target. There are always specific ways to write loops, logic sequences, expressions, function prototypes that match more closely a given processor.

    An embedded programmer that is conscious of these styles will write faster and smaller C code, often deviant from ANSI. When you are struggling to fit a 80KB code in a 64KB processor flash, that's a go/no_go issue.

    "So, if it works in assembler, let sleeping dogs lie"

    Absolutely. I have seen C code that is virtually unrecognizable. As a matter of fact, the assembly portions of the large systems we work with are generally much better documented and maintainable, because they were usually written by a careful coder.

    Almost all large systems we produce have the lower lib layer written in hand-optimized assembly for the target processor core.

  • "writing precise timing loops in C is often a waste of time"

    Rather than "often", I'd say "always" - certainly for precise timing:

    "because you simply can't control the machine code generated from the C source."

    Absolutely - because you can never control it, it is always a waste of time!

    "A simple change in compiler optimization level can wreck you timings"

    Even without changing optimisation; eg, if the compiler happens to be using a register in your delay, then you add some "unrelated" code and the compiler happens to use the register for this and therefore something else in your loop...

  • An embedded programmer that is conscious of these styles

    if he is not, he has no right to call himself an embedded programmer

    Erik

  • Andy Neil wrote: "NEVER write precise timing loops in a HLL"

    erik malund wrote: "... he has no right to call himself an embedded programmer"

    To whom I fully agree. Maybe I should have made stronger remarks on my comments.

    It is so tiresome the pointless ancient discussion of C versus ASM.

    Real development in C always require you to implement base functions and critical portions using non-portable and/or low-level.

    Even when using C++, I use to implement many methods of the base classes in assembly.