1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

adding all digits in a number, MCU 8051

Discussion in '8051/8951' started by PG1995, Mar 31, 2012.

  1. PG1995

    PG1995 Active Member

    Joined:
    Apr 18, 2011
    Messages:
    1,645
    Likes:
    13
    Hi

    I want to add every digit in this number 457-85-9999-1, i.e. 4+5+7+8+.... I'm new to assembly language and using MCU 8051.

    One way to do it is given below. How else can I do it efficiently and using few lines without making it complex for myself? Please help me with it. Thank you.

    Code (text):

    ;add all digits of the number 457-85-9999-1

    ORG 0H

        Repeat:
        CLR A
        ADD A, #4
        ADD A, #5
        ADD A, #7
        ADD A, #8
        ADD A, #5
        ADD A, #9
        ADD A, #9
        ADD A, #9
        ADD A, #9
        ADD A, #1
        SJMP Repeat

    END
     
    Regards
    PG
     
  2. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,170
    Likes:
    910
    Location:
    Rochdale UK
  3. Jon Wilder

    Jon Wilder Active Member

    Joined:
    Oct 22, 2010
    Messages:
    859
    Likes:
    82
    Location:
    Fresno, CA
    A really good site I recommend to anyone wishing to learn the MCS-51 family is http://www.8052.com

    This site was what got me started with the MCS-51 family. I started embedded electronics and assembly language programming with the 16F series of PIC microcontrollers a year and a half ago (knowing nothing about digital electronics or any sort of programming), then took on learning the MCS-51 family last summer. I just finished up writing my first MCS-51 code that I started back in February and it's working 100% bug free now.

    Despite the haters who hate on it for no other reason than its age, the MCS-51 family is a very fun family to code in assembly. I enjoy coding it over the PIC to be honest. But I use both processors in different types of applications, with my favorite PIC being the 16F88/F886/F887. For MCS-51 stuff I use Atmel's AT89S series and am currently working with the AT89S8253.
     
    Last edited: Mar 31, 2012
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. Jon Wilder

    Jon Wilder Active Member

    Joined:
    Oct 22, 2010
    Messages:
    859
    Likes:
    82
    Location:
    Fresno, CA

    You can also preload these values into RAM registers, then set up a loop that adds them via indirect addressing. With indirect addressing you can set the add loop as a subroutine, then change the values loaded in the registers in main code, init the counter and call the subroutine to add any combination of digits, making the whole thing configurable in main code -

    Code (text):

    DigitLoad:  mov     0x30,#4         ;load digits into RAM
            mov     0x31,#5
            mov     0x32,#7
            mov     0x33,#8
            mov     0x34,#5
            mov     0x35,#9
            mov     0x36,#9
            mov     0x37,#9
            mov     0x38,#9
            mov     0x39,#1

            mov     R1,#0x0A        ;set counter for 10 digits
            acall       AddDigit

            ;continue with main code

           

    AddDigit:   push        ACC         ;store accumulator
            push        R0          ;store R0
            mov     R0,#0x30        ;set starting RAM address
            mov     A,#0            ;clear accumulator
    AddLoop:    add     A,@R0           ;add digit
            inc     R0          ;increment digit address
            djnz        R1,AddLoop      ;decrement digit counter, continue adding if counter > 0
            pop     R0          ;restore R0
            pop     ACC         ;restore accumulator
            ret
     
    When using this method, make sure you load the first digit into RAM location 0x30, then follow them with each digit in sequence as shown above.

    Notice I also use the stack to my advantage to back up the registers that will be used in the subroutine, then restore them on subroutine exit. This is a very good programming habit to get into.
     
    Last edited: Mar 31, 2012
  6. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,170
    Likes:
    910
    Location:
    Rochdale UK
    Jon.. In my hayday, I went to Portsmouth University to visit Frederick Cowan, David Callcot and Hassan Parchizadeh the three authors of "8051 Microcontrollers"

    I spent a great day with them discussing the book... I came away with oodles of goodies... SBC's, Development kits and tons of literature. I was a tiny bit responsible for the second edition.. Hassan, whom wrote the C portions of the book, had minor mistakes and we sat down and corrected the parts that needed correcting. I treated them to a dinner. This was my first experience of 3D printing as they had one of the first.. It printed wax or wood.. The wood was liquid and came out with a kind of veneer finish.

    I totally love it... Right in the heart of phillips development.... (Portsmouth was an excellence center for Phillip's micro's)
     
  7. PG1995

    PG1995 Active Member

    Joined:
    Apr 18, 2011
    Messages:
    1,645
    Likes:
    13
    Thank you very much, once again, Rogers, Jon. You guys are really helpful and nice too!

    Just wanted to confirm: I don't think assembly language for 8051 is case sensitive, is it? Is it true of every other assembly language? Please let me know.

    @Rogers: You were right about MCU 8051 IDE. It is a great simple tool for beginners like me. Though I have Keil installed too but I like it more. Thanks for the recommendation.

    Best wishes
    PG
     
    Last edited: Mar 31, 2012
  8. Jon Wilder

    Jon Wilder Active Member

    Joined:
    Oct 22, 2010
    Messages:
    859
    Likes:
    82
    Location:
    Fresno, CA
    The labels you use are case sensitive yes. I think the built in assembler in MCU8051IDE is a bit forgiving with that.

    I always tend to type instructions in lower case and constant labels in upper case. For line labels and subroutine names I capitalize the first letter of every word. That's just my personal naming convention.
     
  9. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,170
    Likes:
    910
    Location:
    Rochdale UK
    PG.. I use asem51 with protues aswell.... There are many options for these little devices... If you download VSM studio (if you have proteus) you can debug with ISIS....
     
  10. PG1995

    PG1995 Active Member

    Joined:
    Apr 18, 2011
    Messages:
    1,645
    Likes:
    13
    Thank you, Jon, Rogers.

    @Rogers: I have Proteus ISIS installed along with Keil uVision and MCU 8051 IDE. I have also downloaded VSM Studio but I think I would stick with MCU 8051 IDE because as a beginner it seems simple to me. But thanks for telling me about the VSM.

    Best regards
    PG
     
  11. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,170
    Likes:
    910
    Location:
    Rochdale UK
    I must admit... Its very good!! The more I play with it, the more it seems to do..... If you ever start messing with C.. You can add the compilers directly to it.

    Have fun.
     
  12. PG1995

    PG1995 Active Member

    Joined:
    Apr 18, 2011
    Messages:
    1,645
    Likes:
    13
    Hi

    Could you please help me with interfacing LCD display in MCU 8051 IDE?

    First I need to change the code below so that "AMERICA" is sent to port 0 which is connected to a LCD.

    Please help me. Thanks.

    Regards
    PG

    Code (text):

    ORG 0000
                MOV     DPTR,#MYDATA   
            MOV     R0,#40H        
            MOV     R2,#7      
      BACK: CLR     A              
             MOVC   A,@A+DPTR      
            MOV @R0,A          
            INC DPTR        
            INC R0             
            DJNZ    R2,BACK        
      HERE:     SJMP    HERE
     
            ORG     250H
      MYDATA:   DB  "AMERICA"
            END
     
     
  13. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,170
    Likes:
    910
    Location:
    Rochdale UK
    Code (text):

    ; Lcd 16x2 display
    ;P3.2 = RS... P3.3 = R/W... P3.4 = E


        org 0
        sjmp    Start
        org 20h
       
    Start: 
        clr P3.3
        mov a.#38h      ; function set 8 bits 2 rows 5x7 font
        acall   lcd_cmd
        mov a.#0Eh      ; screen on..cursor on.. no blink
        acall   lcd_cmd
        mov a.#06h      ; R/L cursor
        acall   lcd_cmd
        mov a.#01h      ; clear and home
        acall   lcd_cmd
       
        mov DPTR, #msg  ; point at message
        acall   lcd_print   ; send it to display
       
    fin:   
        sjmp    fin
       
    lcd_print:
        mov a,#0h       ; start of msg
        movc    a,@a+DPTR   ; set data pointer
        cjne    a,#0h, mod1 ; wait for null
        ret
    mod1:
        acall   lcd_data    ; send char to screen
        inc DPTR        ; get next char
        sjmp    lcd_print   ; again
       
    msg1:  
        db  "AMERICA",0 ; message
       
    lcd_data
        mov P1,#0FFh    ; make input
        setb    P3.3        ; R/W = Read
        clr P3.2        ; RS = command
    waitd:
        clr P3.4        ; E low
        setb    P3.4        ; E high
        jb  P1.7,waitd  ; get busy flag
        clr P3.4        ; E low
        clr P3.3        ; R/W write
        setb    P3.2        ; RS data
        mov P1,a        ; put data on LCD port
        setb    P3.4        ; E high
        clr P3.4        ; E low
        ret
       
    lcd_cmd
        mov P1,#0FFh    ; make input
        setb    P3.3        ; R/W = Read   
        clr P3.2        ; RS = command
    waitc:
        clr P3.4        ; E low
        setb    P3.4        ; E high
        jb  P1.7,waitc
        clr P3.4        ; E low
        clr P3.3        ; R/W write
        clr P3.2        ; RS command
        mov P1,a        ; put command on LCD port
        setb    P3.4        ; E high
        clr P3.4        ; E low
        ret
       
        end
     
    This is a simple program to write to port 1 (8 bit ) with control on port 3 its easy to change ports..
     
  14. Jon Wilder

    Jon Wilder Active Member

    Joined:
    Oct 22, 2010
    Messages:
    859
    Likes:
    82
    Location:
    Fresno, CA
    Can you tell us the make and model of the exact display you're using? Please help me help you. Thanks. ;)
     
  15. PG1995

    PG1995 Active Member

    Joined:
    Apr 18, 2011
    Messages:
    1,645
    Likes:
    13
    Hi Jon

    I'm using this software, MCU IDE 8051, recommended by Rogers. Though, I also have Keil uVision. It was a virtual, probably generic, LCD. Please see the attachments. I don't think I would be able to interface it because what Rogers posted in the last post just was over my head!

    Regards
    PG
     
    Last edited: Apr 22, 2012
  16. Jon Wilder

    Jon Wilder Active Member

    Joined:
    Oct 22, 2010
    Messages:
    859
    Likes:
    82
    Location:
    Fresno, CA
    The LCD has an 8 bit data port. This data port has pins DB0-DB7. You pick a port on the MCU to drive this 8 bit data port with and the MCU's port pins will connect to their corresponding pins on the LCD data port.

    Example, let's say you decide to use Port 1 on the MCU for the LCD data port. You would connect lines DB0-DB7 on the LCD module to Port 1 on the MCU as follows -

    DB0 - MCU Port 1 Bit 0 (P1.0)
    DB1 - MCU Port 1 Bit 1 (P1.1)
    DB2 - MCU Port 1 Bit 2 (P1.2)
    DB3 - MCU Port 1 Bit 3 (P1.3)
    DB4 - MCU Port 1 Bit 4 (P1.4)
    DB5 - MCU Port 1 Bit 5 (P1.5)
    DB6 - MCU Port 1 Bit 6 (P1.6)
    DB7 - MCU Port 1 Bit 7 (P1.7)

    Then you would decide what port lines on either ports 2, 3 or 4 to use for driving the E (Enable), RS (Register Select) and R/W (Read/Write) lines on the LCD module. To send data to the LCD, you would write the data to register P1 on the MCU and set the RS, R/W and E lines accordingly.
     
  17. PG1995

    PG1995 Active Member

    Joined:
    Apr 18, 2011
    Messages:
    1,645
    Likes:
    13
    Thank you, Jon.

    Though Rogers gave me the code in his last post, I wasn't able to understand it as I pointed out in my last posting. Forget about the LCD interfacing. Could you please help me to edit this code in a way that the word AMERICA is sent to the port 1? I think sending the complete word at one time would make things difficult so it sends one letter of word AMERICA to port 1 at a time with a delay of 200ms between sending each letter and a delay of 400ms between start of each sending cycle. This is what I'm trying to say. At first letter "A" is sent to port 1, then there is a delay of 200ms, then "M" is sent,..., now "C" is sent, 200ms delay, and now at last last "A" is sent. One cycle of sending the word is complete. Now there is a delay of 400ms and after that cycle restarts.

    Code (text):

    ORG 0000
                MOV     DPTR,#MYDATA   
            MOV     R0,#40H        
            MOV     R2,#7      
      BACK: CLR     A              
             MOVC   A,@A+DPTR      
            MOV @R0,A          
            INC DPTR        
            INC R0             
            DJNZ    R2,BACK        
      HERE:     SJMP    HERE
     
            ORG     250H
      MYDATA:   DB  "AMERICA"
            END
     
     
  18. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,170
    Likes:
    910
    Location:
    Rochdale UK
    That's is what all lcd code does.... Notice the routine in the code I posted

    lcd_print It is very similar to your original code... It has the msg pointer placed in the DPTR.. and fetches one byte at a time

    Code (text):

    lcd_print:
        mov a,#0h       ; start of msg
        movc    a,@a+DPTR   ; set data pointer
        cjne    a,#0h, mod1 ; wait for null
        ret
    mod1:
        acall   lcd_data    ; send char to screen
        inc DPTR        ; get next char
        sjmp    lcd_print   ; again
     
    You need to open the lcd port only when the command bits are correct.. This is why we write lcd_data and lcd_cmd routines

    All these routines do is wait for the module to be ready!!! then place the data or command on P1...

    You can't just put data on P0 or P1 without controlling the LCD module... The module has its own processor on board (even virtual ones)
     
    Last edited: Apr 23, 2012
  19. PG1995

    PG1995 Active Member

    Joined:
    Apr 18, 2011
    Messages:
    1,645
    Likes:
    13
    Thank you, Rogers.

    I have tried to assemble the quoted code above in MCU 8051 IDE and several errors were repoted. Could you make any sense out them? Thank you for the help.

    Code (text):

    Compiling file: rogersLCD.asm
    Initializing pre-processor ...
    Syntax error at 11 in rogersLCD.asm: Too few operands, mov must take exactly 2 operands
    Syntax error at 13 in rogersLCD.asm: Too few operands, mov must take exactly 2 operands
    Syntax error at 15 in rogersLCD.asm: Too few operands, mov must take exactly 2 operands
    Syntax error at 17 in rogersLCD.asm: Too few operands, mov must take exactly 2 operands
    Syntax error at 12 in rogersLCD.asm: Symbol not defined: lcd_cmd
    Syntax error at 14 in rogersLCD.asm: Symbol not defined: lcd_cmd
    Syntax error at 16 in rogersLCD.asm: Symbol not defined: lcd_cmd
    Syntax error at 18 in rogersLCD.asm: Symbol not defined: lcd_cmd
    Syntax error at 20 in rogersLCD.asm: Symbol not defined: msg
    Syntax error at 32 in rogersLCD.asm: Symbol not defined: lcd_data
    Syntax error at 37 in rogersLCD.asm: Invalid expression: `"AMERICA"'
    Syntax error at 39 in rogersLCD.asm: Unknown keyword: `lcd_data'
        `lcd_data' is neither macro nor instruction nor directive
    Syntax error at 55 in rogersLCD.asm: Unknown keyword: `lcd_cmd'
        `lcd_cmd' is neither macro nor instruction nor directive
    Pre-processing FAILED !
    Creating code listing file ...      -> "rogersLCD.lst"
    13 errors, 0 warnings
     
     
    Last edited: Apr 23, 2012
  20. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,170
    Likes:
    910
    Location:
    Rochdale UK
    Sorry mate..... I did copy it over quickly

    Code (text):

    ; Lcd 16x2 display
    ;P3.2 = RS... P3.3 = R/W... P3.4 = E
     
     
        org 0
        sjmp    Start
        org 20h
     
    Start: 
        clr P3.3
        mov a,#38h      ; function set 8 bits 2 rows 5x7 font
        acall   lcd_cmd
        mov a,#0Eh      ; screen on..cursor on.. no blink
        acall   lcd_cmd
        mov a,#06h      ; R/L cursor
        acall   lcd_cmd
        mov a,#01h      ; clear and home
        acall   lcd_cmd
     
        mov DPTR, #msg1 ; point at message
        acall   lcd_print   ; send it to display
     
    fin:   
        sjmp    fin
     
    lcd_print:
        mov a,#0h       ; start of msg
        movc    a,@a+DPTR   ; set data pointer
        cjne    a,#0h, mod1 ; wait for null
        ret
    mod1:
        acall   lcd_data    ; send char to screen
        inc DPTR        ; get next char
        sjmp    lcd_print   ; again
     
    msg1:  
        db  'AMERICA',0 ; message
     
    lcd_data:
        mov P1,#0FFh    ; make input
        setb    P3.3        ; R/W = Read
        clr P3.2        ; RS = command
    waitd:
        clr P3.4        ; E low
        setb    P3.4        ; E high
        jb  P1.7,waitd  ; get busy flag
        clr P3.4        ; E low
        clr P3.3        ; R/W write
        setb    P3.2        ; RS data
        mov P1,a        ; put data on LCD port
        setb    P3.4        ; E high
        clr P3.4        ; E low
        ret
     
    lcd_cmd:
        mov P1,#0FFh    ; make input
        setb    P3.3        ; R/W = Read   
        clr P3.2        ; RS = command
    waitc:
        clr P3.4        ; E low
        setb    P3.4        ; E high
        jb  P1.7,waitc
        clr P3.4        ; E low
        clr P3.3        ; R/W write
        clr P3.2        ; RS command
        mov P1,a        ; put command on LCD port
        setb    P3.4        ; E high
        clr P3.4        ; E low
        ret
     
        end
     
    'll need to look into the "AMERICA" error... It seems fine....Ah single quotes not double...
     
    Last edited: Apr 23, 2012
  21. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,170
    Likes:
    910
    Location:
    Rochdale UK
    I've tested this in the real world and it works ok...But it wont work on the simulator.... It wont read the busy flag... You may want to put a delay in instead of polling the busy...
     

Share This Page