PDA

View Full Version : Multiple IF THEN Statements: PIC16F84A



bob425
- 9th August 2012, 01:07
Forum Members:

I am using PicBasisPro Ver 2.50a, Melabs Programmer Ver. 4.40 and MicroCode Studio Ver. 2.0.0.5 for the following PIC16F84A application.

Even though I have used both the Melabs printer port of the Melabs USB programmers I haven't identified the following problem.

1. Go to the LOOP section.
2. The first IF THEN performs as intended.
3. The second IF THEN does not even execute the "GOSUB pwrup" sub-routine.
4. If I reverse the IF THEN codes, the first IF THEN section always executes.

I’ve read the PIC16F84A data sheet and haven’t found, or have overlooked, any constants of using the following code on the PIC16F84A component.

Perhaps I’m “too close to the trees…”

Any assistance will be appreciated.

Regards,

Bob


================================================== ================
'************************************************* *******************
'* Name : Syn-Ren50.BAS Author : Bob Wills *
'* MCU : PIC 16F84A USE : OLIN FOX LIFT *
'* Date : 08/04/2012, Ver. 2.0 PicBasic Pro Compiler *
'* Words: 712 Duty Cycle: ~ 0.79 step/1%DC *
'* NOTE: This program controls a BDC motor to move a lift up/down *
'* with the following features: *
'* 1. Increase the motor speed (up/down) from stop to running speed.*
'* 2. Decrease the motor speed (up/down) just before the stopping *
'* limit switch. *
'* 3. Provide various stopping rates for safety purposes. *
'* 4. The motor is controlled by a Dimension Engineering *
'* Single Channel 50A continuous/100A peak, Brushed motor *
'* controller, Model: SyRen50. This contoller containa a MCU. *
'* 5. A PIC16F84A interfaces between the lift inputs and the SyRen50 *
'* and sends control signals to the SyRen50 using the PBP *
'* "SEROUT" statement -- SEROUT mtrdat, T2400, [n] *
'* 6. SEROUT mtrdat, T9600, [127] = motor stop, *
'* ...[0] = motor full reverse; ...[255] = motor full forward. *
'************************************************* ********************
@ DEVICE PIC16F84A, XT_OSC ' 4Mhz
@ DEVICE PIC16F84A, WDT_OFF ' Watchdog Timer
@ DEVICE PIC16F84A, PWRT_ON ' Power-On Timer
@ DEVICE PIC16F84A, PROTECT_OFF ' Program Code Protection

stdwnv con 109 'range 127-0: 96~6vdc, 64~12vdc
stupv con 145 'range 127-256: 158~6vdc, 190~12vdc
upstps con 30 'up
dwnstps con 30 'down
sloup con 30 'up end speed
slodwn con 30 'down end speed
i var byte
n var BYTE
upv var byte
dwnv var byte
'pin
sss VAR PORTA.0 'Pin 17 'RA0/AN0 input safety switch
slo VAR PORTA.1 'Pin 18 'RA1/AN1 input for slow interrupt
upstp VAR PORTA.2 'Pin 1 'RA2/AN2/CVREF/VREF- input for up stop
dwnstp VAR PORTA.3 'Pin 2 'RA3/AN3/VREF+/C1OUT input for down stop
' VAR PORTA.4 'Pin 3 'RA4/AN4/T0CKI/C2OUT recvr input = down start
' Pin 4 MCLR
' Pin 15 OSC2/CLKOUT
' Pin 16 OSC1/CLKIN

syrenpwr VAR PORTB.0 'Pin 6 'RB0/INT/CCP1 output to the syren power relay
mtrlp VAR PORTB.1 'Pin 7 'RB1/SDI/SDA output to the motor loop relay
mtrdat VAR PORTB.2 'Pin 8 'RB2/SDO/RX/DT output data control for syrenpwr
' VAR PORTB.3 'Pin 9 'RB3/PGM/CCP1
rkrup VAR PORTB.4 'Pin 10 'RB4/SCK/SCL rocker input for up start
rcvrdn VAR PORTB.5 'Pin 11 'RB5/SS/TX/CK receiver input for down start
rcvrup VAR PORTB.6 'Pin 12 'RB6/AN5/PGC/T1OSO/T1CKI ICSP CLOCK
'rcvr input for up start
' VAR PORTB.7 'Pin 13 'RB7/AN6(6)/PGD/T1OSI ICSP DATA Manual Switch

PORTA = 5 'PORTA MEMORY ADDRESS
TRISA = 133 'TRISA MEMORY ADDRESS
TRISA = %11111111 'SET PORTA DATA DIRECTIONS
PORTA = %00000000 'CLEAR PORTA MEMORY

PORTB = 6 'PORTB MEMORY ADDRESS
TRISB = 134 'TRISB MEMORY ADDRESS
TRISB = %11111000 'SET PORTB DATA DIRECTIONS
PORTB = %00000000 'CLEAR PORTB MEMORY
INCLUDE "modedefs.bas"


'--------------------------------------------------------------------------
loop:

if (rcvrup = 0) and (upstp = 1) then
gosub pwrup
gosub uprcvr
else
gosub pwrdwn
endif

if (rcvrdn = 0) and (dwnstp = 1) then
gosub pwrup
gosub dwnrcvr
else
gosub pwrdwn
endif

gosub loop
'--------------------------------------------------------------------------
dwnrcvr: 'Increases motor speed from stop to "up speed rate'

serout mtrdat, T2400, [stdwnv]
pause 1000
dwnv = stdwnv
pause 50
for i = 1 to dwnstps step 1
dwnv = dwnv - 1
SEROUT mtrdat, T2400, [dwnv]
pause 50
if (rcvrdn = 1) oR (dwnstp = 0) then 'stop & limit sw
serout mtrdat, T2400, [127]
gosub pwrdwn
else
endif
next i
pause 1000
gosub loop
'--------------------------------------------------------------------------
uprcvr: 'Increases motor speed from stop to "up speed rate'

serout mtrdat, T2400, [stupv]
pause 1000
upv = stupv
pause 50
for i = 1 to upstps step 1
upv = upv + 1
SEROUT mtrdat, T2400, [upv]
pause 50
if (rcvrup = 1) oR (upstp = 0) then 'stop & limit sw
serout mtrdat, T2400, [127]
gosub pwrdwn
else
endif
next i
pause 1000
gosub loop
'--------------------------------------------------------------------------
pwrup:
high syrenpwr
pause 500
serout mtrdat, T2400, [127]
pause 250
high mtrlp
return
'--------------------------------------------------------------------------
pwrdwn:
serout mtrdat, T2400,[127]
pause 50
low syrenpwr
pause 10
low mtrlp
gosub loop
'--------------------------------------------------------------------------

Archangel
- 9th August 2012, 02:32
Gosubs NEED returns to take them off the stack. If you do not wish to return to the next line use goto. I only see return on 1 subprogram. I will look some more.
edit: so replace gosub loop with return (s)

sayzer
- 9th August 2012, 02:36
Use return instead of calling the main loop again after calling a sub routine.
Also, use goto instead of callig the main loop within itself again.

Corrected code is as below.



'================================================= = ================
'************************************************* *******************
'* Name : Syn-Ren50.BAS Author : Bob Wills *
'* MCU : PIC 16F84A USE : OLIN FOX LIFT *
'* Date : 08/04/2012, Ver. 2.0 PicBasic Pro Compiler *
'* Words: 712 Duty Cycle: ~ 0.79 step/1%DC *
'* NOTE: This program controls a BDC motor to move a lift up/down *
'* with the following features: *
'* 1. Increase the motor speed (up/down) from stop to running speed.*
'* 2. Decrease the motor speed (up/down) just before the stopping *
'* limit switch. *
'* 3. Provide various stopping rates for safety purposes. *
'* 4. The motor is controlled by a Dimension Engineering *
'* Single Channel 50A continuous/100A peak, Brushed motor *
'* controller, Model: SyRen50. This contoller containa a MCU. *
'* 5. A PIC16F84A interfaces between the lift inputs and the SyRen50 *
'* and sends control signals to the SyRen50 using the PBP *
'* "SEROUT" statement -- SEROUT mtrdat, T2400, [n] *
'* 6. SEROUT mtrdat, T9600, [127] = motor stop, *
'* ...[0] = motor full reverse; ...[255] = motor full forward. *
'************************************************* ********************
@ DEVICE PIC16F84A, XT_OSC ' 4Mhz
@ DEVICE PIC16F84A, WDT_OFF ' Watchdog Timer
@ DEVICE PIC16F84A, PWRT_ON ' Power-On Timer
@ DEVICE PIC16F84A, PROTECT_OFF ' Program Code Protection

stdwnv con 109 'range 127-0: 96~6vdc, 64~12vdc
stupv con 145 'range 127-256: 158~6vdc, 190~12vdc
upstps con 30 'up
dwnstps con 30 'down
sloup con 30 'up end speed
slodwn con 30 'down end speed
i var byte
n var BYTE
upv var byte
dwnv var byte
'pin
sss VAR PORTA.0 'Pin 17 'RA0/AN0 input safety switch
slo VAR PORTA.1 'Pin 18 'RA1/AN1 input for slow interrupt
upstp VAR PORTA.2 'Pin 1 'RA2/AN2/CVREF/VREF- input for up stop
dwnstp VAR PORTA.3 'Pin 2 'RA3/AN3/VREF+/C1OUT input for down stop
' VAR PORTA.4 'Pin 3 'RA4/AN4/T0CKI/C2OUT recvr input = down start
' Pin 4 MCLR
' Pin 15 OSC2/CLKOUT
' Pin 16 OSC1/CLKIN

syrenpwr VAR PORTB.0 'Pin 6 'RB0/INT/CCP1 output to the syren power relay
mtrlp VAR PORTB.1 'Pin 7 'RB1/SDI/SDA output to the motor loop relay
mtrdat VAR PORTB.2 'Pin 8 'RB2/SDO/RX/DT output data control for syrenpwr
' VAR PORTB.3 'Pin 9 'RB3/PGM/CCP1
rkrup VAR PORTB.4 'Pin 10 'RB4/SCK/SCL rocker input for up start
rcvrdn VAR PORTB.5 'Pin 11 'RB5/SS/TX/CK receiver input for down start
rcvrup VAR PORTB.6 'Pin 12 'RB6/AN5/PGC/T1OSO/T1CKI ICSP CLOCK
'rcvr input for up start
' VAR PORTB.7 'Pin 13 'RB7/AN6(6)/PGD/T1OSI ICSP DATA Manual Switch

PORTA = 5 'PORTA MEMORY ADDRESS
TRISA = 133 'TRISA MEMORY ADDRESS
TRISA = %11111111 'SET PORTA DATA DIRECTIONS
PORTA = %00000000 'CLEAR PORTA MEMORY

PORTB = 6 'PORTB MEMORY ADDRESS
TRISB = 134 'TRISB MEMORY ADDRESS
TRISB = %11111000 'SET PORTB DATA DIRECTIONS
PORTB = %00000000 'CLEAR PORTB MEMORY

INCLUDE "modedefs.bas"


'--------------------------------------------------------------------------
loopx:

if (rcvrup = 0) and (upstp = 1) then
gosub pwrup
gosub uprcvr
else

gosub pwrdwn

endif

if (rcvrdn = 0) and (dwnstp = 1) then
gosub pwrup
gosub dwnrcvr
else

gosub pwrdwn

endif

goto loopx
'--------------------------------------------------------------------------
dwnrcvr: 'Increases motor speed from stop to "up speed rate'

serout mtrdat, T2400, [stdwnv]
pause 1000
dwnv = stdwnv
pause 50
for i = 1 to dwnstps step 1
dwnv = dwnv - 1
SEROUT mtrdat, T2400, [dwnv]
pause 50
if (rcvrdn = 1) oR (dwnstp = 0) then 'stop & limit sw
serout mtrdat, T2400, [127]
gosub pwrdwn
else

endif
next i

pause 1000

return
'--------------------------------------------------------------------------
uprcvr: 'Increases motor speed from stop to "up speed rate'

serout mtrdat, T2400, [stupv]
pause 1000
upv = stupv
pause 50
for i = 1 to upstps step 1
upv = upv + 1
SEROUT mtrdat, T2400, [upv]
pause 50
if (rcvrup = 1) oR (upstp = 0) then 'stop & limit sw
serout mtrdat, T2400, [127]
gosub pwrdwn

else

endif
next i

pause 1000

return
'--------------------------------------------------------------------------
pwrup:
high syrenpwr
pause 500
serout mtrdat, T2400, [127]
pause 250
high mtrlp

return
'--------------------------------------------------------------------------
pwrdwn:
serout mtrdat, T2400,[127]
pause 50
low syrenpwr
pause 10
low mtrlp

return
'--------------------------------------------------------------------------

aratti
- 9th August 2012, 05:46
On top I would suggest also these two modifications to your subroutine:

1) Not necessary to serout twice the same code (127)
2) the Goto Skip will take you out of the For/Next loop



'================================================= = ================
'************************************************* *******************
'* Name : Syn-Ren50.BAS Author : Bob Wills *
'* MCU : PIC 16F84A USE : OLIN FOX LIFT *
'* Date : 08/04/2012, Ver. 2.0 PicBasic Pro Compiler *
'* Words: 712 Duty Cycle: ~ 0.79 step/1%DC *
'* NOTE: This program controls a BDC motor to move a lift up/down *
'* with the following features: *
'* 1. Increase the motor speed (up/down) from stop to running speed.*
'* 2. Decrease the motor speed (up/down) just before the stopping *
'* limit switch. *
'* 3. Provide various stopping rates for safety purposes. *
'* 4. The motor is controlled by a Dimension Engineering *
'* Single Channel 50A continuous/100A peak, Brushed motor *
'* controller, Model: SyRen50. This contoller containa a MCU. *
'* 5. A PIC16F84A interfaces between the lift inputs and the SyRen50 *
'* and sends control signals to the SyRen50 using the PBP *
'* "SEROUT" statement -- SEROUT mtrdat, T2400, [n] *
'* 6. SEROUT mtrdat, T9600, [127] = motor stop, *
'* ...[0] = motor full reverse; ...[255] = motor full forward. *
'************************************************* ********************
@ DEVICE PIC16F84A, XT_OSC ' 4Mhz
@ DEVICE PIC16F84A, WDT_OFF ' Watchdog Timer
@ DEVICE PIC16F84A, PWRT_ON ' Power-On Timer
@ DEVICE PIC16F84A, PROTECT_OFF ' Program Code Protection

stdwnv con 109 'range 127-0: 96~6vdc, 64~12vdc
stupv con 145 'range 127-256: 158~6vdc, 190~12vdc
upstps con 30 'up
dwnstps con 30 'down
sloup con 30 'up end speed
slodwn con 30 'down end speed
i var byte
n var BYTE
upv var byte
dwnv var byte
'pin
sss VAR PORTA.0 'Pin 17 'RA0/AN0 input safety switch
slo VAR PORTA.1 'Pin 18 'RA1/AN1 input for slow interrupt
upstp VAR PORTA.2 'Pin 1 'RA2/AN2/CVREF/VREF- input for up stop
dwnstp VAR PORTA.3 'Pin 2 'RA3/AN3/VREF+/C1OUT input for down stop
' VAR PORTA.4 'Pin 3 'RA4/AN4/T0CKI/C2OUT recvr input = down start
' Pin 4 MCLR
' Pin 15 OSC2/CLKOUT
' Pin 16 OSC1/CLKIN

syrenpwr VAR PORTB.0 'Pin 6 'RB0/INT/CCP1 output to the syren power relay
mtrlp VAR PORTB.1 'Pin 7 'RB1/SDI/SDA output to the motor loop relay
mtrdat VAR PORTB.2 'Pin 8 'RB2/SDO/RX/DT output data control for syrenpwr
' VAR PORTB.3 'Pin 9 'RB3/PGM/CCP1
rkrup VAR PORTB.4 'Pin 10 'RB4/SCK/SCL rocker input for up start
rcvrdn VAR PORTB.5 'Pin 11 'RB5/SS/TX/CK receiver input for down start
rcvrup VAR PORTB.6 'Pin 12 'RB6/AN5/PGC/T1OSO/T1CKI ICSP CLOCK
'rcvr input for up start
' VAR PORTB.7 'Pin 13 'RB7/AN6(6)/PGD/T1OSI ICSP DATA Manual Switch

PORTA = 5 'PORTA MEMORY ADDRESS
TRISA = 133 'TRISA MEMORY ADDRESS
TRISA = %11111111 'SET PORTA DATA DIRECTIONS
PORTA = %00000000 'CLEAR PORTA MEMORY

PORTB = 6 'PORTB MEMORY ADDRESS
TRISB = 134 'TRISB MEMORY ADDRESS
TRISB = %11111000 'SET PORTB DATA DIRECTIONS
PORTB = %00000000 'CLEAR PORTB MEMORY

INCLUDE "modedefs.bas"


'--------------------------------------------------------------------------
loopx:

if (rcvrup = 0) and (upstp = 1) then
gosub pwrup
gosub uprcvr
else

gosub pwrdwn

endif

if (rcvrdn = 0) and (dwnstp = 1) then
gosub pwrup
gosub dwnrcvr
else

gosub pwrdwn

endif

goto loopx
'--------------------------------------------------------------------------
dwnrcvr: 'Increases motor speed from stop to "up speed rate'

serout mtrdat, T2400, [stdwnv]
pause 1000
dwnv = stdwnv
pause 50
for i = 1 to dwnstps step 1
dwnv = dwnv - 1
SEROUT mtrdat, T2400, [dwnv]
pause 50
if (rcvrdn = 1) oR (dwnstp = 0) then 'stop & limit sw
gosub pwrdwn
Goto Skip_01
endif
next i

Skip_01:
pause 1000

return
'--------------------------------------------------------------------------
uprcvr: 'Increases motor speed from stop to "up speed rate'

serout mtrdat, T2400, [stupv]
pause 1000
upv = stupv
pause 50
for i = 1 to upstps step 1
upv = upv + 1
SEROUT mtrdat, T2400, [upv]
pause 50
if (rcvrup = 1) oR (upstp = 0) then 'stop & limit sw
gosub pwrdwn
Goto Skip_02

endif
next i
Skip_02:

pause 1000

return
'--------------------------------------------------------------------------
pwrup:
high syrenpwr
pause 500
serout mtrdat, T2400, [127]
pause 250
high mtrlp

return
'--------------------------------------------------------------------------
pwrdwn:
serout mtrdat, T2400,[127]
pause 50
low syrenpwr
pause 10
low mtrlp

return
'--------------------------------------------------------------------------

bob425
- 9th August 2012, 05:57
Archangel:
sayzar:

Thank you so much for you timely insite and help, plus your programming advice for my benefit.

I'll make those connections and continue with the rest of the code prepatation.

Regards,

Bob

bob425
- 10th August 2012, 06:01
aratti:
Archangel:
sayzar:

All of your comments and suggestions have been quite helpful.

I finished the code using your help -- now it's PCB time.

Thanks again,

Bob