View Full Version : Switch Sequence
Tissy
- 8th February 2005, 20:27
I am very new to PICs, so any help is greatly appriciated. I have scowled the NET and this seems the friendliest place for help.
I would like to develop using a 16F876 a small application that had 1 switch as input, say on RB0. Then each time the switch is pressed a different LED routine is actioned.
So for example:
1st switch push, LED on RC0 stays on
2nd switch push, LED on RC1 blinks
3rd switch push, LEDs on RC2 and RC3 'wink'
etc etc.
Once the, say 3 routines are completed, it goes back to the first again.
Can anyone help with this or point me in the right directionto get me going. I'm keen to learn about PICs as they have so many uses.
Many thanks for any anticipate help.
Steve
mister_e
- 8th February 2005, 21:55
.... that had 1 switch as input, say on RB0. Then each time the switch is pressed a different LED routine is actioned.
So for example:
1st switch push, LED on RC0 stays on
2nd switch push, LED on RC1 blinks
3rd switch push, LEDs on RC2 and RC3 'wink'
As i don't know what 'wink' mean... this is something to help you to start...
There's so many different way but... Never tested but should work.
ADCON1=7 'disable analog to digital converter
OPTION_REG.7=0 'enable pull-up resistor on PORTb
PushButton var PORTB.0 ' pushButton connected between RB0
' and ground
Led1 VAR PORTC.0 ' All LEDs
Led2 VAR PORTC.1 ' Connected between
Led3 VAR PORTC.2 ' RC pins and ground
Led4 VAR PORTC.3 ' via resistor
PushHowManyTimes var byte
Delay VAR BYTE
Delay=0
PushHowManyTimes=0
start:
While pushbutton ' do the specific task untill pushbutton
' is pressed
branch PushHowManyTimes , [Start,StayOn,Blink]
wend
PushHowManytimes=PushHowManytimes+1 ' Changing task
if PushHowManytimes=3 then PushHowManytimes=1
while pushbutton=0 ' waiting untill pushbutton is release
wend
pause 50 ' debounce time
goto start
StayOn:
High PORTC.0
goto start
Blink:
Low PORTC.0
If delay<50 then
High PORTC.1
else
If delay<100 then
low PORTC.1
else
delay=0
endif
endif
pause 10
Delay=delay+1
goto start
Tissy
- 10th February 2005, 02:34
Thanks very much for your help Steve, this is exactly what i wanted and it is a good platform to expand from.
One question, is it possible to permantly monitor the switch input.
For example, when the switch is pressed, the program BRANCHes to a preset routine. However, if this preset routine is a long one , ie multiple LED flashes etc, it will only look at the switch input at the end of this preset routine (when it 'goto START') and not during the routine.
ie.
Blink:
Low PORTC.0
If delay<50 then
High PORTC.1
else
If delay<100 then
low PORTC.1
else
delay=0
endif
endif
pause 10
Delay=delay+1
goto start *** ONLY LOOKS AT SWITCH INPUT HERE AND NOT DURING ROUTINE ***
Does this make sense, i need to permantly monitor the switch input no matter what else the code is doing elsewhere.
Many thanks again,
Steve
mister_e
- 10th February 2005, 03:49
hi,
In the above section, it monitor the switches every 10ms. Close to be constant monitoring.
BTW, i case you have more complex routines, the most interesting stuff to do it is to use interrupts (rb0 or else other interrupt source that your PIC can provide).
In this case, it will monitor in background your push button and jump to the "interrupt handler" when he is pressed. In the interrupt handler, set a flag or variable that will say to your previous task that you have to change to another task.
Tissy
- 11th February 2005, 01:52
I have read some notes on inturrupts and have come up with the following, however, it doesn't do anything !! Of course with what i know about PICs, im not surprised. I am learning quickly though !!
This is what i have so far. Can you correct me if i've gone wrong on the interrupt side please?
ADCON1=7 'disable analog to digital converter
OPTION_REG.7=0 'enable pull-up resistor on PORTb
Led1 VAR PORTC.0 ' All LEDs
Led2 VAR PORTC.1 ' Connected between
Led3 VAR PORTC.2 ' RC pins and ground
Led4 VAR PORTC.3 ' via resistor
Led5 Var PORTC.4 '
ON INTERRUPT GOTO start ' Interrupt handler is start
INTCON = %10010000 ' Enable RB0 interrupt
Bright var byte
PushHowManyTimes var byte
Delay VAR BYTE
Delay=0
PushHowManyTimes=0
start:
DISABLE ' Disable interrupts in handler
branch PushHowManyTimes , [Start,StayOn,Blink,Fade,Wink]
PushHowManytimes=PushHowManytimes+1 ' Changing task
If PushHowManytimes=5 then PushHowManytimes=1
RESUME ' Return to main program
ENABLE ' Enable interrupts after handler
GOTO START
StayOn **** Routine *****
etc etc etc etc
Blink **** Routine *****
etc etc etc etc
Many thanks for any help received.
mister_e
- 11th February 2005, 05:47
not too far. You didn't define the RB0 interrupt type (falling edge)
and i do my own version. Hope this work and help you.
' I/O definition
'
TRISC=0 ' Set PORTC as OUTPUT
TRISB.0=1 ' Set PORTB.1 as input
Led1 VAR PORTC.0 ' All LEDs
Led2 VAR PORTC.1 ' Connected between
Led3 VAR PORTC.2 ' RC pins and ground
Led4 VAR PORTC.3 ' via resistor
Led5 Var PORTC.4 '
' register and interrupt definition
'
ADCON1=7 'disable analog to digital converter
OPTION_REG=0 ' enable pull-up resistor on PORTb
' Interrupt on falling edge of RB0
INTCON = %10010000 ' Enable RB0 interrupt
ON INTERRUPT GOTO ProcedureSwitcher
' Variable definition
'
PushHowManyTimes var byte
Bright var byte
Delay VAR WORD
DelayLoop var Word
' Variable initialisation
'
PORTC=0 ' Reset all outputs on PORTC
PushHowManyTimes=0
start:
Select Case PushHowManyTimes
case 1
gosub StayOn
Case 2
gosub Blink
'
' Place your other procedure here
'
end select
goto start
StayOn:
PORTC.0 = 1
return
Blink:
Toggle PORTC.1
Delay = 500
Gosub DoDelay
return
' I do a Delay Loop to be sure getting all interrupt withou latency
'
DoDelay:
For DelayLoop=0 to Delay
pause 1
Next
' Interrupt handler stuff here
'
DISABLE ' Disable interrupts in handler
ProcedureSwitcher:
PORTC=0 ' reset output to PORTC
PushHowManytimes=PushHowManytimes+1 ' Changing task
If PushHowManytimes=5 then PushHowManytimes=1
DelayLoop=Delay ' to exit the delay loop
While PORTB.0 = 0 ' waiting for push-button release
wend
pause 50 ' debounce time
RESUME ' Return to main program
ENABLE ' Enable interrupts after handler
Tissy
- 11th February 2005, 22:26
Thanks Steve. I've tried but failed !! The code was copied exactly as you have posted it, but didn't seem to work. I've tried to see what the problem is but can't figure it out.
Just to confirm
RC0 is Outputs
RB0 is Switch Input.
Can you help please.
Thanks again.
Steve
mister_e
- 12th February 2005, 11:58
Damn, the next time i'll test it before sending here.. many apologize. Change to this tested one ;o[
' I/O definition
'
TRISC=0 ' Set PORTC as OUTPUT
TRISB.0=1 ' Set PORTB.1 as input
Led1 VAR PORTC.0 ' All LEDs
Led2 VAR PORTC.1 ' Connected between
Led3 VAR PORTC.2 ' RC pins and ground
Led4 VAR PORTC.3 ' via resistor
Led5 Var PORTC.4 '
' register and interrupt definition
'
ADCON1=7 'disable analog to digital converter
OPTION_REG=0 ' enable pull-up resistor on PORTb
' Interrupt on falling edge of RB0
INTCON = %10010000 ' Enable RB0 interrupt
ON INTERRUPT GOTO ProcedureSwitcher
' Variable definition
'
PushHowManyTimes var byte
HexLed var byte
Delay VAR WORD
DelayLoop var Word
' Variable initialisation
'
PORTC=0 ' Reset all outputs on PORTC
PushHowManyTimes=0
HexLed=0
start:
Select Case PushHowManyTimes
case 1
gosub StayOn
Case 2
gosub Blink
case 3
gosub HEXonPORTC0_1
end select
goto start
StayOn:
led1 = 1
return
Blink:
Toggle led2
Delay = 500
Gosub DoDelay
return
HEXonPORTC0_1:
PORTC=HexLed
delay=500
gosub dodelay
HexLed=HexLed+1
if HexLed=4 then HexLed=0
return
' I do a Delay Loop to be sure getting all interrupt withou latency
'
DoDelay:
For DelayLoop=0 to Delay
pause 1
Next
RETURN
' Interrupt handler stuff here
'
DISABLE ' Disable interrupts in handler
ProcedureSwitcher:
INTCON.7 = 1 'disable all interrputs
PORTC=0 ' reset output to PORTC
HexLed=0
DelayLoop=Delay ' to exit the delay loop
PushHowManytimes=PushHowManytimes+1 ' Changing task
If PushHowManytimes=4 then PushHowManytimes=1
While PORTB.0 = 0 ' waiting untill
wend ' push-button is release
pause 100 ' debounce time
INTCON = %10010000 ' Enable RB0 interrupt
' reset RB0 interrupt flag
RESUME ' Return to main program
ENABLE ' Enable interrupts after handler
Tissy
- 12th February 2005, 14:15
Thanks very much, that works great. I'm almost there with the main code now. The one thing i can't figure out though, is that with an Interrupt, should that stop what ever is being processed and then move onto the next procedural call? As part of the sequence i have set up at the moment is some PWM. If this procedure is being processed, and you push the button, it does remember the push, but doesn't move on until the full PWM part of the code has finished its cycle.
Heres an extract of working code which hopefully demonstartes what i mean. Its a piece of code which makes the LEDs look as if the are fading on and off. I would like to step to the next LED immediately the button is pushed, no matter at what position the fading is at. Can this be done?
Here it is:
' I/O definition
'
TRISC=0 ' Set PORTC as OUTPUT
TRISB.0=1 ' Set PORTB.1 as input
Red VAR PORTC.0 ' All LEDs
Green VAR PORTC.1 ' Connected between
Bright var byte
' register and interrupt definition
'
ADCON1=7 'disable analog to digital converter
OPTION_REG=0 ' enable pull-up resistor on PORTb
' Interrupt on falling edge of RB0
INTCON = %10010000 ' Enable RB0 interrupt
ON INTERRUPT GOTO ProcedureSwitcher
' Variable definition
'
PushHowManyTimes VAR byte
Delay VAR WORD
DelayLoop VAR Word
' Variable initialisation
'
PORTC=0 ' Reset all outputs on PORTC
PushHowManyTimes=0
start:
Select Case PushHowManyTimes
case 1
gosub FadeRed
Case 2
gosub FadeGreen
end select
goto start
FadeRed:
low Red
for bright = 0 to 255
PWM Red,Bright,1
next
for bright = 255 to 0 step -1
PWM Red,Bright,1
next
return
FadeGreen:
low red
for bright = 0 to 255
PWM Green,Bright,1
next
for bright = 255 to 0 step -1
PWM Green,Bright,1
next
return
' I do a Delay Loop to be sure getting all interrupt withou latency
'
DoDelay:
For DelayLoop=0 to Delay
pause 1
Next
RETURN
' Interrupt handler stuff here
'
DISABLE ' Disable interrupts in handler
ProcedureSwitcher:
INTCON.7 = 1 'disable all interrputs
PORTC=0 ' reset output to PORTC
' HexLed=0
DelayLoop=Delay ' to exit the delay loop
PushHowManytimes=PushHowManytimes+1 ' Changing task
If PushHowManytimes=3 then PushHowManytimes=1
While PORTB.0 = 0 ' waiting untill
wend ' push-button is release
pause 100 ' debounce time
INTCON = %10010000 ' Enable RB0 interrupt
' reset RB0 interrupt flag
RESUME ' Return to main program
ENABLE ' Enable interrupts after handler
Thank you again.
mister_e
- 12th February 2005, 14:36
Heres an extract of working code which hopefully demonstartes what i mean. Its a piece of code which makes the LEDs look as if the are fading on and off. I would like to step to the next LED immediately the button is pushed, no matter at what position the fading is at. Can this be done?
sure it can be done.
start:
Select Case PushHowManyTimes
case 1
GetOut = 0
gosub FadeRed
Case 2
GetOut = 0
gosub FadeGreen
end select
goto start
FadeRed:
bright = 0
while (Bright !=255) and (GetOut=0)
PWM Red,Bright,1
bright = bright + 1
wend
while (bright !=0) and (getout = 0)
PWM Red,Bright,1
bright=bright - 1
wend
return
FadeGreen:
bright = 0
while (Bright !=255) and (GetOut=0)
PWM Green,Bright,1
bright = bright + 1
wend
while (bright !=0) and (getout = 0)
PWM Green,Bright,1
bright=bright - 1
wend
return
' Interrupt handler stuff here
'
DISABLE ' Disable interrupts in handler
ProcedureSwitcher:
INTCON.7 = 1 'disable all interrputs
PORTC=0 ' reset output to PORTC
DelayLoop=Delay ' to exit the delay loop
GetOut = 1 ' to get out of the entire PWM loops
PushHowManytimes=PushHowManytimes+1 ' Changing task
If PushHowManytimes=3 then PushHowManytimes=1
While PORTB.0 = 0 ' waiting untill
wend ' push-button is release
pause 100 ' debounce time
INTCON = %10010000 ' Enable RB0 interrupt
' reset RB0 interrupt flag
RESUME ' Return to main program
ENABLE ' Enable interrupts after handler
Tissy
- 13th February 2005, 19:38
Thanks ever so much for your help Steve. I now have the main body of the code working very well.
As it is evident that you know your stuff when it comes to Pic Basic, can you recommend any books for learning. I value your opinion.
Thanks again.
Steve
mister_e
- 13th February 2005, 20:36
Sorry to disapointed you but, i can't recommmend any book since i use only the PBP manual and datasheets.
BUT if you do a search in this forum, on Melabs, on Crownhill and on Reynolds Electronic website, you'll find few books related to PBP.
Be friend with PBP manual and datasheet will lead you success. I know datasheet are sometime hard to understand but... what is the worst result you'll have ??? compile error, nothing is working... that's food for brain cells ;)
Have fun!
Powered by vBulletin® Version 4.1.7 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.