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
    Thank you, KISS.

    Could someone please help me with the queries included in the attachment? Thank you.

    Regards
    PG
     
  2. Jon Wilder

    Jon Wilder Active Member

    Joined:
    Oct 22, 2010
    Messages:
    859
    Likes:
    82
    Location:
    Fresno, CA
    Vpp is the required 12V programming voltage when the main code is being written to the chip by the parallel programmer. The programming hardware supplies this voltage.

    The PROG in "ALE/PROG" is the pin that the programming hardware sends the clocking pulse to during the programming phase when programming the chip. When the program data is placed onto the data pins (P0), a pulse is sent to the chip to tell the chip when to read the data present on the P0 pins and store it into the chip's internal code memory.

    This is all stuff that is used by a parallel programmer only. If you're using an ISP programmer such as the AT89ISP cable, these signals are not needed (ISP stands for In System Programming).

    "EA" stands for "External Access". It is an active low pin that tells the chip whether to execute code in its internal memory or from an external EPROM. In normal use, EA/VPP gets tied to Vdd when using the chip's internal code space. When EA is high, the chip will execute code from its internal memory. Any code memory addresses past the internal code memory address range will address external code memory. This allows you to use the chip's internal code memory with additional code memory residing off chip up to a total of 64K.

    Example...if your chip has 12K of code space on chip and EA is tied to Vdd, you can have the 12K of internal code memory with an additional 52K of external code memory. Addresses 0x0000-0x2FFF will access the on chip memory while addresses 0x3000-0xFFFF will accesses external code memory.

    If all code execution is to take place from an external EPROM, EA should be tied to Vss instead.
     
    Last edited: May 30, 2012
  3. PG1995

    PG1995 Active Member

    Joined:
    Apr 18, 2011
    Messages:
    1,645
    Likes:
    13
    Thank you very much, Jon. I understand it now.

    Regards
    PG
     
  4. dave

    Dave New Member

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


     
  5. PG1995

    PG1995 Active Member

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

    Hi

    Could you please help me with the queries below? It would be really nice of you.

    You could find Q1 here, Q2 here, and Q2, Q3, Q4, and Q5 here.

    Please help me. Thank you.

    Regards
    PG
     
    Last edited: May 30, 2012
  6. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    910
    Location:
    Rochdale UK
    Q1.... There is frequency being produced on P1.7... This will emit a sound on a siren.
    Q2.... We've been here before... You MUST make a pin an input BEFORE you read it.... Writing a 1 to the port makes it an input.
    Q3,Q5 Try not to think of it as a latch......If you want to "output the port" you just do.... If you need to "input a port" you just need to prevent contention by writing a 1 to it..

    ***The latch controls a FET.... If you write a 1 the FET is off..... No contention!!! If you write a 0 the FET is on... Ground is on the pin...If you read a 1 on the port in this condition

    MELTDOWN...
     
  7. Jon Wilder

    Jon Wilder Active Member

    Joined:
    Oct 22, 2010
    Messages:
    859
    Likes:
    82
    Location:
    Fresno, CA
    Q3: If there is one thing I cannot stand about 8051 books, it is the incorrect explaining of the port operations.

    The first thing that needs to be cleared up...THERE IS NO "INPUT MODE" AND "OUTPUT MODE"! 8051 ports are NOT to be thought of in this fashion. This is what messes most people up when dealing with 8051 I/O ports. They ARE NOT a tri-state port like a PIC micro has. They don't have a tristate register that allows you to turn off the pin output drivers. The weak internal pull up driver is ALWAYS on. Only the pull down driver gets turned on/off when writing to the port. 0 turns on the pull down driver, pulling the pin low. 1 turns the pull down driver off, which allows the pull up driver to pull the pin high. Again it IS NOT a "push-pull" style output driver. This is the reason why they cannot source nearly as much current as they can sink.

    OK...the ports on an 8051 are bi-state quasi-bidirectional. Let's look at what these two terms mean -

    Bi-State: The pins on the port can only be in 1 of 2 possible states...HIGH or LOW. This differs from more modern microcontrollers (such as the PIC microcontroller) that feature tri-state ports. On tri-state ports, the pins can either be HIGH, LOW, or HI-IMPEDANCE (all output drivers off). On the traditional 8051 however, the weak pullup drivers are always active so the hi-impedance state is not available, making it a bi-state port.

    Port 0 is a bit different. When it is being used as a standard I/O port, it does not have any internal pull up because it is an open drain design. So the two states available on port 0 are HI-IMPEDANCE and LOW. When used as the low order address/data port, its internal pull ups are active, making it a HIGH/LOW bi-state port.

    Quasi-Bidirectional: This means that the port functions as BOTH input AND output when the pins are internally pulled high by writing 1's to the port latch. However, when 0's are written to the port latch, the port pins function as output only. When a 1 is written to a pin, the pin is placed in a high state and can be externally pulled low by some external hardware. If a pin has a 1 written to it and something external is pulling the pin low, reading this pin will return a 0, NOT the 1 that was written to the pin in the latch.

    When a 0 is written to a pin, the pin is placed in a low state. A pin CANNOT be externally pulled high when it is internally pulled low. This is why it only functions as an output when a 0 is written to it.

    Let's review -

    Port pins which contain a 1 in the port latch function as BOTH and input AND and output

    Port pins which contain a 0 in the port latch function as output only

    Any instructions which WRITE to the port write to the port latch. Any instructions which READ the port read the data present on the port pins themselves.

    Q4: Write instructions modify the value in the port latch. "mov P1,#44" is a write instruction. After executing this instruction, the port latch will contain the value of 44.
    Keep in mind that you CANNOT read the contents of the latch. You can only read the contents of the port itself. Reading the port contents returns the high/low states of the port pins themselves...NOT the contents of the latch.

    Q5: ALE has NOTHING to do with the port latch. ALE is for an external latch IC that is used to demultiplex the low order address byte from the data byte on port 0 when accessing external memory only. Again, THIS PIN IS ONLY USED WHEN ACCESSING EXTERNAL MEMORY!

    The port latch is used ONLY when writing a value to a port. Reading a port ONLY reads the port pins themselves...NOT THE LATCH.

    I'll give you an example. Let's say we execute "mov P1,#0xFF". The latch will contain the value of 0xFF, or 11111111. If nothing is externally pulling any port 1 pins low, all of port 1's pins will be high.

    However, let's say we use a switch to drive pin P1.5 low. Then we read port 1 by executing "mov A,P1". The accumulator will contain the value of 11011111 even though the latch contains 11111111. This is because pin 5 of port 1 is being pulled low by a switch. Since reading the port returns the high/low state of the port's pins, reading the port returned the value of 0 on pin 5 because of this.
     
    Last edited: May 30, 2012
  8. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    910
    Location:
    Rochdale UK
    Yeah.... Like Jon said.....
     
  9. PG1995

    PG1995 Active Member

    Joined:
    Apr 18, 2011
    Messages:
    1,645
    Likes:
    13
    Thank you very much, Rogers, Jon. Very kind of you.

    Is my calculation of extra delay which is mostly ignored is correct? Please let me know. I have calculated it for AT89C51 using 12 MHz frequency XTAL. Thanks

    Code (text):

    ;-------Delay Subroutine

    ;period of one MC = 0.001 ms
    ;75(50(255x2x0.001)) = 1912.5 ms = 2 s

        org 0x300

        Delay:
            mov R0, #75     ;1 MC
        L1: mov R1, #50
        L2: mov R2, #255
        L3: DJNZ R2, L3     ;2 MC
            DJNZ R1, L2
            DJNZ R0, L1
            RET         ;2 MC

    end

    ;please notice that we have ignored extra delay corresponding to some instructions in the Delay
    ;subroutine and this extra delay is: {50(1+2) + 75(1+2) + 2} x 0.001 = 0.377 ms = 0.000377 s
     
     
  10. PG1995

    PG1995 Active Member

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

    Do you think that the code below is correct? I'm confused because the code given in the book is quite different. Please help me. Thank you.

    Code (text):

    ;Assume that bit P2.3 is an input and represents the condition of an oven. If it goes HIGH, it means that
    ;the oven is hot. Monitor the bit continuously. Whenever it goes HIGH, send a low-to-high pulse to
    ;pin P1.5 to turn on the buzzer.

    ORG 0H

            OVEN BIT P2.3
            SETB OVEN   ;to make the pin an input

            BUZZER BIT P1.5

         REPEAT:    JB OVEN, BUZ
                SJMP REPEAT

         BUZ:   CLR BUZZER
                SETB BUZZER

                SJMP REPEAT

    END
     
     
  11. Jon Wilder

    Jon Wilder Active Member

    Joined:
    Oct 22, 2010
    Messages:
    859
    Likes:
    82
    Location:
    Fresno, CA
    First we need to talk about proper assembly code format.

    Assembly code follows a very simple syntax. You have 3 columns -

    Code (text):

    <LABEL>         <INSTRUCTION>       <OPERAND>
     
    Label - Labels are optional and provide a means to give a line of code a "name" to refer to when using jump and call instructions without having to know the physical address that the line of code resides in.

    Instruction - This is the instruction itself

    Operand - This is what the instruction is being performed on and the values for the instruction to use. Also known as "arguments".

    When you're doing equates tables (i.e. EQU, DATA, IDATA, BIT, etc etc), the label goes in the label column, the EQU/BIT/DATA/IDATA/etc goes in the instruction column while the value it's being equated to goes in the operand column. For example -

    Code (text):

    OVEN            BIT         P2.3
     
    Equates tables do not go in the code. You place them BEFORE the first org instruction. Your code should appear as such -

    Code (text):


    ;equates table

    OVEN            BIT         P2.3
    BUZZER          BIT         P1.5

    ;start main code

                org         0x0000      ;reset vector

                setb            OVEN        ;P2.3 high

    Repeat:         jnb         OVEN,Repeat ;continuously poll P2.3 until P2.3 is high
                acall           Delay       ;run delay
                cpl         BUZZER      ;switch P1.5 to opposite state
                acall           Delay       ;run delay
                ajmp            Repeat      ;loop forever

    Delay:          mov         R0,#0xFF
                mov         R1,#0xFF
    DelayCount:     djnz            R0,DelayCount
                djnz            R1,DelayCount
                ret

                end
     
    For the buzzer to continuously sound you have to continuously compliment bit P1.5 at an audible frequency, which will require a delay loop before and after each compliment of the pin. Otherwise it will switch the pin at a frequency that is too high for the human ear to hear it.

    Let's look at what the code is doing. The first instruction says to continuously jump to itself if bit P2.3 is not set. The program counter will continuously jump to that line of code if the sensor is holding pin P2.3 low. As soon as the oven gets hot, the sensor will drive pin P2.3 high, causing it to jump out of the continuous loop.

    Once out of the continuous polling loop, the next instruction calls a delay loop. After returning from the delay loop, the next instruction states to compliment bit P1.5 (compliment means to switch the bit to the opposite state). After complimenting bit P1.5, it calls the delay loop again, then returns and jumps back to the first line that continuously polls bit P2.3 if the sensor is holding P2.3 low.

    The buzzer will continuously sound until P2.3 is driven low again by the sensor.
     
    Last edited: Jun 17, 2012
  12. PG1995

    PG1995 Active Member

    Joined:
    Apr 18, 2011
    Messages:
    1,645
    Likes:
    13
    Thanks a lot, Jon.

    In my humble view, whether the buzzer will sound or not once P2.3 is driven low entirely depends what was the state of the buzzer just before P2.3 went low. The complement operation is actually turning the buzzer on and off. Do you get my point? Please let me know if I'm correct. Thank you.

    Best wishes
    PG
     
  13. Jon Wilder

    Jon Wilder Active Member

    Joined:
    Oct 22, 2010
    Messages:
    859
    Likes:
    82
    Location:
    Fresno, CA
    No you are not correct.

    In order for the buzzer to sound, it must be cycled high and low continuously at a human audible frequency with a square wave. That is what the loop routine that continuously compliments P1.5 does with the delay calls and the "cpl" instruction. When P2.3 is set low again, pin P1.5 may remain in either the high or the low state, but it will not sound if it is left in either of those two states because pin P1.5 is outputting a continuous high or a continuous low (basically a DC signal) once P2.3 is set low.

    On a side note...can you please start a new thread each time you ask a new question that is not related to the original question? This thread has been filled with questions that are far from related to the original topic.
     
    Last edited: Jun 17, 2012
  14. PG1995

    PG1995 Active Member

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

    Yes, I understand that I should create a new thread and I will. But some time it's good to combine all the queries about a subject in one place. Besides in the last two months I have had good experience learning from you and Ian Rogers therefore making queries here would notify you that I need your help once again! Anyway, I will create a new thread.

    1:
    Doesn't a buzzer work on a DC signal? In my last post I had in mind that a buzzer worked on DC and that made me confused.

    2:
    What's wrong with the code below? It doesn't assemble. Both "-120" and "-2" aren't out of range because range for negative numbers is -1 to -128. Please help me with this.

    Code (text):

    ;Observe the following, noting the role of the OV flag

    ORG 0H

            MOV A, #-120
            MOV R4, #-2
            ADD A, R4

            SJMP $

    END
     
    Errors:
    Code (text):

    Compiling file: EXAMP_14.asm
    Initializing pre-processor ...
    Notice at 5 in EXAMP_14.asm: Overflow `-120' -> `65416'
    Syntax error at 5 in EXAMP_14.asm: Operand value out of range: `-120' (`65416')
    Notice at 6 in EXAMP_14.asm: Overflow `-2' -> `65534'
    Syntax error at 6 in EXAMP_14.asm: Operand value out of range: `-2' (`65534')
    Pre-processing FAILED !
    Creating code listing file ...      -> "EXAMP_14.lst"
    2 errors, 0 warnings
     
     
  15. ericgibbs

    ericgibbs Well-Known Member Most Helpful Member

    Joined:
    Jan 4, 2007
    Messages:
    21,187
    Likes:
    644
    Location:
    Ex Yorks' Hants UK
    hi PG,
    A buzzer or 'sounder will work with a DC voltage supply, I think Jon is confusing a buzzer with a piezo transducer which requires driving with a square wave voltage at the piezo transducer frequency.
     
    Last edited: Jun 18, 2012
  16. PG1995

    PG1995 Active Member

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

    Yes, I also think that a buzzer should work with DC. But we should wait for Jon's reply.

    Best wishes
    PG
     
  17. Jon Wilder

    Jon Wilder Active Member

    Joined:
    Oct 22, 2010
    Messages:
    859
    Likes:
    82
    Location:
    Fresno, CA
    Yes but these questions you're asking have nothing to do with "adding all digits in a number", which is the title of this thread. This is why I mentioned to start new threads for any and all questions which do not pertain to "adding all digits in a number". Ian and I constantly monitor this thread so we will see your new posts regardless.

    A self contained buzzer only needs a high or a low DC signal. If the code in your book were meant to work with a self contained buzzer, it would set bit P1.5 if P2.3 is high and clear P1.5 if P2.3 is low. But that's not how the code in the book is written. It is written to work with a piezo transducer, which requires a square wave at a human audible frequency in order to make the piezo element vibrate and create a sound. Continuously complimenting P1.5 as long as P2.3 is driven low by the sensor with the delay calls in between does exactly that...generates the needed square wave to make a piezo transducer work.

    Furthermore, even if you did have a self contained buzzer, the 8051 port pin cannot source current to it so you would have to use a transistor to switch the buzzer on/off and have the 8051 send the high/low signal to the transistor base.

    Assemblers don't deal with signed values (+/-). They only deal with unsigned values (+ only). The microcontroller does not have a floating point unit on it so the microcontroller itself can only deal with unsigned integers (i.e. positive only). In C language, you can use negative values via using signed variables because the compiler handles them via the use of the carry flag. But assemblers weren't really meant to deal with signed variables. Since the 8051 is an 8-bit processor and the accumulator is only 8 bits wide (along with all other RAM registers on an MCS-51), you can only load it with values between 0-255, or 0x00-0xFF in hex.
     
    Last edited: Jun 18, 2012
  18. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    910
    Location:
    Rochdale UK
    Jon's right!! I'm watching as well..... There is a hex conversion tool in MCU8051 -120 = 87H
     
  19. PG1995

    PG1995 Active Member

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

    So, does this mean that I can't do the code below in the assembler? Please let me know. Thanks.

    Code (text):

    ORG 0H
     
            MOV A, #-120
            MOV R4, #-2
            ADD A, R4
     
            SJMP $
     
    END
     
    PS: I see Rogers' post now. Yes, there is a calculator in MCU 8051 IDE. Do you want to do the conversion myself? Can't assembler handle the conversion by itself? Please let me know. Thanks.

    Regards
    PG
     
    Last edited: Jun 18, 2012
  20. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

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

    ORG 0H
     
            MOV A, #87h   ; is the same as -120
            MOV R4, #0FEh   ; is the same as -2
            ADD A, R4
     
            SJMP $
     
    END
     
    This is how you initiate negative numbers

    When you work with negative numbers, you must take care of the sign... ie if you TeST a number by checking the MSBit to check for negativity (is that a word ):D
     
  21. PG1995

    PG1995 Active Member

    Joined:
    Apr 18, 2011
    Messages:
    1,645
    Likes:
    13
    Thanks a lot, Rogers.

    1:
    So, this means I have to make conversions myself. Too bad! But I'm wondering that why the book give the code below when the 8051 can't do the conversion itself. The book should have at least mentioned it.

    Code (text):

    ORG 0H
     
            MOV A, #-120
            MOV R4, #-2
            ADD A, R4
     
            SJMP $
     
    END
     

    2:
    Could you please tell me why I'm getting the error? Apparently I can't see any error in the syntax for line which has #'s as a comment. Thank you.

    Code (text):

    ;Assume that P1 is an input port connected to a temperature sensor. Write a program to read
    ;the temperature and test it for the value 75. According to the test results, place the temperature
    ;value into the registers indicated by the following.

    ;       if T=75     then    A=75
    ;       if T<75     then    R1=T
    ;       if T>75     then    R2=T

    ORG 0H

            MOV P1, #0FFH
            MOV A, P1
            MOV R0, #75
            CJNE A, R0, UN_EQUAL  ;###############################################
            SJMP EXIT
       UN_EQUAL:    JC GREATER
            MOV R2, A
            SJMP EXIT
       GREATER: MOV R1, A
       EXIT:        NOP
       
            SJMP $

    END
     
    Error:
    Code (text):

    Compiling file: EXAMP_25.asm
    Initializing pre-processor ...
    Syntax error at 14 in EXAMP_25.asm: Invalid set of operands: cjne 224,R0,UN_EQUAL
    Pre-processing FAILED !
    Creating code listing file ...      -> "EXAMP_25.lst"
    1 error, 0 warnings
     
     
    Last edited: Jun 18, 2012

Share This Page