PORTA EQU $00 ; PA7 CLK1 (L) PB7 general status PORTB EQU $01 ; 6 CHOP1(L) 6 " PORTC EQU $02 ; 5 DIR(L) 5 " PORTD EQU $03 ; 4 4 " DDRA EQU $04 ; 3 3 " DDRB EQU $05 ; 2 2 " DDRC EQU $06 ; 1 1 " TSR EQU $13 ; 0 0 " TCR EQU $12 ; PC7 level status port PD7 (mode select port) ICAPHI EQU $14 ; 6 " 6 XXX (Cannot be use!) ICAPLO EQU $15 ; 5 " 5 !SERIAL COM 's status or SPEED ALTIMERHI EQU $1A ; 4 " 4 speed !MAX or 9600 ALTIMERLO EQU $1B ; 3 " 3 OCMPHI EQU $16 ; 2 " 2 start to !MAX or STOP OCMPLO EQU $17 ; 1 " 1 XXX (For serial com) ; 0 " 0 XXX (For serial com) BAUDRATE EQU $0D SCCR1 EQU $0E SCCR2 EQU $0F SCSR EQU $10 SCDAT EQU $11 ******************************************************************* * VARIABLES * ******************************************************************* *Variable LEVEL SPEED CYCLE must be done together *For CYCLE please X 2 yourself (-_-_-_-_- one cycle = two delay period = CYCLE) *At final speed or final frequency cycle=$00 --max delay before change of chopping * cycle=$01 --min delay before change of chopping ; ORG $0020 ;Only allows 32 bytes ;max only $3E [6 bits' levels - 1(which is use for on spot turning code)] ;LEVEL FCB $3E ;no. of acc-1 ORG $160 *set 9 50Hz-2000Hz * FDB $7D,$7F,$80,$82,$84,$85 * FDB $87,$89,$8B,$8D,$8F,$91,$93, CYCLEDELAY FDB $95,$98,$9A FDB $9C,$9F,$A1,$A4,$A7,$A9,$AC,$AF,$B3,$B6 FDB $B9,$BD,$C0,$C4,$C8,$CC,$D0,$D5,$D9,$DE FDB $E3,$E9,$EE,$F4,$FA,$100,$107,$10E,$116,$11E FDB $126,$12F,$139,$142,$14D,$159,$165,$172,$181,$190 FDB $1A1,$1B3,$1C7,$1DC,$1F4,$20E,$22C,$24C,$271,$29B FDB $2CA,$301,$341,$38D,$3E8,$457,$4E2,$683,$9C4,$1388 ORG $0030 CYCLE RMB $40 ;note that memory may over flow CYCLEPOOR RMB $40 ;max is $8F= $47+$47 *PORTS NAME MODEPORT EQU PORTD TLEVEL1 EQU PORTC ;rlevel1 fcb $ff STATUSPORT EQU PORTB ;statusport rmb $1 MOTORPORT EQU PORTA LEVEL RMB $1 MAXLEVEL RMB $1 ;control maximum speed LEVEL1 RMB $1 ;for displaying current level2 CYCLE1 RMB $1 ;no of 2*cycle or period WHICHPROFILE? RMB $1 ;to select optimise or delicated profile *Serial Communication COMMAND RMB $5 ;to store command from main MCU SCI_INT RMB $1 ;to tell if interrupt is activate DIRCHSTATUS RMB $1 ;1- direction changed 0- no direction changed LMOTORSTEP RMB $1 ;number of step left motor stepped RMOTORSTEP RMB $1 ;number of step right motor stepped *temperory storage TEMPA RMB $1 ;protect ACC TEMPX RMB $1 ;protect X TEMP1 RMB $1 ;cannot be use for holding value for long TEMP2 RMB $1 ;cannot be use for holding value for long ******************************************************************* * INITIALIZATION * ******************************************************************* ORG $0400 INITIAL ; CLI ;got interrupt **communication ; LDA #%00110001 ; BRSET 4,MODEPORT,CHBAUDRATE ; LDA #%00000000 ; CHBAUDRATE ; STA BAUDRATE ; LDA #%00000000 ; STA SCCR1 ; LDA #%00100100 ;can be improve to make MCU sleep STA SCCR2 ; **timer ; LDA #%01000000 ;enable timer interrupt STA TCR ; ;disable timer when motor stops ;enable timer if not motor stop at WAITRUNDELAY ;set OCIE (output compare interrupt enable) ;note if OCIE interrupt set the TSR will not work **ports ; LDA #%11111111 ; STA DDRA ;OUT ; STA DDRB ;OUT ; STA DDRC ;OUT ; LDA #!0 ; ; ;MOTORPORT below ; STA STATUSPORT ; STA TLEVEL1 ; **variable ; ;MAXLEVEL below ; STA LEVEL1 ;clearing memories STA CYCLE1 ; STA COMMAND ; STA SCI_INT ; STA DIRCHSTATUS ; STA LMOTORSTEP ; STA RMOTORSTEP ; ; STA WHICHPROFILE? ; ; STA TEMPA ; STA TEMPX ; STA TEMP1 ; STA TEMP2 ; ; lda LEVEL ;stop brclr 2,MODEPORT,startatstop ;to select to stop or travel to maxspeed LDA #!0 ;maxlevel startatstop STA MAXLEVEL ; ; LDA #%00100000 ; STA MOTORPORT ;need to init PORTA because of cmp in stopping ; JSR PROFILE_DOWNLOADING JSR STACC ; JMP WAITRUNDELAY ; ****************************************************************************** PROFILE_DOWNLOADING LDA SCCR2 STA TEMP1 ;save seting AND #%11011111 ;disable SCI interrupt first STA SCCR2 ;receiving data will base on polling LDA #%10101010 ;"ready" code1 STA TLEVEL1 ;report ready signal for downloading CLRX ;indexing variable RECEIVE-CYCLE BRCLR 5,SCSR,RECEIVE-CYCLE LDA SCDAT CMP #$FF ;check end code BEQ RECEIVE1-CYCLE STA CYCLE,X INCX ;index to next position BRA RECEIVE-CYCLE RECEIVE1-CYCLE DECX STX LEVEL LDA #%01010101 ;"ready" code2 STA TLEVEL1 ;report ready signal for downloading CLRX ;indexing variable RECEIVE-CYCLEPOOR BRCLR 5,SCSR,RECEIVE-CYCLEPOOR LDA SCDAT CMP #$FF ;check end code BEQ RECEIVE1-CYCLEPOOR STA CYCLEPOOR,X INCX ;index to next position BRA RECEIVE-CYCLEPOOR RECEIVE1-CYCLEPOOR DECX RECEIVE-ERROR CPX LEVEL BEQ RECEIVE_FINISH JMP ERROR RECEIVE_FINISH STX TLEVEL1 ;report back the number of LEVEL received LDA TEMP1 ;restore original SCCR2 status STA SCCR2 ; RTS ****************************************************************************** ******************************************************************* * COMMUNICATION CODE CONVERTOR * ******************************************************************* ;L FOR VARIABLE1, R FOR VARIABLE2 ;L BIT LSB , R BIT MSB ;L/R MOTOR high bytes/low bytes ;DIRECTION 1-FORWARD 0-BACKWARD ;bit 7= FORWARD !BACKWARD bit 0-6= LEVEL =0 (means stop motor) SORTCOMMAND ; LDX SCI_INT ;sorted status so need to clear SCI_INT LDA COMMAND,X ;load the command receive during SCI_INT CLR SCI_INT ;routine served STA COMMAND ; AND #%00111111 ;obtain the rate of turn only STA MAXLEVEL ;save level ; LDA MOTORPORT ;load present status AND #%00100000 ;filter out the direction bit only STA TEMP1 ;save accumulator ; LDA #%00100000 ;forward code (forward flow shorter because mostly use) BRSET 7,COMMAND,SORT_DIR_FORWARD ; SORT_DIR_BACKWARD ; CLRA ;backward code SORT_DIR_FORWARD ; EOR TEMP1 ;EOR with present motor dir status STA DIRCHSTATUS ;store the toggle dir code LDA #%01000000 ; AND COMMAND ; STA WHICHPROFILE? ; RTS ; ****************************************************************************** *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * THIS IS TO BE COPY AND CHANGE TO USE IN ACCM ;need to change variable MAXLEVEL,LEVEL1 ;add JSR CONTROLLEVEL at the beginning of RUNLEVEL ;del STA TLEVEL1 at SPEED_STATUS GETDATA ;do not need to check for duplicate received data BRCLR 5,SCSR,GETDATA ; ; lda scsr ; ; and #%00001110 ;Over-run, Noise, Framing ERROR ; beq notransmitionerror ;check for transmition error transmitionerror ; ;applied a pulse to IRQ of transmitter for retransmit ;test ; jsr errortest ; ; bra assumenotreceive ; notransmitionerror ; LDA SCDAT ; INC SCI_INT ; LDX SCI_INT ; STA COMMAND,X ; assumenotreceive ; RTI ; ****************************************************************************** ;NOTE: acc is a sub rountine because of the RUNCYCLE interrupt/sub rountine or RTS STACC ;initalise value to start acc of motor LDX LEVEL ; DECX ;first level is dummy level therefore STX LEVEL1 ;start at next level LDA CYCLE,X ; STA CYCLE1 ; BSR SETDELAY ; RTS ;take NOTE above ****************************************************************************** ********MAIN PROGRAM FLOW longest period of program flow here***************** ****************************************************************************** WAITRUNDELAY ; *status update----------------------; SPEED_STATUS ; LDA LEVEL1 ;load offset/speed STA TLEVEL1 ;FOR SLAVE ONLY (report level MASTER MCU) BRSET 5,MODEPORT,WAITRUNDELAY1 ;speed or serial com data status switch SC_STATUS LDX SCI_INT ; LDA COMMAND,X ;load serial communication data *-----------------------------------; WAITRUNDELAY1 STA STATUSPORT ;display data LDA SCI_INT ;is there SCI before coming to wait BEQ WAIT-SCI-TIMER ; JSR SORTCOMMAND ; WAIT-SCI-TIMER ; WAIT ;energy saving at the longest serving ;rountine ;if an ISR of SCI occurs or maybe TIMER ;if there is SCI during wait branch back to WAITRUNDELAY to enter SORTCOMMAND *note that all interrupt can only occur at WAIT instruction BRA WAITRUNDELAY ; ****************************************************************************** * ACCCERATION CHANGE FOR TIMER INTERRUPT * ****************************************************************************** ACC_CHANGE ; BSR SETDELAY ; BSR RUNCYCLE ; RTI ; ******************************************************************* * DELAY SUBROUTINE FOR SPEED/2/4 * ******************************************************************* *NOTE: X must be pass down to this function for use.500us SETDELAY ; STX TEMPX ; STA TEMPA ; LDA ALTIMERHI ; STA TEMP1 ; LDA ALTIMERLO ; LDX LEVEL1 ; LSLX ;X times 2 ADD CYCLEDELAY+1,X ;low byte first STA TEMP2 ; LDA CYCLEDELAY,X ; ADC TEMP1 ; STA OCMPHI ; LDA TSR ; LDA TEMP2 ; STA OCMPLO ;clear OCF LDA TEMPA ; LDX TEMPX ; RTS ; ******************************************************************* ****************************************************************************** * SPEED WITH MAXLEVEL CONTROLLED for left right motor * ****************************************************************************** RUNCYCLE ; CLRX ;X is use in L/R variable indexing ;X not to be use other than indexing LDA MOTORPORT ;load current status of motor EOR #%10000000 ; STA MOTORPORT ;store toggled result back to the port NEXT2 ; DEC CYCLE1 ;decrement CYCLE BEQ RUNLEVEL ; BRA ENDRUNCYCLE ; *-----------------------------------; RUNLEVEL ; LDA MAXLEVEL ; CMP LEVEL ; BEQ STOPMOTOR ; ; LDA DIRCHSTATUS ; BNE CHANGE_DIR ;DIR changed slow motor to change DIR ; LDA LEVEL1 ; CMP MAXLEVEL ; BNE CHANGE_SPEED ;at max speed go & change chopping *-----------------------------------; CHOPPING ; LDA #%01000000 ; CCC ORA MOTORPORT ;set chopping for current indexing STA MOTORPORT ; BRA LOADCYCLE ;skip all INC &DEC level rountine *-----------------------------------; CHANGE_SPEED ; BHI INCSPEED ; ADD #!5 ;minimum speed is not LEVEL but is LEVEL-1 CMP MAXLEVEL ; BLO STOLEVEL ;if level2 is still not reaching maxlevel2 LDA MAXLEVEL ;if level2 is over the wanted maxlevel2 BRA STOLEVEL ; INCSPEED SUB #!1 ; STOLEVEL ; CMP LEVEL ;compare with minimum speed BHS LEVELSTALL ;if higher or same don"t reduce speed STA LEVEL1 ; LEVELSTALL ; PRELOADCYCLE LDA #%10111111 ;clear all chopping because AND MOTORPORT ;it is not at MAXLEVEL STA MOTORPORT ; LOADCYCLE ; LDX LEVEL1 ;load offset LDA CYCLE,X ;load wanted value BRCLR 6,WHICHPROFILE?,CYCLEPROFILESELECTED; LDA CYCLEPOOR,X ; CYCLEPROFILESELECTED ; STA CYCLE1 ;store wanted value to variable BRA ENDRUNCYCLE ; *-----------------------------------; CHANGE_DIR ;mostly for on spot turn LDA DIRCHSTATUS ; EOR MOTORPORT ; STA MOTORPORT ; CLR DIRCHSTATUS ; BRA RESTART_MOTOR ; STOPMOTOR ; LDA #%00100000 ;set ready the direction ORA MOTORPORT ; STA MOTORPORT ; LDA TCR ; CLR TCR ; WAIT ; STA TCR ; RESTART_MOTOR ; JSR STACC ;restart motor acceration ENDRUNCYCLE ; RTS ; ****************************************************************************** ****************************************************************************** ERROR LDA #%00001111 STA STATUSPORT errorsignal ;test lda statusport ;test eor #$ff ;test sta statusport ;test BSR DELAY bra errorSIGNAL ;test ****************************************************************************** DELAY STA TEMPA STX TEMPX LDA #$00 COUNT1 CLRX ;test COUNT2 DECX ;test bne COUNT2 DECA BNE COUNT1 LDA TEMPA LDX TEMPX RTS ****************************************************************************** *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ WASTE_NO_USE ; RTI ; ******************************************************************* * RESET VECTOR * ******************************************************************* ORG $1FDF ;initialise RAM memory space FCB $C0 ; ORG $1FFE ;RESET VECTOR FDB INITIAL ; ORG $1FFA ;IRQ VECTOR(temp use as serial com) FDB GETDATA ; ORG $1FFC ;SWI VECTOR (software interrupt) FDB WASTE_NO_USE;RECALLCOMMAND ORG $1FF6 ;SCI VECTOR (serial communication) FDB GETDATA ; ORG $1FF8 ;TIMER VECTOR (for half period) FDB ACC_CHANGE ;WASTE_NO_USE