I'm trying to program a simple traffic light control using a 8051 micro-controller and assembly language. I use the Multisim application for simulation purposes.
I'm having a problem with the timers. I want the red and green lights to be on for 10 seconds and the yellow ones for 2 seconds. In simulation mode they seem to change faster and appear to blink (they are on then off during the counter and on again when the situation changes). Any suggestion?

$MOD51	; instructions for assembler

		; variables
		ARED	equ	P1.0
		AYEL	equ	P1.1
		AGRE	equ	P1.2
		BRED	equ	P1.3
		BYEL	equ	P1.4
		BGRE	equ	P1.5

		ORG	0000H
		LJMP	BEGGIN
		ORG	0030H

BEGGIN:
		LCALL	CLEARALL
		SJMP	MAIN

MAIN:
		LCALL	SIT1
		LCALL	SIT3
		LCALL	SIT2
		LCALL	SIT4
		SJMP	MAIN

; the four possible situations
SIT1:
		SETB	ARED
		SETB	BGRE
		MOV	R0, #0AH		; 10 seconds
		LCALL	WAIT
		LCALL	CLEARALL
		RET

SIT2:
		SETB	AGRE
		SETB	BRED
		MOV	R0, #0AH		; 10 seconds
		LCALL	WAIT
		LCALL	CLEARALL
		RET

SIT3:
		SETB	ARED
		SETB	BYEL
		MOV	R0, #02H		; 2 seconds
		LCALL	WAIT
		LCALL	CLEARALL
		RET

SIT4:
		SETB	AYEL
		SETB	BRED
		MOV	R0, #02H		; 2 seconds
		LCALL	WAIT
		LCALL	CLEARALL
		RET

; counters
WAIT:
		LCALL	ONESEC			; determines 1 second
		DJNZ	R0, WAIT		; repetes R0 times
		RET

ONESEC:
		MOV	R1, #14H		; determines 1 second

CLEARALL:
		MOV	P1, #00H		; clears P1
		CLR	A			; clears ACC
		RET

END

Why does ONESEC fall through to CLEARALL ?

I forgot to check that. Should I use a RET?

Should it be a cycle like the one I used for WAIT? I'm using for references an example that comes with Multisim, it used R1 and the hexadecimal value for 20, maybe I missed out some lines.

I'm using this now:

(...)

ONESEC:
		MOV		R1, #14H	

ONESEC2:
		MOV	TH0, #00H
		MOV	TL0, #00H
		CLR	TF0
		SETB	TF0
		JNB	TF0, $
		CLR	TF0
		DJNZ	R1, UMSEG2
		RET

(...)

And I got it working, thank you.

This question has already been answered. Start a new discussion instead.