If you were able to change the program, it should be no problem changing the outputs to be inverted, right?
Then you would just need to swap the NPNs for PNPs and swap the +5v and gnd rails going to them. If youre doing this on a breadboard it should be easy to change the rails, on a ready made pcb it might be harder.
Here is another option, this one eliminates many of the discrete components by using two integrated circuits.
However, it requires some programme changes.
Description
During the initialisation sequence, the PIC sets RA to 10-- -001 & clears RB (- = don't care).
This makes U1 output 1 low thus activating Column 1.
Then the PIC sets RB1 which turns the first NPN transistor on thus activating row 1 - hence turning the first LED is on.
At the end of this scan period, RA0 is cleared & RA1 is set thus U1/1 goes high & U1/2 low.
This activates column 2 hence turning the second LED is on.
The RA2:0 outputs are changed at the end of each scan period in a binary sequence so Columns 3 ~ 7 are activated in turn.
At the end of the seventh scan period, RA2:0 are cleared, RA6 is set & RA7 is cleared.
This activated Column 8.
As before, RA2:0 are changed at the end of each scan period in a binary sequence so Columns 9 ~ 15 are activated in turn.
At the end of the 15th scan period, RA is again set to 10-- -001, RB7 is set & RB6 is cleared.
This reactivates Column 1. RB1 is cleared & RB2 is set thus activating row 2.
This process continues until all LEDs have been addressed & then the first LED is re-addressed as described above.
Don't bother trying a CD4028.I very much like this the best.
I ordered some 74ls145's from NTE and waiting for them....in the meantime I'm gonna try and see if cd4028 will work.
Sorry took sooo long to respond! I'm here daily. No problem, I have many other things to do.
Talk tomorrow if i find out something.
Have you done any PIC programming in Assembly before?
If not, it would be a good idea to start with a simple porgramme.
I can post some if you wish.
;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
Tom,
I suggest that you post some examples of code that you don't understand so I & others can help.
Below is a Traffic Lights programme that is relatively simple. I think I used the delay sub routine from one of Nigel's tutorials. However, there are other ways to do delays.
Note that - although I used the "RB change interrupt" - I did not use an interrupt sub routine (ISR).
ISRs can cause some complications & are not always necessary as this example shows.
In other words, you can use the interrupt facilities without necessarily employing an ISR.
PS. What does the PIC do? In other words, what are the effects of pressing the various buttons?
Code:;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
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?