In this guide, we will learn how to interface a DC motor with the STM32-F103RB Nucleo Board. By accomplishing this, we can control the speed and direction of the motor using the Nucleo Board and achieve precise motor control in our projects.
The objective of this project is to interface a DC motor with the STM32-F103RB Nucleo Board and develop a system that can control the motor's speed and direction.
To successfully complete this project, you will need the following components:
STM32-F103RB Nucleo Board
DC Motor
L298N motor driver
Breadboard
Jumper wires
12v Battery
Follow the circuit diagram below to interface the DC motor with the Nucleo board:
Connect the ENA and ENB pins of the motor driver to the PA9 and PA8 pins of the STM32 Nucleo board, respectively.
Similarly, connect the IN1, IN2, IN3, and IN4 pins of the motor driver to the PC8, PC7, PC6, and PB15 pins of the board, respectively.
Don't forget to connect the external 12V battery to power the motor, and connect the ground of the battery to the common ground of the Nucleo board.
Follow these steps to configure the .IOC file and set up GPIOs and Clock :
Open the STM32 Cube IDE and start by creating a new STM32 project. Click on the board selector tab in the target selection window.
Enter "NUCLEO-F103RB" as the commercial part number and click on "Next" after selecting the board.
3. Enter the Project Name "DC_Motor" and click on "Finish". After that, click on "Yes" to initialize all the peripherals in default mode.
Pinout & Configuration: In the Pinout & Configuration menu, select "TIM1" from the Timers section. This will configure Timer 1 for generating PWM signals.
Clock Source and PWM Generation: Choose "Internal Clock" as the Clock Source to utilize the internal clock of the STM32-F103RB Nucleo Board for PWM generation. Additionally, select "PWM Generation CH1" in Channel 1 and "PWM Geneneration CH2" in Channel 2.
Timer Configuration: In the Configuration part of the Timers section, set the Prescaler value as "72-1". The prescaler determines the frequency of the timer clock. Here, we divide the timer clock frequency by 72.
Next, specify the Counter Period as "100-1". The counter period defines the overall period of the PWM signal. With a value of 100-1, the PWM signal will complete one cycle every 100 timer clock cycles.
Also, set up the pins IN1, IN2, IN3 and IN4 in the pin out view. Rename the PWM_CH1 and PWM_CH2 to "ENA" and "ENB" respectively.
9. After finishing the Pinout Configuration, go to the Clock Configuration menu. In the HCLK field, enter "72 MHz" as the desired frequency for the HCLK (system clock). The Integrated Development Environment (IDE) will automatically search for the necessary clock sources and prescalers based on this configuration.
10. Next, locate the gear-like icon on the toolbar and click on it. This will add the configuration settings we did in the GUI to the code.
Now, let's proceed to understand and write the C code to control the motor using motor driver. Follow the steps below:
The Device Configuration Tool will automatically open the main.c file for you. In the project, you will find all the necessary pin and port names defined in the Core ⇾ Inc ⇾ main.h file. These definitions will help us easily reference the pins and ports in our code.
Navigate to the main function in the main.c file and paste the following code:
Note: You can download the full project code from the provided link.
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_TIM1_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
int pwm = 0;
/* USER CODE END 2 */
while (1)
{
/* USER CODE BEGIN 3 */
// Set direction to forward
HAL_GPIO_WritePin(IN1_GPIO_Port, IN1_Pin, SET);
HAL_GPIO_WritePin(IN2_GPIO_Port, IN2_Pin, RESET);
HAL_GPIO_WritePin(IN3_GPIO_Port, IN3_Pin, SET);
HAL_GPIO_WritePin(IN4_GPIO_Port, IN4_Pin, RESET);
for (pwm = 0; pwm <= 100; pwm = pwm + 1) // slow to fast: 0-100% duty cycle
{
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, pwm); // update pwm value
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_2, pwm); // update pwm value
HAL_Delay(50); // Wait for 5ms
}
HAL_Delay(500); // hold for 0.5s
// Set direction to backward
HAL_GPIO_WritePin(IN1_GPIO_Port, IN1_Pin, RESET);
HAL_GPIO_WritePin(IN2_GPIO_Port, IN2_Pin, SET);
HAL_GPIO_WritePin(IN3_GPIO_Port, IN3_Pin, RESET);
HAL_GPIO_WritePin(IN4_GPIO_Port, IN4_Pin, SET);
for (pwm = 0; pwm <= 100; pwm = pwm + 1) // slow to fast: 0-100% duty cycle
{
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, pwm); // update pwm value
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_2, pwm); // update pwm value
HAL_Delay(50); // Wait for 5ms
}
HAL_Delay(500); // hold for 0.5s
}
/* USER CODE END 3 */
}
After pasting the above code, ensure that you have connected your STM32-F103RB Nucleo Board to your PC/Laptop using a USB cable.
Next, click on the "Run and Debug" icon in the toolbar menu of the IDE (Refer to image below ). This will initiate the build process for your project. The IDE will compile the code. Once the build process is successful, the IDE will start flashing the compiled project to the STM32-F103RB Nucleo Board.
Upon successful execution of the project, the STM32-F103RB Nucleo Board will be able to control the speed and direction of the DC motor. By sending signals to the GPIO pins, the board can vary the motor's speed and change its direction.
In this guide, we have learned to interface a DC Motor with the STM32-F103RB Nucleo Board. This allows us to achieve automatic control of Motors. By following the steps outlined in this guide, we have successfully implemented a project that offers various applications such as robot car, cooling fan and much more.