PWM / Motor Control Update

As it turns out, the ubiquitous little servo motors that seem to be everywhere are more sensitive to the PWM signal being sent to them than I originally thought.  At first I thought that as long as you were sending them a pulse that was the appropriate length that the frequency did not matter much, but try as I might, I could not get my servo to work with a 32.7ms delay (thats the time between TOIs on the HC11).  It actually required a very precise 20ms period before I could get my servo to do anything slam itself into the left hand side of its range.  Perhaps my servo is particularly picky, or perhaps it wasn’t the period at all and I just happened to change something else that made it work at the same time as I changed the period to 20ms (it was kind of one of those “I’ll do anything to get this damn thing to work” moments, so I was flailing around changing anything I could think of, all at the same time).

At any rate, I did eventually get the HC11 to control the servo motor based on the ADC input reading the pot on the evaluation board.  I still have a lot of tuning to do.  I am currently splitting up the functions and trying to work out a good way to organize things so that I can keep the PWM stuff in a separate file and link it to the main program.  I also need to calibrate the range of the servo, but that will come later.

Here is the code:

*=========================================
* TAKE ANALOG INPUT ON PE0
* CONVERT TO PWM ON PA6
*=========================================
ORG $C000
PORTB_OF    EQU $04
ADR_OF      EQU $31
ADCTL_OF    EQU $30
TCNT        EQU $100E
P_WIDTH     EQU $1018
OC1         EQU $1016
TFLG1       EQU $1023
TMSK1       EQU $1022
RAW_READ    RMB 1
DELAY       RMB 2
FREQ        EQU $9C40
LDS #$8fff
LDX #$1000
* TURN ON A/D CONVERTER:
*====================================
LDAA    $1039
ORAA    #%10000000
STAA    $1039
* SET UP TIMER:
*====================================
* SET OC1 INTERRUPT:
LDAA    #%10000000
STAA    $1022
* SET OC2 TO CLEAR ON FLAG:
LDAA    #%10000000
STAA    $1020
* SET OC1 TO SET OC2:
LDAA    #%01000000
STAA    $100C
STAA    $100D
* ENABLE INTERRUPTS:
CLI
*====================================
* MAIN PROGRAM
*====================================
LOOP        JSR GET_PE0
JSR PRC_DELAY
BRA LOOP
*====================================
* SUB-ROUTINES:
*====================================
ORG $D000
*====================================
* D/A CONVERSION ON PIN 0
* AVERAGE RESULTS AND RETURN IN ACCB
*====================================
GET_PE0     LDAA    #%00000111
STAA    $1030
CLRA
CLRB
SELF1       BRCLR   ADCTL_OF,X $80 SELF1
LDAB    ADR_OF,X
ADDB    ADR_OF+1,X
ADCA    #$00
ADDB    ADR_OF+2,X
ADCA    #$00
ADDB    ADR_OF+3,X
ADCA    #$00
LSRD
LSRD
STAB    RAW_READ
RTS
*====================================
* CONVERT READING TO DELAY
*====================================
PRC_DELAY   CLRA
CLRB
LDAB    RAW_READ
ASLD
ASLD
ASLD
ADDD    #1800
STD     DELAY
RTS
*====================================
* OC1 INTERRUPT ROUTINE:
*====================================
ORG     $00DF
JMP     $D100
ORG     $D100
OC1_I       LDD     TCNT
ADDD    DELAY
STD     P_WIDTH
LDD     TCNT
ADDD    #FREQ
STD     OC1
LDAA    #%10000000
STAA    TFLG1
STAA    TMSK1
RTI

About the Author