[phpBB Debug] PHP Warning: in file /home/mergweb/public_html/includes/common_functions.php on line 113: Trying to access array offset on null
[phpBB Debug] PHP Warning: in file /home/mergweb/public_html/merg_journal/download.php on line 68: Cannot modify header information - headers already sent by (output started at [ROOT]/includes/functions.php:3103)
[phpBB Debug] PHP Warning: in file /home/mergweb/public_html/merg_journal/download.php on line 69: Cannot modify header information - headers already sent by (output started at [ROOT]/includes/functions.php:3103)
[phpBB Debug] PHP Warning: in file /home/mergweb/public_html/merg_journal/download.php on line 70: Cannot modify header information - headers already sent by (output started at [ROOT]/includes/functions.php:3103)
[phpBB Debug] PHP Warning: in file /home/mergweb/public_html/merg_journal/download.php on line 71: Cannot modify header information - headers already sent by (output started at [ROOT]/includes/functions.php:3103)
[phpBB Debug] PHP Warning: in file /home/mergweb/public_html/merg_journal/download.php on line 72: Cannot modify header information - headers already sent by (output started at [ROOT]/includes/functions.php:3103)
[phpBB Debug] PHP Warning: in file /home/mergweb/public_html/merg_journal/download.php on line 73: Cannot modify header information - headers already sent by (output started at [ROOT]/includes/functions.php:3103)
[phpBB Debug] PHP Warning: in file /home/mergweb/public_html/merg_journal/download.php on line 74: Cannot modify header information - headers already sent by (output started at [ROOT]/includes/functions.php:3103)
[phpBB Debug] PHP Warning: in file /home/mergweb/public_html/merg_journal/download.php on line 75: Cannot modify header information - headers already sent by (output started at [ROOT]/includes/functions.php:3103)
;This program controls the operation of a small dc permanent magnet
;motor via a switch which operates like a section switch. If the
;section is "off" the unit, when entering the section slows down, at
;a rate determined by P1, until it stops. When the section
;switch is turned "on", even briefly, the unit then accelerates at
;a rate set by P2 until full speed is reached. When the unit leaves
;the section the sequence can then be repeated. At all times the
;presence of the car in the section is signalled by an output (+12/24v dc)
;when it is in section. The traction supplies are isolated from the control supply
;by means of opto isolators, one for detecting the flow of current to the motor
;and the other for controlling the drive transistor. The circuit needs
;12/24 dc supply and it has its own on board 5v regulator. More detailed
;explanations of the aspects of the software are given at the start of
;each section.
;This program is based on the original version for 16F84 device "sloswhfx"
;Written by Geoff Wilson
;10th April 2008 Developed fom Sloswh8q
;saved as Sloswh8r.asm
;for PIC12F675 8 pin device
;Clock 4MHz (internal)
;Watchdog Ensabled
;Code protect Off
;Copyright Geoff Wilson 2008
list P=PIC12F675
;*******general equates
;the folowing are on page0
tmr0 equ 01h ;timer register
pcl equ 02h ;program counter
status equ 03h ;status register
fsr equ 04h ;indirect register
gpio equ 05h ;input/outputs
cmcom equ 19h ;compatator control register
adresh equ 1eh ;value of hi A/D result
adcon0 equ 1fh ;A/D control reg
;the following are on page1
option_reg equ 01h
trisio equ 05h ;gpio function select
osccal equ 10h ;osc calibration register
ansel equ 1fh ;analogue select register
;********bit equates
c equ 00h ;carry bit
z equ 02h ;zero bit
w equ 00h ;destination w reg
f equ 01h ;destination file register
page1 equ 05h ;change SFR page
godone equ 01h ;start/check A/D conversion
;********GPIO equates for prototype
;all digital inuts have pull down resistors
decip equ 00h ;analogue input for decel rate control(pin7)
accip equ 01h ;analogue input for accel rate control(pin6)
secip equ 02h ;section or trigger switch input(pin5)
fbsig equ 03h ;feedback input(pin4)
pwrop equ 04h ;power output(pin3)
detop equ 05h ;PLC output(pin2)
;corresponding value to triso is b'00001111' - ansel is b'00100011'
;A/D channel = 00 or 01 - adcon is b'00000001' left justified, Vref = Vdd
;********memory equates
cblock 0020h
flagreg ;system flag register
pulsecnt ;number of pulses in cycle
pwmdc ;pwm duty cycle 1
testcnt ;test count register
decreg ;decel rate
accreg ;accel rate
temp1 ;temp data register1
temp2 ;temp data register2
delcnt ;delay counter
decrate ;deceleration rate
accrate ;acceleration rate
exitcnt ;end of sequence counter
endc
;*********flagreg bit equates
detflg equ 00h ;car detected flag
decflg equ 01h ;decelerating flag
stopflg equ 02h ;car stopped flag
accflg equ 03h ;acceleration flag
aofflg equ 04h ;accel control flag
endflg equ 05h ;end flag
secflg equ 06h ;section off flag
exitflg equ 07h ;exit flag (reset delay)
;set values - frame time is (frmcnt + sync) x pulse width
;number of steps from full power to zero = frame time x frmcnt x ADC result
;time for decel or accel = (frame time) x frmcnt x (decel/accel rate)
;exit value is no of times frame is scanned at end of sequence for exit delay
;sclfac is number of shifts applied to A/D result in adresh for practical situations.
frmcnt set .19 ;number of pulses in frame (between Sync pulses)
minval set .1 ;min value of decel/accel rate (scans per step)
timval set .132 ;pulse width timer value (gives 500uS pulse width)
exitval set .37 ;number of scans before sequence can repeat (370mS)
sclfac set .3 ;1 equ to div by 2, 2 to div by 4, 3 = div by 8
testnum set .4 ;number of tests of detection
org 00h
goto init
;*******delay subroutine
;This is the standard delay subroutine which is used to calculate
;the intervals between tests on the inputs to minimise noise effects.
org 06h
del50 movlw 0x9 ;gives 50uS interval
movwf delcnt
delay nop
decfsz delcnt,1 ;reduce filter count
goto delay ;go round again if non zero
return ;end subroutine
;******sync subroutine
;This is the main subroutine during which the state of the current
;detector input is checked as is the state of the section switch.
;The decel/accel rate is also calculated. Watch dog timer is reset.
;The nominal time for one cycle from sync to sync is 10mS
;(1 syc + 19 power cycles) x 500uS
sync bsf gpio,pwrop ;turn on output drive
bsf adcon0,godone ;and start A/D conversion
clrwdt ;clear watch dog timer
btfsc flagreg,exitflg ;is exit flag set
decf exitcnt,f ;yes - decrement exit count
;Test for car detected**** tests for "on" or "off" for value of (testcnt + 1),
;with 50us interval, before allowing results to change detflg. If no car
;is detected no further tests on other inputs are carried out and the
;program jumps to the A/D calculation. If a car is removed from the track
;during a sequence this is detected, all flags are reset and the
;sequence starts again.
det movlw testnum ;number of tests
movwf testcnt ;to test count
btfsc gpio,fbsig ;is car current on
goto deton ;yes - do check for on
detoff call del50 ;no current detected - wait 50us
btfsc gpio,fbsig ;check for current
goto adcal ;car detected - go to A/D calc
decfsz testcnt,1 ;decrement test count
goto detoff ;non zero - go back
bcf flagreg,detflg ;clear det flag
bcf gpio,detop ;clear PLC flag
btfss flagreg,endflg ;is endflag set
goto imstop ;no - go to immediate stop
bsf flagreg,exitflg ;yes - set exit flag
bcf flagreg,endflg ;and end flag
goto adcal
imstop clrf flagreg ;clear all flags
goto adcal ;then go to A/D
deton call del50 ;car detected - wait for 50us
btfss gpio,fbsig ;check for current
goto adcal ;no car detected - go to A/D calc
decfsz testcnt,1 ;decrement test count
goto deton ;non zero go back
bsf flagreg,detflg ;yes - set det flag
bsf gpio,detop ;and PLC output
;Test for section switch ***similar to detect section
;above
sec movlw testnum ;no of tests
movwf testcnt ;to test count
btfsc gpio,secip ;is section "ON"
goto secon ;yes - jump
secoff call del50 ;no - wait 50usec
btfsc gpio,secip ;section still "OFF"
goto sec ;no - go back to start
decfsz testcnt,1 ;yes - reduce count
goto secoff ;non zero - go back
bcf flagreg,secflg ;turn off flag
goto trig ;go to trigger
secon call del50 ;section "ON" - wait
btfss gpio,secip ;retest for "ON"
goto sec ;no - go back to start
decfsz testcnt,1 ;yes - reduce count
goto secon ;non zero - go back
btfsc flagreg,stopflg ;is stop flag set
goto trig ;yes - go to trigger
bsf flagreg,secflg ;sec section flag
btfss flagreg,detflg ;is det flag on
goto trig ;no - go to trigger
btfsc flagreg,accflg ;is accel flag set
goto trig ;yes - go to trigger
btfsc flagreg,endflg ;is end flag set
goto trig ;no - go to trigger
btfss flagreg,decflg ;is dec flag on
call pwmctld ;no call decel pwm control
secend bsf flagreg,decflg ;set decel flag
;Test for section switch operation***looks for operation
;of section flag to enable restart of unit.
trig btfsc flagreg,secflg ;is section 'on'?
goto adcal ;yes - go to A/D calc
offsec btfsc flagreg,endflg ;no - is end flag on?
goto adcal ;yes - go to adcal
btfsc flagreg,accflg ;no - is acc flag on?
goto adcal ;yes - go to adcal
btfsc flagreg,decflg ;no - is dec flag on?
goto accset ;yes - go to accset
btfss flagreg,stopflg ;no - is stop flag on?
goto adcal ;no - go to adcal
accset bsf flagreg,accflg ;yes - set acc flag
bcf flagreg,decflg ;and reset dec flag
;adcal takes the result from the A/D conversion and directs it to either
;the decel or accel calculation depending on the reading of the channel
;selected. It then changes the address to the alternate channel for the
;next sync pulse.
adcal clrf testcnt ;clear test count (if coming from det)
btfsc adcon0,godone ;A/D complete
goto exit ;no - go to exit
call scale
adcalb movf adcon0,w ;move adcon0 reg to w
andlw b'00000100' ;diff between accel and decel
btfss status,z ;is result zero
goto accal ;no go to accel cal
decal movf temp2,w ;move result to w reg
movwf decrate ;move result to decel register
movlw b'00000101' ;select chan1 (prototype)
movwf adcon0 ;and put in A/D control register
goto exit
accal movf temp2,w ;move result to w reg
movwf accrate ;move result to accel register
movlw b'00000001' ;select chan0 (prototype)
movwf adcon0 ;and put in A/D control register
;exit from sync call during decel or accel
exit movlw frmcnt ;move no of frame pulses
movwf pulsecnt ;to pulse count
btfss flagreg,endflg ;is end flag set
goto exita ;no - go to exita
return ;and then return
exita btfsc flagreg,stopflg ;is stop flag set?
bcf gpio,pwrop ;yes - turn off power
return ;no - return
;This section scales the result from adresh register depending on
;the magnitude of the scale factor. The result is put in temp2.
;Since this can never be zero and is set to be a min of 1.
;The scaling is provided to cover different modes ie trams with
;short accel & decel periods to fast trains with longer periods.
;This factor is therefore set in software for the application.
scale movf adresh,w ;move A/D result
movwf temp2 ;to temp store
movlw sclfac ;move scale factor
movwf temp1 ;to temp store
scalea bcf status,c ;clear carry
rrf temp2,f ;shift result to right
decfsz temp1,f ;decrement scale factor
goto scalea ;non zero - go back
movf temp2,w ;is temp2 zero?
btfss status,z ;is result zero
goto scaleb ;no - return with measured value
movlw minval ;yes - put min value
movwf temp2 ;into temp2
scaleb bcf adcon0,godone ;clear A/D bit
return ;go back with value
;******decel subroutine
;This is the subroutine run when the car has been detected and the output voltage
;is reduced to zero by pwm (except the sync pulses). At the end of the decel period
;the decel flag is reset and the stop flag is set. Note that the unit can go from
;the decel state to the accel state without stopping.
decel decf pulsecnt,f ;decrement no of frame pulses
movf pwmdc,w ;mov pwm cnt to w
subwf pulsecnt,w ;and subtract from current frame count
btfsc status,z ;is the result zero
bcf gpio,pwrop ;yes - turn off output
movf pulsecnt,f ;check pulse count
btfss status,z ;for zero
return ;non zero - return
decfsz decreg,f ;zero - decrement ratecnt
return
;non zero return
movf decrate,w ;zero - move rate counter
movwf decreg ;to decel rate register
incf pwmdc,f ;increment pwm count
movlw frmcnt ;put frame count in w
subwf pwmdc,w ;and subtract from pwmcnt
btfss status,z ;check if result = zero
return ;no zero - return
bsf flagreg,stopflg ;zero - set stop flag
bcf flagreg,decflg ;and reset dec flag
return
;*****pwmctld subroutine***run only at the start of the decel phase and called
;from the section part of the sync pulse subroutine.
pwmctld movlw frmcnt ;move number of frame pulses
movwf pulsecnt ;to pulse count
clrf pwmdc ;and pwm counter
movf decrate,w ;move decel count
movwf decreg ;to decel reg
return
;*****accel subroutine***This is run either after a car has stopped or during the
;decel phase so that a car can slow down and then accelerate without stopping.
;The "aofflg" is used to turn on only the current pulse during acceleration (see
;return from tmr0 operation). At the end of the accel phase the accflg is reset
;and the endflg is set. When the car leaves the section the endlfg is reset and
;the exit flag set.
accel btfsc flagreg,stopflg ;is stop flag reset?
call pwmctla ;no - call pwm control
movf pwmdc,w ;mov pwm cnt to w
subwf pulsecnt,w ;and subtract from pulse count
btfsc status,c ;is the result zero
goto accela ;non zero - go to accela
bsf flagreg,aofflg ;set aofflg
accela decfsz pulsecnt,f ;decrement pulse count
return ;non zero - return
decfsz accreg,f ;zero - decrement ratecnt
return ;non zero - return
movf accrate,w ;move accel rate to w
movwf accreg ;move rate reg
decfsz pwmdc,f ;decrement pwm count
return ;non zero - return
bsf flagreg,endflg ;zero - set end of accel flag
bcf flagreg,accflg ;and reset accflag
return
;******pwmctla subroutine***only run when acceleration starts from zero speed
pwmctla movlw frmcnt ;move number of frame pulses
movwf pulsecnt ;to pulse count
movwf pwmdc ;and pwm control
movf accrate,w ;move accel rate
movwf accreg ;to accel reg
bcf flagreg,stopflg ;reset stop flag
return
;******initalisation***sets up ports and clears registers
init clrf gpio ;clear all I/O
movlw b'00111100' ;set gpio 2,3,4 & 5
movwf cmcom ;as digital I/O
bsf status,page1 ;set to page 1 to set registers
movlw b'10000001' ;set up
movwf option_reg ;option register
movlw b'00001111' ;make digital I/O
movwf trisio ;0 & 3 as inputs
movlw b'00010011' ;prototype (Ch0 & Ch1) Fosc/8
movwf ansel ;A/D select register
call 3ffh ;get osc calibrate value
movwf osccal ;and put in calibration register
bcf status,page1 ;back to page0
clrf adresh ;clear A/D high register
movlw b'00000001' ;prototype Select Ch0 address
;- left justified - A/D ON
movwf adcon0 ;A/D control register
clrf flagreg ;clear all flags
clrf pulsecnt ;clear pulsecount
clrf decrate ;clear decel
clrf decreg ;registes
clrf accrate ;clear accel
clrf accreg ;registers
clrf pwmdc ;clear pwm duty cycle
clrf temp1 ;clear temporary store
clrf temp2 ;and additional store
movlw exitval ;set up
movwf exitcnt ;exit counter
movlw .240 ;set initial value
movwf tmr0 ;into tmr0 reg
goto main ;then got to main
;******main program
;This decides from the state of the flags, determined during the sync pulses,
;which routine to run
main incfsz tmr0,0 ;is tmr0 complete
goto main ;no loop back
movlw timval ;put tmr0 value
movwf tmr0 ;into tmr0 reg
btfss flagreg,aofflg ;accel control flag on?
goto maina ;no go to maina
bcf gpio,pwrop ;yes - turn off output
bcf flagreg,aofflg ;and accel control flag
maina movf pulsecnt,0 ;check pulse count
btfss status,z ;for zero
goto drive ;non zero - go to drive
call sync ;zero - call sync
goto main ;then go back to main
drive btfsc flagreg,exitflg ;is exit flag set
goto finisc ;yes - go to finisc
btfsc flagreg,endflg ;is end flag on?
goto finis ;yes - go to finis
btfsc flagreg,accflg ;is accel flag on?
goto finisa ;yes - goto finisa
btfsc flagreg,stopflg ;is stop flag on?
goto finis ;yes - go to finisc
btfsc flagreg,decflg ;is decel flag on?
goto finisb ;yes - go to decel
goto finis ;no - go to finisc
finisa call accel ;call acceleration
goto main ;then go to main
finisb call decel ;call decel
goto main ;then go to main
finisc movf exitcnt ;is exit count zero?
btfss status,z ;yes - reset system for next pass
goto finis ;no - go to finisc
bcf flagreg,exitflg ;yes - reset exit flag
movlw exitval ;move number of scans
movwf exitcnt ;into exit counter
finis decf pulsecnt,1 ;dec pulsecnt on run thru
goto main ;go back to check tmr0
end
Website Database Error No: JRND3002