Hello Everyone!
I'm currently doing a project right now that controls bipolar stepper motors. What I have done so far was to use the L297 and L298 to control the steppers using a 555 timer to manipulate the speed of rotation. What I'm planning to do next is to integrate these to my mcs09jm60 using the DEMOJM board. I want to subsititute the 555 timer with the TPM of the mcu. My problem is on how to generate variable clock pulses to drive the L297 in order to control the speed of rotation of the stepper. Can anyone point me to the right direction? Thanks ahead for the help!
Regards,
Kris
解決済! 解決策の投稿を見る。
Hello Kris,
I will make some assumptions about what you might want to achieve, and look at an approach for doing so.
Firstly, stepper motors are capable of both position control and speed control without the need for feedback. Since you are using the L297 device, I will assume that you have interest only in speed control of the motor.
Since you wish to use the ADC to control the motor speed, I will assume 10-bit mode, with an output value of 0- 1023, which will linearly control the speed of the motor. If each control step were to represent an increment of 0.1 rpm, this would give a maximum speed of 409.5 rpm.
It would seem that the L297 requires four clock pulses for each full step of the motor, and with 48 steps per revolution of the motor, this would require 192 clock pulses per revolution. At the maximum speed, the clock rate would be 1310 Hz I do not know whether this is too fast for the stepper you are using - it will depend on the inertia of the load, in addition to the inertia of the motor rotor - but this might be a reasonable experimental starting point.
In order to achieve linear control of the clock frequency, I am proposing a method where the 10-bit ADC reading is periodically added to a 16-bit accumulating counter, and the MSB of the counter determines the output clock state at a selected GPIO pin. To achieve the required output clock rate, the accumulating register should be updated every 47.7 microseconds. This would be controlled within a TPM module channel ISR (software output compare mode).
With this method, we now come to a time critical process. The number of CPU cycles available for the completion of ISR code will be determined by the bus clock. For a 8 MHz clock, the number of bus cycles between updates is 381. The ISR must be completed in substantially less than this number of cycles. I am not sure whether this is feasible, but if so is likely to require the use of tight assembly code. A bus clock of 16 MHz would give 762 cycles between updates, and is a little more comfortable.
The following sequence of events would need to occur within the channel ISR code:
Maybe something like the following C code would work.
#define INCR_VAL 762 // 16 MHz bus assumed#define ADC_CHAN 1 // ADC channel 1#define STEP_CLK PTAD_PTAD0 // GPIO pininterrupt void ISR_TPM1C0( void){ static word accum = 0; TPM1C0SC_CHOF = 0; // Clear flag TPM1C0V += INCR_VAL; // Next compare value accum += ADCR; // Update accumulation count ADCSC1 = ADC_CHAN; // Start next conversion if (accum & 0x8000) // Test MSB STEP_CLK = 1; else STEP_CLK = 0;}
You will also need to initialise the TPM module and the ADC module.
I guess that there are other possible approaches that would have less critical timing, but would require more complex calculations to convert the ADC reading to an equivalent period value for a TPM channel. In this case the step clock would appear at the TPM channel pin.
Regards,
Mac
Hello Kris,
Yes it should be possible to make use of a TPM module for this purpose.
Before making more detailed suggestions for the possible approach, the maximum clock frequency would need to be known. There are also other factors such as the incremental frequency step size, and whether the frequency increment should have a linear characteristic. Another design issue may be whether the stepper motor needs to ramp up and ramp down its stepping rate whenever there is a speed change.
Another potential approach might be to eliminate the L297 device, and directily drive the L298 from the MCU.
Regards,
Mac
Hello Mac!
Thanks for the response! My apologies for the late response on my part. Got busy with some stuffs due to the holiday season. Anyway, I'm using a Portescap Bipolar Stepper Motor which I've purchased rom DigiKey. Based from its datasheet, its frequency step size is 7.5+- 0.5 degrees. I don't have any data with regards to the maximum clock frequency that it can handle. What I did was to configure my 555 timer to run at different speeds by using a potentiometer. I found out that it can still run at around 120 Hz. Yet I still dont have any idea of its maximum clock frequency. Do you have any idea on how to determine such frequency? Going back to the matter, my overall plan is to control the speed of the stepper motor using the potentiometer installed within the DEMOJM. I'm quite hesitant in removing the L297 and directly connecting the L298 to the MCU because using the L297 made my life easier
but if it is the best thing to do in order to progress in my project, I will be glad to do it. Hoping that you will be able to guide and help me along the way.
By the way, I've attached the datasheet of the Bipolar stepper motor for your reference.
Thanks and hope to hear from you soon!
Kris
Hello Kris,
I will make some assumptions about what you might want to achieve, and look at an approach for doing so.
Firstly, stepper motors are capable of both position control and speed control without the need for feedback. Since you are using the L297 device, I will assume that you have interest only in speed control of the motor.
Since you wish to use the ADC to control the motor speed, I will assume 10-bit mode, with an output value of 0- 1023, which will linearly control the speed of the motor. If each control step were to represent an increment of 0.1 rpm, this would give a maximum speed of 409.5 rpm.
It would seem that the L297 requires four clock pulses for each full step of the motor, and with 48 steps per revolution of the motor, this would require 192 clock pulses per revolution. At the maximum speed, the clock rate would be 1310 Hz I do not know whether this is too fast for the stepper you are using - it will depend on the inertia of the load, in addition to the inertia of the motor rotor - but this might be a reasonable experimental starting point.
In order to achieve linear control of the clock frequency, I am proposing a method where the 10-bit ADC reading is periodically added to a 16-bit accumulating counter, and the MSB of the counter determines the output clock state at a selected GPIO pin. To achieve the required output clock rate, the accumulating register should be updated every 47.7 microseconds. This would be controlled within a TPM module channel ISR (software output compare mode).
With this method, we now come to a time critical process. The number of CPU cycles available for the completion of ISR code will be determined by the bus clock. For a 8 MHz clock, the number of bus cycles between updates is 381. The ISR must be completed in substantially less than this number of cycles. I am not sure whether this is feasible, but if so is likely to require the use of tight assembly code. A bus clock of 16 MHz would give 762 cycles between updates, and is a little more comfortable.
The following sequence of events would need to occur within the channel ISR code:
Maybe something like the following C code would work.
#define INCR_VAL 762 // 16 MHz bus assumed#define ADC_CHAN 1 // ADC channel 1#define STEP_CLK PTAD_PTAD0 // GPIO pininterrupt void ISR_TPM1C0( void){ static word accum = 0; TPM1C0SC_CHOF = 0; // Clear flag TPM1C0V += INCR_VAL; // Next compare value accum += ADCR; // Update accumulation count ADCSC1 = ADC_CHAN; // Start next conversion if (accum & 0x8000) // Test MSB STEP_CLK = 1; else STEP_CLK = 0;}
You will also need to initialise the TPM module and the ADC module.
I guess that there are other possible approaches that would have less critical timing, but would require more complex calculations to convert the ADC reading to an equivalent period value for a TPM channel. In this case the step clock would appear at the TPM channel pin.
Regards,
Mac
hi bigmac,
thanks for the comprehensive response. i'm currently figuring out your suggestion to my problem. i would just like to ask on how you arrived at the 47.7 microsecond update time of the accumulating register?
thanks!
kris
Hello Kris,
Actually, I must have had a mental mixup between 10-bit and 12-bit operation of the ADC. For your application there would be little justification in using higher resolution than 10 bits. So we need to pretend that the accumulating register has 14 bits, rather than 16 bits, with an overflow count of 16384.
At the maximum output frequency of 1310 Hz, corresponding to an ADC reading of 1023, this value will need to be added 16 times per overflow, or output cycle. This gives an update frequency of 1310*16 = 20.96 kHz, or a required update period of 47.7 us.
To reflect the 14-bit overflow requirement, the previous code might be modified thus -
if (accum & 0x2000) // Test bit-13 STEP_CLK = 1; else STEP_CLK = 0;
Regards,
Mac
hi bigmac!
my apologies but i'm quite confused. please bear with me. i'm confused on these statements:
"At the maximum output frequency of 1310 Hz, corresponding to an ADC reading of 1023, this value will need to be added 16 times per overflow, or output cycle. This gives an update frequency of 1310*16 = 20.96 kHz, or a required update period of 47.7 us."
why is there a need to add the ADC value 16 times per overflow?
by the way, i have found a torque vs speed curve for my stepper motor. I've attached a pdf below. please refer to page 2. my stepper motor is 35L048B1B. As what i've noticed, the maximum speed of the motor with useful torque is 500rpm. Am i correct in interpreting the graph?
thanks for your help. again, my apologies for the quite dumb questions.
regards,
kris
Hello Kris,
With the arrangement I have suggested, the state of bit-13 of the accumulating register is transferred to an output pin, to provide the variable frequency signal. This will be a square wave.
With a clock rate of ~20kHz, the ADC reading of 0-1023 is added to the accumulating register. The higher the value added, the more quickly the 14-bit value within the accumulating register will overflow, and the higher will be the output frequency. With the highest ADC value, the 14-bit value will overflow after every 16 additions, to produce the highest output frequency available.
The output frequency may be calculated with the formula:
fout = fclk * N / 16384
The maximum output frequency of 1310 Hz will result in a motor speed of 1310 * 60 / 192 = 409 rpm, which should be compatible with the motor you are using, but subject to some experimentation.
Regards,
Mac
Hi Bigmac!
Good news!! I did it! I just made some adjustments regarding the speed of my motor and added a few lines of codes to yours. I am now able to control the speed of my motor using the potentiometer of the DEMOJM. The max speed that I set was 85hz. I experimented on this speed and found out that speeds above this one would cause the motor to have lesser torque. Next thing to do is to enhance this further by creating a GUI that would control the direction, speed of the motor. Once again, thanks for you help bigmac! Looking forward to have another interaction with you in the future! More power!
Regards and Many Thanks,
Kris