MSP430F5529 multi-channel PWM output control servo and motor
[Copy link]
MSP430F5529 has rich timer resources. This time I bring you a multi-channel PWM wave output, which can control the servo. Of course, after simple modification, it can also control the motor. The experimental platform is TI's MSP-EXP430F5529LP, which is what we often call launchpad. I believe that many friends who do electronic racing have one.
First, let's briefly talk about the difference between controlling a motor and controlling a digital servo. To control a motor, we only need to output a certain duty cycle, and do not need to accurately control the cycle. However, to control a servo, we need to accurately control the duty cycle and cycle. We will not talk much about motor control. We just need to ensure that the output frequency is not too low (the motor will buzz) or too high (too high will also cause problems, which will not be expanded here). We initially set the frequency of the motor speed regulation to 5KHz. I will not say more about the control requirements of a digital servo. The duration of the high level of a 20ms cycle is 0.5~2.5ms. Let's first talk about the general motor control to generate a 5KHz square wave signal with an adjustable frequency.
Here is the code link: Code link The implementation effect will be placed at the end of the article. The main thing I want to share with you is the implementation process.
Step 1: IO port multiplexing
IO multiplexing should be familiar to those who have learned a little about STM32 or microcontrollers other than 51 (even enhanced 51 like STC12xx has this function of IO multiplexing). It is just an introduction to the function. We will first generate four-channel PWM and demonstrate it briefly...
Open the Datasheet of our chip and in the Terminal Function section there is an introduction to the IO multiplexing function.
IO multiplexing is very simple in MSP (there are relatively few multiplexing functions, and not many single mappings...) Just set the specified position of the PxSEL register to 1. The operation is like this
Step 2: Set the relevant registers of the timer
Here I use the SMCLK clock, which is not clock-up (1MHz). For how to increase the system clock, see this blog. This is the address
We open the user manual of msp430F5529 (user_guide, not datasheet)
From the above figure we can see about two parts of registers. The first part is the setting of the clock body:
As shown in the figure above, the register parameters we need to set are mainly these four options: The first option is the clock source. Here I choose 1MHz SMCLK (Subsystem master clock)
In the header file library #include <msp430F5529.h>, I found the relevant bits about TA0CTL
Keep looking down, the official header files clearly state the practical method is very simple
TA0CTL |= TASSEL__SMCLK; It's that simple. The clock is selected! The next operation is to configure the two registers ID and IDEX
ID is the first frequency division and the second frequency division is IDEX
We need to calculate the frequency division parameters we need, but before that we also need to configure some other parameters: such as mode
The choice of mode directly determines your usage, which in turn changes the meaning of the parameters! The choice of mode is the position of the MC in our previous picture.
We can see that these two bits are controlling the mode.
Here are the four modes formed by the combination of these two bits. They are defined later. Both motor control and servo control must select mode 1. We can do a simple calculation. Even if my clock is not divided, that is, the counting frequency is 1MHz (maximum 25MHz), then the frequency of our pulse is 1M/65536 = 15 or 25M/65536 = 381. In our 1M case, we can only use the MC_Up option, that is, use CCR0 as the ARR (Auto Reload) register, and reset it to 0 when the timer's CNT counts to CCR0. Take motor control as an example. Assume that the accuracy of our motor control is 1000 (there is an accuracy issue involved here. My understanding is that the accuracy is how many pulses you want to divide your cycle time into. The accuracy is related to ARR. For example, when controlling a servo, your pulse of 20ms is divided into 200 parts (ARR = 2000), then the minimum pulse time you can control is 20ms/2000 = 10us. That is, you cannot generate a pulse that is not an integer multiple of 10us. The minimum step value of your pulse width is 10us. This step value will affect the control accuracy of your servo, etc. ARR will affect the range of the output value of your motor speed control closed loop! ) The value of ARR is still worth further study. If ARR is too high, the count value will be relatively large, and the control accuracy will be very high, but the high frequency of the 430 timer means more power consumption, and you even need to generate a clock that is much higher than the normal system clock! If the value is too small, the accuracy will be wasted (such as a high-precision servo)
Here I set SMCLK = 1MHz. ID and IDEX are both default settings (no frequency division). CCR0 is 100. The frequency of the PWM generated at this time is
SMCLK / (ID*IDEX*CCR0) = 100 0000/(1*1*100) = 10KHz
The above is the generated 10KHz frequency (the error here is large because the clock is not 1Mhz but 1.05Mhz. As for why it is 1.05MHz, I will find out... The following articles are tested according to 1.05M! ! ! The calculations in the article are all problematic! No subsequent modifications will be made here. I hope readers understand. As for why the clock is 1.05MHz, see here-------> Link address
To set our 5KHz, just adjust the ID
The above pulses can be used for motor control but not for servo control. Next, we design the configuration of servo control.
Assuming we have a 180-degree servo, I hope to achieve a step value of 1 degree. We might as well set the pulse time to change 2ms when the CCR register value changes by 180 units. In this way, the entire cycle requires 1800 pulses, that is, our CCR0 needs to be set to 1800. Calculate the frequency if there is no frequency division at this time. SMCLK/CCR0 = 1000000/1800 = 555.555 Hz > 50Hz. The specified frequency should be obtained through frequency division!
Next we should calculate the frequency division coefficient. The frequency division coefficient we need is 555.5/50 = 11.1. This number is a bit small. The reliable division should be 2*6 = 12.
We get a 42Hz square wave. Next we adjust IDEX = 5.
Amazing! We got a 49Hz square wave. There should be no problem with the servo control!
I will provide the code link later. Through these tests, I also found that the clock fluctuation of MSP430 is relatively large, and the clock is not so stable. If you want to get the best parameters, you still need to test it yourself. The actual test results are still somewhat different from the expected ones.
The oscilloscope used for debugging is Loto's virtual oscilloscope OSC802, a tool that can be directly plugged into the computer for debugging. It is so convenient to debug the code!
I just picked up 430 again recently and there are still many unfamiliar things. If there are any mistakes, please feel free to correct me.
|