8051 time delays (PLEASE HELP ME)

[b][red]This message was edited by the sureshot3000 at 2002-4-11 4:51:56[/red][/b][hr]
just wondering if SOMEONE can help.i am looking for an assembler code that produces an exact 1 second time delay using an intel 8051 from the address org 8000.
also i am looking for a code using the same language and chip to control the sequence of a set of traffic lights with the following sequence

red red 4 seconds
red & amber red 2 seconds
green red 10 seconds
amber red 2 seconds
red red 4 seconds
red red & amber 2 seconds
red green 7 seconds
red amber 2 seconds

the interface between the lights and the 8051 require a logic 1 to turn the light on
thanks for any help


  • First of all: I cannot test this as I don't have a 8051 assembler (or even a 8051) by me. Use this solely as a pointer in some(!) direction.

    As for the first question, I'd advice you to use a timer instead... But if you want to do it the hardcoded way, you'll need to find out:
    - CPU Clock Frq / Cycle Frq.
    - Cycles per Instructions.

    Say that the frq is 8 MHZ. Then you'd need to make a loop that waited for 8000000 cycles (minus loop setup time).

    The function could look like this:
    WaitSeconds: // NumSeconds in a (Note: 0 means 65536!!)
    mov r2,#160 ; 12 cycles
    l3: mov r1,#200 ; 12 cycles
    l2: mov r0,#256 ; 12 cycles
    l1: djnz r0,l1 ; 24 cycles
    djnz r1,l2 ; 24 cycles
    djnz r2,l3 ; 24 cycles
    dec a ; 12 cycles
    jnz WaitSeconds ; 24 cycles

    So, the inner loop uses 24*256 = 6144 cycles
    together with the next loop : (6144+12)*100 = 615600 cycles
    together with the next loop : (615600+12)*13 = 8002956 cycles

    So, this will wait for 8002956/8000000=1,0004 seconds, or 1 second and 40 milliseconds. It's very hard to get closer than that.

    The bad thing about this approach is of course, that an upgrade of the CPU to a faster one will give you too short waiting times...

    : red red 4 seconds
    : red & amber red 2 seconds
    : green red 10 seconds
    : amber red 2 seconds
    : red red 4 seconds
    : red red & amber 2 seconds
    : red green 7 seconds
    : red amber 2 seconds

    You'd be better off by explaining it like this:
    Duration | Red | Amber | Green
    4 | X | |
    2 | X | X |
    10 | | | X
    2 | | X |
    4 | X | |
    2 | X | X |
    7 | | | X
    2 | | X |

    (This is my interpretation of your text)

    One could make a small table that consisted of "structs":
    BYTE Seconds;
    BYTE BitCode;

    Where bit code is simply the byte to write to the port (or external bus). I'm simply assuming that you're writing a byte to the LED at address 0x4000, where the three LSBs are bits for Red, Amber and Green.

    In ASM it would look like this:
    RED_BIT .equ 1
    AMBER_BIT .equ 2
    GREEN_BIT .equ 4
    LED_ADDRESS .equ 0x4000

    .db 4,RED_BIT
    .db 10,GREEN_BIT
    .db 2,AMBER_BIT
    .db 4,RED_BIT
    .db 7,GREEN_BIT
    .db 2,AMBER_BIT
    .db 0 ; End of table...

    We could then have a routine that expects dptr to point to a valid entry in the table:

    LEDOut: ; dptr pointing to valid entry (BYTE Seconds,BYTE BitCode)
    clr a
    movc a,@a+dptr ; Get Seconds
    mov r0,a ; Store Seconds in r0
    inc dptr
    clr a
    movc a,@a+dptr ; Get BitCode
    mov dptr,#LED_ADDRESS ; Setup Port Address
    movx @dptr,a ; Write Bit To Port
    mov a,r0 ; Restore Seconds
    lcall WaitSeconds

    And a function calling this routine:

    LEDSequence: ; Loops forever!!
    mov dptr,#LightTable ; Point to start of table
    loop: clr a
    movc a,@a+dptr ; Get First entry
    jz LEDSequence ; If 0, we've reached the end of the table, so restart...
    push dptr ; Save dptr
    lcall LEDOut
    pop lptr ; Restore dptr
    inc dptr ; Point
    inc dptr ; to next address in table
    sjmp loop ; Next address loop


  • Excellent reply - I have an 80C320 and could not have put it any better. But I would also agree that the built in timers are the way to go.
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!


In this Discussion