;Programme function - Simulate pedestrian traffic lights
;The push button is connected to RB7. It should be connected
; such that it is set when the button is pressed.
LIST P=PIC16F84, F=INHX8M
include "p16f84.inc"
__CONFIG 0x3FF2 ;4 MHz crystal oscillator, WDT disabled, Power up reset enabled
porta EQU 05 ;porta is at address 05
portb EQU 06 ;portb is at address 06
cblock 0x20 ;start of general purpose registers
counter8 ;flash counter
count_a ;used in delay routine
count_b ;used in delay routine
count_1 ;used in delay routine
count_2 ;used in delay routine
endc
ORG 0x00
#define Ped_Red porta, 0 ;Bit 0 Pedestrian's Red LED
#define Ped_Green porta, 2 ;Bit 2 Pedestrian's Green LED
#define Motor_Red portb, 0 ;Bit 0 Motorist's Red LED
#define Motor_Amber portb, 1 ;Bit 1 Motorist's Amber LED
#define Motor_Green portb, 2 ;Bit 2 Motorist's Green LED
#define Button portb, 7 ;Bit 7 Pedestrian's button
;Programme start
start call Init
main clrf porta ; resets inputs & outputs
clrf portb ; ditto
bsf Ped_Red ;sets pedestrians; red on (RA0), others off
bsf Motor_Green ;sets motorists; green on (RB2), others off
sleep ;interrupt if pedestrian's button is pressed
nop
;the PIC will be awoken from sleep when the RB change interrupt occurs
; due to a pedestrian pressing the button which sets RB7 high
bsf Motor_Amber ;turns motorist's amber light on (RB1)
bcf Motor_Green ;turns motorist's green light off (RB2)
call delay_2s ;2 second delay
movlw 0x08 ;reset INTCON after a 2 sec delay so the
movwf INTCON ; Pedestrian's button will have been released
bcf Motor_Amber ;turns motorist's amber light off (RB1)
bsf Motor_Red ;turns motorist's red light on (RB0)
bcf Ped_Red ;pedestrian's red off (RA0)
bsf Ped_Green ;pedestrian's green on (RA2),
call delay_8s ;creates 8 second delay
bsf Motor_Amber ;turns motorist's amber light on (RB1)
bcf Motor_Red ;turns motorist's red light off (RB0)
movlw 08 ;moves 8 into w
movwf counter8 ;moves 8 from w into counter8
flashloop
movlw b'00000100'
xorwf porta, f ;toggles the green pedestrian light
call delay_500m ;creates half second delay
decfsz counter8 ;8 times to flash pedestrian green
goto flashloop ;loops back
call delay_30s ;to give motorists at least 30 sec before
; a Pedestrian can change the lights
goto main ;loops back to main
; Subroutines:
Init
clrf porta ; resets inputs & outputs
clrf portb ; ditto
bsf STATUS, 5 ;selects BANK 1
movlw 00
movwf TRISA ;RA0:4 O/P Pedestrian's light: RA0 red, RA2: green
movlw 80 ;RB0:6 o/p, RB7 i/p RB3:5, not used
movwf TRISB ;Motorist's light: RB0: red, RB1 amber RB2: green.
movlw b'00000111' ;sets up prescaler to divide
movwf OPTION_REG ; by 256 internal clock, so TMR0 increments every 256
; instruction cycles
bcf STATUS, 5 ;selects bank 0
movlw 0x08 ;set interrupts file reg to enable
movwf INTCON ; the RB change interrupt
return ;return to main programme
;delay sub routines
delay_30s ;30 sec delay
movlw d'60'
goto delay_n
delay_8s ;8 sec delay
movlw d'16'
goto delay_n
delay_2s ;2 sec delay
movlw d'4'
goto delay_n
delay_n
movwf count_1
call delay_500m
decfsz count_1
goto $-2
return
delay_500m ;500 millisec delay
call delay_250m
delay_250m movlw 0xFA ;delay 250 mS
goto td0
delay_100m movlw d'100' ;delay 100 mS
goto td0
delay_50m
movlw d'50' ;delay 50 mS
goto td0
delay_20m
movlw d'20' ;delay 20 mS
goto td0
delay_5m
movlw 0x05 ;delay 5 ms (4 MHz clock)
goto td0
delay_1m
movlw 0x01 ;delay 1 ms (4 MHz clock)
td0 movwf count_a ;1 ms loop * count_a
movlw 0x63 ;
movwf count_b
goto td3
td1 movlw 0x63 ;
movwf count_b
goto $+1
goto $+1
goto $+1
td2 goto $+1 ;10us loop
nop
td3 goto $+1
goto $+1
decfsz count_b, f
goto td2
decfsz count_a, f
goto td1
return
delay_250u ;250 us
movlw d'81' ;
goto $+1
movwf count_a ;
decfsz count_a, f
goto $-1
return
delay_30u
movlw d'8' ;delay 30 us
movwf count_2
decfsz count_2, f
goto $-1
nop
return
ORG 0x2100
DE 0x07, 0x0A, 0x08, 0x01
end