Q5Microprocessor
Question
Q.5. Write an assembly language program to perform traffic light control operation.
Answer
A traffic light control assembly program cycles the outputs of a microcontroller port (each bit driving a red/yellow/green lamp for two intersecting roads) through a predefined sequence of lamp-combination states, holding each state for an appropriate time delay (using a timer or software delay subroutine) before advancing to the next state in the cycle.
Problem setup: a simple two-road traffic light intersection requires controlling 6 lamps total (Red, Yellow, Green for Road A; Red, Yellow, Green for Road B), which can be conveniently mapped onto 6 bits of a single 8051 output port (e.g., P1.0-P1.5), with the remaining sequence logic implemented by writing the appropriate 6-bit lamp-pattern to the port for each phase of the traffic cycle, holding each pattern active for its required duration using a timer-based or software delay subroutine, before advancing to the next phase.
Typical sequence (4 phases in a basic cycle): (1) Road A Green + Road B Red (Road A traffic flows); (2) Road A Yellow + Road B Red (Road A traffic prepares to stop); (3) Road A Red + Road B Green (Road B traffic flows); (4) Road A Red + Road B Yellow (Road B traffic prepares to stop) — after which the cycle repeats back to phase 1, giving each road its turn to flow while the other remains stopped, with brief yellow transition phases in between to safely clear the intersection before switching the flowing direction.
; Assume P1.0=A-Red, P1.1=A-Yellow, P1.2=A-Green,
; P1.3=B-Red, P1.4=B-Yellow, P1.5=B-Green
START: MOV P1, #00H ; clear all lamps
SETB P1.2 ; Phase 1: A-Green ON
SETB P1.3 ; B-Red ON
ACALL LONGDELAY ; e.g., 10 seconds
MOV P1, #00H
SETB P1.1 ; A-Yellow ON
SETB P1.3 ; B-Red ON
ACALL SHORTDELAY ; e.g., 2 seconds
MOV P1, #00H
SETB P1.0 ; A-Red ON
SETB P1.5 ; B-Green ON
ACALL LONGDELAY
MOV P1, #00H
SETB P1.0 ; A-Red ON
SETB P1.4 ; B-Yellow ON
ACALL SHORTDELAY
SJMP START ; repeat the full cycle indefinitelyExplanation: the program cycles indefinitely (via the final SJMP back to START) through the four traffic-light phases described above; for each phase, it writes the appropriate combination of lamp bits to Port P1 (turning on exactly the lamps required for that phase and ensuring all others are off, typically by first clearing the whole port and then setting only the required bits, or by writing a complete pre-calculated bit pattern for that phase in a single MOV instruction), then calls an appropriate delay subroutine — a longer delay (LONGDELAY) for the main Green phases (allowing substantial traffic flow time) and a shorter delay (SHORTDELAY) for the transitional Yellow phases (just long enough to safely warn approaching traffic before the light changes to Red) — before proceeding to the next phase. Both LONGDELAY and SHORTDELAY would be implemented as timing-delay subroutines (using either a timer-overflow-based approach or a software counting-loop approach, as discussed in detail for other delay-calculation questions in this paper), with their specific duration constants chosen and calibrated to produce the actual desired real-world time intervals (e.g., 10 seconds green, 2 seconds yellow) based on the microcontroller's actual crystal frequency, forming a complete, functional, continuously-repeating basic two-road traffic light control sequence.
Why the port is cleared before setting each phase's bits: each phase transition begins with MOV P1, #00H, unconditionally turning off every lamp before the specific two lamps for the upcoming phase are individually turned on with SETB; this approach guarantees that no lamp accidentally remains illuminated from the immediately preceding phase (which could otherwise happen if the program merely toggled or set new bits without first clearing the old ones — for example, if the previous phase's Green lamp bit were never explicitly cleared, it would remain lit even after the program intended to switch to the Yellow phase, creating an unsafe and confusing simultaneous Green+Yellow display). Explicitly clearing the entire port first, then setting only the bits required for the new phase, is a simple and robust technique to ensure the lamp state transitions cleanly and unambiguously between phases with no risk of leftover bits from a previous state.
Safety and realistic timing considerations: in a real physical traffic-light installation, it would additionally be considered good practice (and is often a legal/safety requirement) to insert a brief all-red 'clearance' interval between the two roads' green phases — i.e., a short period where both Road A and Road B simultaneously show Red — to ensure the intersection is completely clear of any vehicles that entered on a stale yellow/green signal before the opposing road's green phase begins; this simple 4-phase program, as given, does not include such an all-red clearance phase and would need one additional phase (SETB P1.0 and P1.3 together, with a short delay) inserted between each road's green-to-red transition and the opposing road's red-to-green transition for a fully realistic, safety-compliant traffic signal implementation, illustrating that this basic example represents the core cyclic-sequencing logic of a traffic light controller rather than a complete, safety-certified real-world traffic signal system.
Extensibility to more complex intersections: this same fundamental technique — mapping each lamp to a dedicated output bit, defining an ordered sequence of lamp-pattern/delay-duration pairs representing each phase of the desired signal cycle, and looping through this sequence indefinitely — extends directly to more complex intersections involving additional roads, pedestrian crossing signals, or turn-arrow signals, simply by using more output bits (potentially spanning multiple 8051 ports if more than 8 total lamp outputs are needed) and adding the corresponding additional phases (each with its own lamp pattern and appropriate delay duration) to the cyclic sequence, without requiring any fundamental change to the underlying control technique demonstrated by this simpler two-road example.
Alternative table-driven implementation approach: rather than writing out each phase's SETB instructions explicitly in sequence as shown, a more compact and easily-extensible implementation would instead store the sequence of lamp-patterns and corresponding delay-durations as two parallel lookup tables in code memory (accessed via MOVC A, @A+DPTR, as demonstrated in the stepper-motor interfacing questions elsewhere in this paper), with a single small loop simply fetching each phase's pattern and delay value from these tables in turn and applying them, rather than repeating essentially the same MOV/SETB/ACALL instruction sequence separately for every individual phase — this table-driven approach becomes increasingly advantageous as the number of phases grows (for a more complex, multi-road intersection with many phases), since adding, removing or reordering phases then only requires editing the table data rather than restructuring the program's actual instruction sequence.
Interrupt-driven refinement: the program as given uses purely software delay subroutines (ACALL LONGDELAY / SHORTDELAY), which occupy the CPU in a busy-wait loop for the entire duration of each phase, leaving it unable to perform any other useful work (such as monitoring a pedestrian call-button, an emergency-vehicle preemption sensor, or a vehicle-detector loop) during that time. A more sophisticated, interrupt-driven implementation would instead use one of the 8051's hardware timers, configured in auto-reload mode and generating a periodic timer-overflow interrupt, with the interrupt service routine incrementing a phase-duration counter and only actually advancing to the next lamp phase once the required count (corresponding to the desired real-time phase duration) has been reached — this frees the main program loop to continuously poll or respond to other inputs (pedestrian buttons, vehicle sensors) between timer interrupts, providing a much more responsive and functionally complete traffic-signal controller than the simpler, purely sequential busy-wait version presented as the direct answer to this specific question.