The program .
********************************************
*Variable used in the program *
********************************************
*Variables used when reading the ADConvertor
SPCR EQU $28
SPSR EQU $29
SPDR EQU $2A
PORTD EQU $08
DDRD EQU $09
*Variables used to send to the display
admsb RMB 1
adlsb RMB 1
devmsb RMB 1
devlsb RMB 1
COUNTER RMB 1
tpm1 RMB 1
tpm2 RMB 1
ORG $E000
Main
**********************************************************************************
******************************************** *
*Initialisation * *
******************************************** *
**********************************************************************************
*******************************************************
*Initialisation of the programs *
*******************************************************
LDS #$00FF
LDX #$1000
BSET $24,X %10000011 *Timer overflow interrupt enabled; timer is prescaled by 16, timer step every 8 µs
BSET $22,X %00000001 *Input capture 3 interrupt enabled
BSET $21,X %00000001 *Input capture 3 on rising edges only
JSR Initserial *Initialize the SCI
JSR InitSPI
BSET $26,X %00001000 *DDRA3 as an output
BCLR $00,X %00001000 *be sure that portA3 is disabled
JSR Klok *Wait a bit before initialize the dispal
Init
********************************************
*Initialize the display *
********************************************
LDAA #%00111000 * 2-line-mode; 5*7dots
LDX #$1000
JSR Schrijfgetal
LDAA #$00
JSR Schrijfgetal
LDX #$1000
BSET $00,X %00001000
BSET $00,X %01000000
BCLR $00,X %00001000
BCLR $00,X %01000000
Init2
LDAA #%00001100 * display on; cursor off; blink off
LDX #$1000
JSR Schrijfgetal
LDAA #$00
JSR Schrijfgetal
LDX #$1000
BSET $00,X %00001000
BSET $00,X %01000000
BCLR $00,X %00001000
BCLR $00,X %01000000
Init3
LDAA #%00000001 * Clear entire display
LDX #$1000
JSR Schrijfgetal
LDAA #$00
JSR Schrijfgetal
LDX #$1000
BSET $00,X %00001000
BSET $00,X %01000000
BCLR $00,X %00001000
BCLR $00,X %01000000
JSR Klok * wait for more than 1.53ms
Init4
LDAA #%00000110 * decrement mode; entire shift off
LDX #$1000
JSR Schrijfgetal
LDAA #$00
JSR Schrijfgetal
LDX #$1000
BSET $00,X %00001000
BSET $00,X %01000000
BCLR $00,X %00001000
BCLR $00,X %01000000
**********************************************************************************
******************************************** *
*Main program * *
******************************************** *
**********************************************************************************
***********************************************************************************
*The first step is to read all the points and the speed, and calculate the values.*
***********************************************************************************
Read
Lezen
PSHX
LDD #$0000 *The begin value is 0
LDY #$0000
STD $0040 * Place were the sum is put
LDX #$F800 * We calculate 1024 points, in 16bit. This gives $800 in the counter
Blijflezen
JSR LeesADC * Read the ADC
LDAA admsb
LDAB adlsb
STD $00,X * Store the value in the memory
JSR tellen * Count the total, for the average calculation
DEX * Decrement the counter twice, because the memory is in 2 bytes
DEX
CPX #$F000 * Stop reading after $400 times
BNE Blijflezen
STY $0038 * Store the overload of information(24-bit) next to the sum.
PULX
JSR Gemmidelde * Calculate the average
JSR Deviatie * Calculate the deviation
JSR Toerental * Calculate the speed
JSR Adjust * Adjust the information from V to Nm
************************************************
*Write all the information to the display *
************************************************
Write
Opnieuw
LDAA #%10000000 * Start the writing at the left corner of the screen
LDX #$1000
JSR Schrijfgetal
LDAA #$00
JSR Schrijfgetal
LDX #$1000
BSET $00,X %00001000
BSET $00,X %01000000
BCLR $00,X %00001000
BCLR $00,X %01000000
LDAA admsb * Load the average
LDAB adlsb
JSR Schrijf_koppel * Write the average
LDAA #'+ * Write +/-
JSR WriteLcd
LDAA #'/
JSR WriteLcd
LDAA #'-
JSR WriteLcd
LDAA devmsb * Load the deviation
LDAB devlsb
JSR Schrijf_koppel * Write the deviation
LDAA #'N * Write Nm
JSR WriteLcd
LDAA #'m
JSR WriteLcd
Newline
LDAA #%11000000 * Begin at the next line
LDX #$1000
JSR Schrijfgetal
LDAA #$00
JSR Schrijfgetal
LDX #$1000
BSET $00,X %00001000
BSET $00,X %01000000
BCLR $00,X %00001000
BCLR $00,X %01000000
LDAA #'C * Write CFR
JSR WriteLcd
LDAA #'F
JSR WriteLcd
LDAA #'R
JSR WriteLcd
LDAA #$20 * Write a space 6 times
JSR WriteLcd
LDAA #$20
JSR WriteLcd
LDAA #$20
JSR WriteLcd
LDAA #$20
JSR WriteLcd
LDAA #$20
JSR WriteLcd
LDAA #$20
JSR WriteLcd
LDAA tpm1 * Load the speed
LDAB tpm2
JSR Schrijf_tpm * Write the speed
LDAA #'t * Write tpm
JSR WriteLcd
LDAA #'p
JSR WriteLcd
LDAA #'m
JSR WriteLcd
JMP Read * End of the program, start counting again.
**********************************************************************************
*END OF MAIN PROGRAM (The rest is for the perfect working of the microcontroller)*
**********************************************************************************
Prog3
JSR Schrijfniets
JMP Prog3
Loop JMP Loop
**********************************************************************************
******************************************** *
*Subprograms * *
******************************************** *
**********************************************************************************
*1.**************************************************************************************
*****************************************************************************************
*Programs to write the numerical values on the display, since they arent in ASCII *
*****************************************************************************************
Duizenden
LDX #$03E8 * Load X with 1000
IDIV * Divide
STAA $0010 *Store the rest in the RAM-memory
STAB $0011
XGDX *Exchange X to A to write it on the display
TBA
LDAB #$30 * In ASCII, a number got the form $3X
ABA * Load it to change it to ASCII
JSR WriteLcd* Write to the Display
LDAA $0010 * Load the rest
LDAB $0011
RTS
Honderden
LDX #$0064 * Load X with 100
IDIV
STAA $0010
STAB $0011
XGDX
TBA
LDAB #$30
ABA
JSR WriteLcd
LDAA $0010
LDAB $0011
RTS
Tientallen
LDX #$000A * Load X with 10
IDIV
STAA $0010
STAB $0011
XGDX
TBA
LDAB #$30
ABA
JSR WriteLcd
LDAA $0010
LDAB $0011
RTS
Eenheden
LDX #$0001
IDIV
STAA $0010
STAB $0011
XGDX
TBA
LDAB #$30
ABA
JSR WriteLcd
LDAA $0010
LDAB $0011
RTS
***************************************************
*Torque-writing, with a comma in the middle *
***************************************************
Schrijf_koppel
JSR Duizenden * Divide by 1000, and write it
JSR Honderden * Divide by 100, write it
STAA $0010 * Put the rest in the RAM memory
LDAA #', * Write the comma
JSR WriteLcd
LDAA $0010 * Load the rest
JSR Tientallen * Divide by ten, write it
JSR Eenheden * Write the rest
RTS
******************************************************************
*Speed-writing. Identical to the torque-writing, except the comma*
******************************************************************
Schrijf_tpm
JSR Duizenden
JSR Honderden
JSR Tientallen
JSR Eenheden
RTS
*2.******************************************************
*********************************************************
*Main programs to write on the Display, using A3-A6 *
*********************************************************
************************************************************
*Program to write a value in A (in ASCII) to the screen *
************************************************************
WriteLcd
LDX #$1000
JSR Schrijfgetal * Write the value to the digital/parallel transmittor CD4094
LDAA #$02 * RS=1; RW=0 , this gives a 2
JSR Schrijfgetal * Write the value to the digital/parallel transmittor CD4094
LDX #$1000
BSET $00,X %00001000 * Set the enable signal(A3) on the display
BSET $00,X %01000000 * Send the data from the CD4094 to the display, output enable (A7)
BCLR $00,X %00001000 * Stop the enable signal
BCLR $00,X %01000000 * Stop the data
RTS
************************************************************
*Send a 0 to the digital/parallel transmitter *
************************************************************
Nul
LDX #$1000
BCLR $00,X %00010000 * Set the data output (A4) to 0
BSET $00,X %00100000 * Give 1 clock-signal (A3) to the transmitter, to send the bit
BCLR $00,X %00100000
LSRA * Set the next bit in the first place
RTS
************************************************************
*See if the bit to send is a 0 or 1 *
************************************************************
Een
LDX #$1000
BSET $00,X %00010000 * Only difference with the other, it puts a 1
BSET $00,X %00100000
BCLR $00,X %00100000
LSRA
RTS
************************************************************
*See if the bit to send is a 0 or 1 *
************************************************************
Stuurbit
LDX #$0000
STAA $0000
BRCLR $00,X %00000001 Nul * If the bit is 0, then go to next subroutine
BRSET $00,X %00000001 Een * If the bit is 1, then go to next subroutine
LDX #$1000
RTS
************************************************************
*Send an 8-bit value to the digital/parallel transmitter *
************************************************************
Schrijfgetal
LDX #$1000
BCLR $00,X %00110000 * Be sure that clock(A5) and data(A4)-signal are zero
BSET $00,X %01000000 *
JSR Stuurbit * Send the first bit, and replace it by the next one
JSR Stuurbit
JSR Stuurbit
JSR Stuurbit * Do this 8 times, to send the whole 8-bit value
JSR Stuurbit
JSR Stuurbit
JSR Stuurbit
JSR Stuurbit
LDX #$1000
RTS
*3.******************************************************
*********************************************************
*Program to use the SCI *
*********************************************************
*********************************************************
*Initiate the SCI *
*********************************************************
Initserial
PSHA
PSHX
LDAA #$30
STAA $102B
LDX #$1000
BSET $2D,X %00001100
PULX
PULA
RTS
*********************************************************
*Send a character *
*********************************************************
Putchar
PSHX
LDX #$1000
BRCLR $2E,X $80 *
STAB $2F,X
PULX
RTS
*3.******************************************************
*********************************************************
*Program to use the SPI *
*********************************************************
*********************************************************
*Initiate the SPI *
*********************************************************
InitSPI
PSHX
PSHA
LDX #$1000 * load Index Register X with starting address of register block (= 1000)
LDAA #%00111010 * SPI outputs (SCK, MOSI, Tx and /SS configured as an output)
* configured by setting the Data Direction Register bits
STAA DDRD,X * load data into the Data Direction Register
LDAA #%01010000 * set data for SPCR
STAA SPCR,X * load data into the SPCR
* LDAA #%00101111 * set /SS and MOSI high; set SCK low
* STAA PORTD,X * load data into PORTD to set-up SPI control lines
BSET PORTD,X %00100000 * set /SS high
BSET PORTD,X %00000010 * set TxD high
PULA
PULX
RTS
*********************************************************
*Use the SPI to read the ADConverter *
*********************************************************
LeesADC
PSHX
LDX #$1000
BCLR PORTD,X %00100000 * bring /CS low !!!
LDAA #%10000000 * load control-byte into Accumulator(A)
STAA SPDR,X * load control-byte into SPDR
WAIT3 LDAA SPSR,X * beginning of loop to poll SPSR
BITA #%10000000 * mask all bits except SPIF (transfer complete) flag
BEQ WAIT3 * branch if SPIF is not set to beginning of loop
LDAA SPDR,X * read the SPDR to clear the SPIF bit in the SPSR
WAIT4 LDAA PORTD,X * beginning of loop to poll PORTD bit RxD: goes high when conversion is complete
* connect the Rxd-pin to the SSTRB-pin on the MAX1270
BITA #%00000001 * mask all bits except RxD (conversion complete)
BEQ WAIT4 * branch if RxD is not set to beginning of loop
LDAA #%00000000
STAA SPDR,X * Write to SPDR to start data transfer
WAIT5 LDAA SPSR,X * beginning of loop to poll SPSR
BITA #%10000000 * mask all bits except SPIF (transfer complete) flag
BEQ WAIT5 * branch if SPIF is not set to beginning of loop
LDAA SPDR,X * load received byte into Accumulator(A)
STAA admsb * store received byte in memory location admsb
LDAA #%00000000
STAA SPDR,X * Write to SPDR to start data transfer
WAIT6 LDAA SPSR,X * beginning of loop to poll SPSR
BITA #%10000000 * mask all bits except SPIF (transfer complete) flag
BEQ WAIT6 * branch if SPIF is not set to beginning of loop
LDAB SPDR,X * load received byte into Accumulator(B)
BSET PORTD,X %00100000 * bring /CS high
LDAA admsb * load 8 most significant bits into Accumulator(A)
LSRD * shift bits in Double Accumulator(D) one right, replace
LSRD * Accumulator(A) bit 7 with 0 (, store Accumulator(B) bit 0 in CCR C-bit)
LSRD * four times LSRD to put 8 least significant bits in Accumulator(B)
LSRD * and put 4 most significant bits in 4 least significant Accumulator(A) bits
STAA admsb * store Accumulator(A) in admsb
STAB adlsb * store Accumulator(B) in adlsb
LDAB admsb
JSR Putchar * Send the admsb to the SCI
LDAB adlsb
JSR Putchar * Send the adlsb to the SCI
PULX
RTS
*4.***********************************************************************
**************************************************************************
*Programs to calculate the average, the deviation, and adjust the values.*
**************************************************************************
**************************************************************************
*Adjust the average and the deviation by multiplying it with 2.44 *
**************************************************************************
* After a study, we found out that the result given by the ADC must be multiplyed with 1.22
Adjust
LDAA admsb * Load the average
LDAB adlsb
STD $0030 * Save the average in the RAM memory
ADDD $0030 * Add the result 4 times
STD $0034 * Save the new value in the memory
LDX #$000A
IDIV * Divide it by 10, gives *0.2
XGDX
STD $0032 * Put the result in the memory
LDD $0034
LDX #$0064
IDIV * divide it a second time with 100, gives *0.02
XGDX
STD $0036 * Put the result in memory
LDD $0030
ADDD $0032
ADDD $0036 * Add all results, it gives a *1.22
STAA admsb * Save the new values
STAB adlsb
LDAA devmsb
LDAB devlsb
STD $0030
ADDD $0030
STD $0034
LDX #$000A
IDIV
XGDX
STD $0032
LDD $0034
LDX #$0064
IDIV
XGDX
STD $0036
LDD $0030
ADDD $0032
ADDD $0036
STAA devmsb
STAB devlsb
RTS
**************************************************************************
*Calculate the average *
**************************************************************************
Gemmidelde
PSHX
LDD $0039 * The sum of all $400 points is a 24bit number located from $0039 to $0041
* We only load the 16-bit number, this is already a division by $100
LDX #$0004 * Load X with 4, for the second division
IDIV * Divide the sum by 4
XGDX
STAA admsb * Put the average back in memory
STAB adlsb
PULX
RTS
**************************************************************************
*Increase the sum at every new reading *
**************************************************************************
* This procedure is placed in the reading-proces, after reading a new number, located in D
tellen
PSHX
LDX #$0040 * This is the adress of the sum
ADDD $00,X * Add the new value with the already-existing sum
BCS increase * See if there is an overflow, then increase the second sum Y
voort * Come back to the process
CLC * Clear the carry bit for next addition
STD $0040 * Put the total value in the sum
PULX
RTS
increase
INY * Increase Y, used as the second adress of the sum
JMP voort * Go back to the procedure
**************************************************************************
*Calculate the deviation *
**************************************************************************
Deviatie
PSHX
LDD #$0000 * Reset D; sum of the deviations
LDX #$0060
STD $00,X * Put the sum in RAM-memory $0060
LDY #$0000 * Use Y as overload, set it at 0
LDAA admsb * Load the average
LDAB adlsb
LDX #$F800 * Load X as $800, for loading the 1024 adresses of the values
STD $0050 * Put the average in memory
deviatie2 * begin of loop for the calculation of the deviation
LDD $00,X * Load a mesured point
SUBD $0050 * value min average
BCS rechttrekken * If the value is negative, redress it to positive
bewerking * come back to the procedure
CLC * Clear carry bit
JSR devtellen * take the sum of all deviations
DEX * decrease X twice, for reading next 16bit-value
DEX
CPX #$F000 * When all the points are taken, continue the procedure
BNE deviatie2
STY $0058 * Put most significant bits before the sum of deviations
LDD $0059 * The 24bit-value is located from $0059 to $0061
* We take the first 16bit, so we already divide by $100
LDX #$0004 * Load X , for dividing the sum with 4
IDIV * Divide
XGDX * Eschange with D
STAA devmsb * Save the values
STAB devlsb
PULX
RTS
**************************************************************************
*Take the sum of the deviation *
**************************************************************************
devtellen
ADDD $0060 * Add the result with the sum
BCS increase2 * If overload, increase Y in next procedure
voort2
CLC * Clear carry bit
STD $0060 * Store the sum in memory
RTS
increase2
INY * Increase Y if there is an overload in the sum
JMP voort2
**************************************************************************
*Put the negative value into positive *
**************************************************************************
* When a value is negative, the controller goes below zero, for him an overload $FFFF
* We need a positive value, so we take it back above $0000
rechttrekken
STD $0078 * Put D in memory
LDD #$FFFF * Load D with overload value
SUBD $0078 * Take away, it gives the positive number-1
INCB * Increase
JMP bewerking
**************************************************************************
*Calculate the speed *
**************************************************************************
Toerental
PSHX
PSHA
PSHB
LDX #$1000
begin
CLR COUNTER * Set the counter to 0
LDAA #$00 * Set the values of the speed back to 0
STAA tpm1
STAA tpm2
CLI * Activate the interrupts (one timer overflow interrupt, one input compare interrupt)
midden
LDAB #$03 * Compare if counter equals 3
* First the counter reach 1 at the first overflow, and from than we begin counting the pulses.
* After that we wait for 2 overflows, to reach 1 sec of counting. This gives a total of 3
CMPB COUNTER
BEQ einde * If counter=3, go to the end of the procedure
JMP midden * Otherwise, stay in the loop
einde
SEI * Stop all the interrupts
PULX
PULA
PULB
RTS
Deel1 * Overflow interrupt, comes after 0.52 seconds
BSET $25,X %01000000 * Set flag away
INC COUNTER * Increase the counter
RTI
Deel2 * Input compare interrupt, comes on rising edges only
* We dont save the values in the timer, we only need to count the number of pulses
BSET $23,X %00000001 * Set flag away
LDAB #$00
CMPB COUNTER * If counter = 0 , dont start counting.
BEQ stoptel
LDAB #$FF * If the value is $FF, we need to increase tpm1 and tpm2
CMPB tpm2
BEQ tel * Next procedure to increase tpm1 and tpm2
INC tpm2 * Otherwise, only in crease the least significant bits
RTI
tel
INC tpm1 * Increase the 2 numbers
INC tpm2
RTI
stoptel * Simply end the interrupt
RTI
*5.***********************************************************************
**************************************************************************
*Little programs *
**************************************************************************
**************************************************************************
*Send 6 to the SCI *
**************************************************************************
Schrijfniets
LDAB #$36
JSR Putchar
RTS
**************************************************************************
*Wait a certain time *
**************************************************************************
Klok
PSHX
LDX #$0300 * Load X with $300
LoopKlok
DEX * Decrease X
CPX #$0000 * Decrease until X reaches 0
BNE LoopKlok
PULX
RTS
ORG $FFDE * Overflow interrupt
FDB Deel1
ORG $FFEA * Input compare 3 interrupt
FDB Deel2
ORG $FFFE
FDB Main