|
Registered User
Join Date: Jul 2004
Posts: 11
|
The solution
I worked a final solution, which involved rethinking the code entirely, here it is for anyone interested
Code:
$NOMOD51
$INCLUDE (REG552.H)
ORG 0 /*PROGRAM START VECTOR*/
JMP main
ORG 0003H /*EXTERNAL INT0 START VECTOR*/
JMP runKeyISR
/************************************************
*location for KeyID = A *
* *
*Main program sets interrupt INT0, this then *
*calls the scanKeypad, clearPad then runs Mx and*
* jumps back to refreshing the motors, waiting *
*for INT0 *
* Ready for emulation 17/2/05. c Toby Mole 2005 *
************************************************/
ORG 0030H /*MAIN START VECTOR*/
main:
MOV TMOD, #11H /*SET T0 & T1 AS 16 BIT TIMERS*/
SETB IT0 /*SET EX0 AS LEVEL ACTIVATED*/
SETB EX0 /*SET EXTERNAL KEY PRESS INT*/
MOV PWMP, #0EAH /*Fpwm = 12Mhz / (2x (1+EAH) x255) = 100Hz*/
CLR P1.0 /*SET ROWS AS OUTPUTS FOR SCAN*/
CLR P1.1
CLR P1.2
CLR P1.3
CLR P1.4
SETB P1.6 /*SET COLUMNS AS INPUTS FOR SCAN*/
SETB P1.7
CALL motorCenter /*CENTRE ALL MOTORS AND INITIALISE R1-R5*/
SETB EA /*ENABLE INTS*/
loop: CALL refresh
JMP loop /*WAIT FOR KEY DOWN INT IF NO KEY FOUND YET*/
runKeyISR:
CLR EX0 /*DISABLE INT0 INT*/
CALL debounce /*RUN DELAY TO CANCEL OUT DEBOUNCE*/
CALL scanPad /*GET KEY DOWN NUMBER*/
CALL clearPad /*IN PLACE OF waitForKeyRelease*/
CALL disablePins/*MAKE SURE ALL PINS ARE DISABLED FROM REFRESH ROUTINE*/
CALL loadValue /*SELECT Rx AND MOVE CURRENT mX VALUE TO PWM0*/
CALL enablePin /*ENABLE Mx PIN*/
CALL run /*INC PWM & RUN DELAY*/
CALL disablePins/*DISABLE*/
CALL copyNewValue /*COPY NEW CURRENT VALUE BACK TO Rx*/
CLR IE0 /*CLR INT0 FLAG*/
SETB EX0 /*ENABLE INT0 INT*/
RETI
motorCenter:
/********************************************************
*This function loads the centering value to the PWM, *
*enables all motors and runs them, copies the *
*centering (current), value to the corresponding *
*registers. Then returns *
********************************************************/
/*LOAD UP PWM0 FOR CENTERING*/
MOV PWM0, #0EFH /*DC = PWM0 / (255-PWM0) I.E. 239=14.93%=EF*/
MOV P2, #00H /*ENABLE (CLEAR) ALL O/P PIN BUFFERS*/
CALL delay /*DELAY FOR MOTOR MOVE TIME*/
MOV P2, #1FH /*DISABLE (SET) ALL O/P PIN BUFFERS*/
MOV R1, PWM0 /*COPY PWM0 CENTERED VALUE TO Rx*/
MOV R2, PWM0
MOV R3, PWM0
MOV R4, PWM0
MOV R5, PWM0
RET
refresh:
/********************************************************
*This function refreshes all motors with their current *
*values, and then returns. *
********************************************************/
MOV A, #01H /*LOAD FOR M1*/
CALL loadValue /*SELECT REGISTER AND COPY INTO PWM0*/
CALL enablePin /*ENABLE PIN1*/
CALL delay /*RUN M1*/
CALL disablePins/*DISABLE PIN*/
MOV A, #02H /*LOAD FOR M2*/
CALL loadValue /*SELECT REGISTER AND COPY INTO PWM0*/
CALL enablePin /*ENABLE PIN2*/
CALL delay /*RUN M2*/
CALL disablePins/*DISABLE PIN*/
MOV A, #03H /*LOAD FOR M3*/
CALL loadValue /*SELECT REGISTER AND COPY INTO PWM0*/
CALL enablePin /*ENABLE PIN3*/
CALL delay /*RUN M3*/
CALL disablePins/*DISABLE PIN*/
MOV A, #04H /*LOAD FOR M4*/
CALL loadValue /*SELECT REGISTER AND COPY INTO PWM0*/
CALL enablePin /*ENABLE PIN4*/
CALL delay /*RUN M4*/
CALL disablePins/*DISABLE PIN*/
MOV A, #05H /*LOAD FOR M5*/
CALL loadValue /*SELECT REGISTER AND COPY INTO PWM0*/
CALL enablePin /*ENABLE PIN5*/
CALL delay /*RUN M5*/
CALL disablePins/*DISABLE PIN*/
RET
debounce:
/********************************************************
*This function is a delay loop to prevent wrong readings*
*from the keypad after INT0 due to contact bounce *
********************************************************/
CLR TR0 /*STOP TIMER0 IN CASE ITS LEFT RUNNING*/
MOV TH0, #8AH /*SET TIMER0 FOR 35,536 (8AD0H)*/
MOV TL0, #0D0H
SETB TR0 /*START TIMER0*/
JNB TF0, $ /*WAIT FOR OVERFLOW*/
CLR TF0 /*CLEAR OVERFLOW*/
CLR TR0 /*STOP TIMER0*/
RET
scanPad:
/********************************************************
*This function selects a row for the colscan function *
*Then returns. *
********************************************************/
MOV A,0H /*CLEAR A READY FOR NEW KEY DOWN NUMBER*/
CLR P1.0 /*CLEAR 1ST ROW*/
SETB P1.1 /*SET ALL OTHER ROWS*/
SETB P1.2
SETB P1.3
SETB P1.4
CALL colScan /*SCAN THE COLUMNS*/
JB 40H, return /*TEST FOR KEY*/
SETB P1.0
CLR P1.1 /*CLEAR 2ND ROW*/
SETB P1.2 /*SET ALL OTHER ROWS*/
SETB P1.3
SETB P1.4
CALL colScan /*SCAN THE COLUMNS*/
JB 40H, return /*TEST FOR KEY*/
SETB P1.0
SETB P1.1
CLR P1.2 /*CLEAR 3RD ROW*/
SETB P1.3 /*SET ALL OTHER ROWS*/
SETB P1.4
CALL colScan /*SCAN COLUMNS*/
JB 40H, return /*TEST FOR KEY*/
SETB P1.0 /*SET ALL OTHER ROWS*/
SETB P1.1
SETB P1.2
CLR P1.3 /*CLEAR 4TH ROW*/
SETB P1.4
CALL colScan /*SCAN COLUMNS*/
JB 40H, return /*TEST FOR KEY*/
SETB P1.0 /*SET ALL OTHER ROWS*/
SETB P1.1
SETB P1.2
SETB P1.3
CLR P1.4 /*CLEAR 5TH ROW*/
CALL colScan /*SCAN COLUMNS*/
return: ADD A, #01H /*BIAS KEYID (INC A?)*/
RET
colScan:
/********************************************************
*This function checks each column in a row and *
*increments a counter, keyID, if keydown not found. *
********************************************************/
JNB P1.6, skip /*SCAN FIRST COLUNM*/
INC A /*INC A FOR KEY ID*/
JNB P1.7, skip /*SCAN SECOND COLUMN*/
INC A /*INC A FOR KEY ID*/
RET /*RETURN IF NO KEY FOUND ON THAT COLUMN*/
skip: SETB 40H /*KEY FOUND SO SET TO JUMP OUT OF JNB WAIT LOOP*/
RET
clearPad:
/********************************************************
*This function clears the rows ready for a new reading. *
* Then returns *
********************************************************/
CLR P1.0 /*CLEAR THE KEYPAD ROWS READY FOR NEXT SCAN*/
CLR P1.1
CLR P1.2
CLR P1.3
RET
loadValue:
/********************************************************
* This function uses the keyID in the ACC, to *
*select the correct register from which it obtains the *
*corresponding current motor's PWM value and loads it to*
*the PWM0. Then returns *
********************************************************/
CJNE A, #01H, mov1skip /*IF 1 COPY FROM R1*/
MOV PWM0, R1 /*MOV CURRENT M1 VALUE TO PWM0*/
JMP endSkip /*JUMP TO END OF FUNCTION*/
mov1skip:
CJNE A, #02H, mov2skip /*IF 2 COPY FROM R2*/
MOV PWM0, R2 /*MOV CURRENT M2 VALUE TO PWM0*/
JMP endSkip /*JUMP TO END OF FUNCTION*/
mov2skip:
CJNE A, #03H, mov3skip /*IF 3 COPY FROM R3*/
MOV PWM0, R3 /*MOV CURRENT M3 VALUE TO PWM0*/
JMP endSkip /*JUMP TO END OF FUNCTION*/
mov3skip:
CJNE A, #04H, mov4skip /*IF 4 COPY FROM R4*/
MOV PWM0, R4 /*MOV CURRENT M4 VALUE TO PWM0*/
JMP endSkip /*JUMP TO END OF FUNCTION*/
mov4skip:
CJNE A, #05H, mov5skip /*IF 5 COPY FROM R5*/
MOV PWM0, R5 /*MOV CURRENT M5 VALUE TO PWM0*/
JMP endSkip
mov5skip:
CJNE A, #06H, mov6skip /*IF 6 COPY FROM R1*/
MOV PWM0, R1 /*MOV CURRENT M1 VALUE TO PWM0*/
JMP endSkip /*JUMP TO END OF FUNCTION*/
mov6skip:
CJNE A, #07H, mov7skip /*IF 7 COPY FROM R2*/
MOV PWM0, R2 /*MOV CURRENT 2 VALUE TO PWM0*/
JMP endSkip /*JUMP TO END OF FUNCTION*/
mov7skip:
CJNE A, #08H, mov8skip /*IF 8 COPY FROM R3*/
MOV PWM0, R3 /*MOV CURRENT M3 VALUE TO PWM0*/
JMP endSkip /*JUMP TO END OF FUNCTION*/
mov8skip:
CJNE A, #09H, mov9skip /*IF 9 COPY FROM R4*/
MOV PWM0, R4 /*MOV CURRENT M4 VALUE TO PWM0*/
JMP endSkip /*JUMP TO END OF FUNCTION*/
mov9skip:
CJNE A, #10H, endSkip /*IF 10 COPY FROM R5*/
MOV PWM0, R5 /*MOV CURRENT M5 VALUE TO PWM0*/
JMP endSkip /*JUMP TO END OF FUNCTION*/
endSkip:RET /*RETURN TO MAIN*/
enablePin:
/********************************************************
*This function uses the keypadid in ACC to enable the *
*correct Mx pin. Then returns *
********************************************************/
CJNE A, #01H, en1skip /*IF NOT 1 TRY NEXT*/
CLR P2.0 /*IF 1 ENABLE (CLEAR) PIN*/
JMP en10skip /*JUMP TO END*/
en1skip:CJNE A, #02H, en2skip /*IF NOT 2 TRY NEXT*/
CLR P2.1
JMP en10skip
en2skip:CJNE A, #03H, en3skip /*IF NOT 3 TRY NEXT*/
CLR P2.2
JMP en10skip
en3skip:CJNE A, #04H, en4skip /*IF NOT 4 TRY NEXT*/
CLR P2.3
JMP en10skip
en4skip:CJNE A, #05H, en5skip /*IF NOT 5 TRY NEXT*/
CLR P2.4
JMP en10skip
en5skip:CJNE A, #06H, en6skip /*IF NOT 6 TRY NEXT*/
CLR P2.0
JMP en10skip
en6skip:CJNE A, #07H, en7skip /*IF NOT 7 TRY NEXT*/
CLR P2.1
JMP en10skip
en7skip:CJNE A, #08H, en8skip /*IF NOT 8 TRY NEXT*/
CLR P2.2
JMP en10skip
en8skip:CJNE A, #09H, en9skip /*IF NOT 9 TRY NEXT*/
CLR P2.3
JMP en10skip
en9skip:CJNE A, #10H, en10skip /*IF NOT 10 TRY NEXT*/
CLR P2.4
JMP en10skip
en10skip:
RET
run:
/********************************************************
*This function checks that the value is within the Mx *
*boundries, if it is, it changes the pulse width for the*
*Mx by xxus then runs a delay for 5ms, and returns. *
*If not, it returns doing nothing. *
********************************************************/
MOV R0, PWM0 /*MOV PWM0 TO R0 FOR COMPARE PAIR*/
CJNE R0, #0F1H, skip1 /*UPPER LIMIT (241) AT 17% D.C.*/
RET /*IF NOT WITHIN LIMIT DO NOTHING AND RETURN*/
skip1: CJNE R0, #0EDH, skip1a /*LOWER LIMIT (237) AT 13% D.C.*/
RET /*IF NOT WITHIN LIMIT DO NOTHING AND RETURN*/
skip1a: CJNE A, #01H, run2 /*IF 1 RUN 1 UP*/
JMP skip2
run2: CJNE A, #02H, run3 /*IF 2 RUN 2 UP*/
JMP skip2
run3: CJNE A, #03H, run4 /*IF 3 RUN 3 UP*/
JMP skip2
run4: CJNE A, #04H, run5 /*IF 4 RUN 4 UP*/
JMP skip2
run5: CJNE A, #05H, run6 /*IF 5 RUN 5 UP*/
JMP skip2
run6: CJNE A, #06H, run7 /*IF 6 RUN 1 DOWN*/
JMP skip3
run7: CJNE A, #07H, run8 /*IF 7 RUN 2 DOWN*/
JMP skip3
run8: CJNE A, #08H, run9 /*IF 8 RUN 3 DOWN*/
JMP skip3
run9: CJNE A, #09H, run10 /*IF 9 RUN 4 DOWN*/
JMP skip3
run10: CJNE A, #10H, endSkip1 /*IF 10 RUN 5 DOWN*/
JMP skip3
RET /*IN CASE NO ID FOUND, RETURN*/
skip2: MOV R0, A /*TEMPORARILY SAVE ACC TO R0*/
MOV A, PWM0 /*COPY CURRENT Mx VALUE FROM PWM0 TO A*/
INC A /*STEP PWM0 UP BY 1%*/
MOV PWM0, A /*MOV NEW RESULTANT VALUE INTO PWM0*/
CALL delay /*RUN DELAY WHILE Mx MOVES*/
MOV A, R0 /*MOVE ACC BACK FROM R0*/
RET
skip3: MOV R0, A /*TEMPORARILY SAVE ACC TO R0*/
MOV A, PWM0 /*COPY CURRENT Mx VALUE FROM PWM0 TO A*/
DEC A /*STEP PWM0 DOWN BY 1%*/
MOV PWM0, A /*MOV NEW RESULTANT VALUE INTO PWM0*/
CALL delay /*RUN DELAY WHILE Mx MOVES*/
MOV A, R0 /*MOVE ACC BACK FROM R0*/
endSkip1:
RET
disablePins:
/********************************************************
*This function disables all pins including any enabled *
*so as to stop any PWM output, and to make pins ready *
*for re-entry to the refresh loop. Then returns *
********************************************************/
MOV P2, #1FH /*DISABLE (SET) ALL O/P PIN BUFFERS*/
RET
copyNewValue:
/********************************************************
*This function uses the keyID in the ACC, to select the *
*correct register to which it copies the corresponding *
*current motor's new PWM value. Then returns *
********************************************************/
CJNE A, #01H, testv2 /*IF 1 copy MOTOR 1*/
MOV R1, PWM0 /*MOV NEW M1 VALUE TO R1*/
JMP endSkip2 /*JUMP TO END OF FUNCTION*/
testv2: CJNE A, #02H, testv3 /*IF 2 copy MOTOR 2*/
MOV R2, PWM0 /*MOV NEW M2 VALUE TO R2*/
JMP endSkip2 /*JUMP TO END OF FUNCTION*/
testv3: CJNE A, #03H, testv4 /*IF 3 copy MOTOR 3*/
MOV R3, PWM0 /*MOV NEW M3 VALUE TO R3*/
JMP endSkip2 /*JUMP TO END OF FUNCTION*/
testv4: CJNE A, #04H, testv5 /*IF 4 copy MOTOR 4*/
MOV R4, PWM0 /*MOV NEW M4 VALUE TO R4*/
JMP endSkip2 /*JUMP TO END OF FUNCTION*/
testv5: CJNE A, #05H, testv6 /*IF 5 copy MOTOR 5*/
MOV R5, PWM0 /*MOV NEW M5 VALUE TO R5*/
JMP endSkip2 /*JUMP TO END OF FUNCTION*/
testv6: CJNE A, #06H, testv7 /*IF 6 copy MOTOR 1*/
MOV R1, PWM0 /*MOV NEW M1 VALUE TO R1*/
JMP endSkip2 /*JUMP TO END OF FUNCTION*/
testv7: CJNE A, #07H, testv8 /*IF 7 copy MOTOR 2*/
MOV R2, PWM0 /*MOV NEW M2 VALUE TO R2*/
JMP endSkip2 /*JUMP TO END OF FUNCTION*/
testv8: CJNE A, #08H, testv9 /*IF 8 copy MOTOR 3*/
MOV R3, PWM0 /*MOV NEW M3 VALUE TO R3*/
JMP endSkip2 /*JUMP TO END OF FUNCTION*/
testv9: CJNE A, #09H, testv10 /*IF 9 copy MOTOR 4*/
MOV R4, PWM0 /*MOV NEW M4 VALUE TO R4*/
JMP endSkip2 /*JUMP TO END OF FUNCTION*/
testv10:CJNE A, #10H, endSkip2 /*IF 10 copy MOTOR 5*/
MOV R5, PWM0 /*MOV NEW M5 VALUE TO R5*/
endSkip2:
RET /*RETURN TO MAIN*/
delay:
/********************************************************
*This function is a basic delay for 5ms while PWM is *
*output. *
********************************************************/
CLR TR1 /*STOP TIMER1 IN CASE ITS LEFT RUNNING*/
MOV TH1, #0ECH /*SET TIMER1 FOR 60,536 (EC78H)*/
MOV TL1, #78H
SETB TR1 /*START TIMER1*/
JNB TF1, $ /*WAIT FOR OVERFLOW*/
CLR TF1 /*CLEAR OVERFLOW*/
CLR TR1 /*STOP TIMER1*/
RET
END
Note the first 2 lines; The first suppresses reg51 code so the second can safely include reg552 (Im using a 87C552) 
Last edited by toblerone; 02-17-2005 at 12:09 PM.
|