96 lines
3.3 KiB
C
96 lines
3.3 KiB
C
|
/* brushed dc motor control example
|
||
|
|
||
|
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||
|
|
||
|
Unless required by applicable law or agreed to in writing, this
|
||
|
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||
|
CONDITIONS OF ANY KIND, either express or implied.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* This example will show you how to use MCPWM module to control brushed dc motor.
|
||
|
* This code is tested with L298 motor driver.
|
||
|
* User may need to make changes according to the motor driver they use.
|
||
|
*/
|
||
|
|
||
|
#include <stdio.h>
|
||
|
|
||
|
#include "freertos/FreeRTOS.h"
|
||
|
#include "freertos/task.h"
|
||
|
#include "esp_attr.h"
|
||
|
|
||
|
#include "driver/mcpwm.h"
|
||
|
#include "soc/mcpwm_reg.h"
|
||
|
#include "soc/mcpwm_struct.h"
|
||
|
|
||
|
#define GPIO_PWM0A_OUT 15 //Set GPIO 15 as PWM0A
|
||
|
#define GPIO_PWM0B_OUT 16 //Set GPIO 16 as PWM0B
|
||
|
|
||
|
static void mcpwm_example_gpio_initialize()
|
||
|
{
|
||
|
printf("initializing mcpwm gpio...\n");
|
||
|
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, GPIO_PWM0A_OUT);
|
||
|
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0B, GPIO_PWM0B_OUT);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief motor moves in forward direction, with duty cycle = duty %
|
||
|
*/
|
||
|
static void brushed_motor_forward(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num , float duty_cycle)
|
||
|
{
|
||
|
mcpwm_set_signal_low(mcpwm_num, timer_num, MCPWM_OPR_B);
|
||
|
mcpwm_set_duty(mcpwm_num, timer_num, MCPWM_OPR_A, duty_cycle);
|
||
|
mcpwm_set_duty_type(mcpwm_num, timer_num, MCPWM_OPR_A, MCPWM_DUTY_MODE_0); //call this each time, if operator was previously in low/high state
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief motor moves in backward direction, with duty cycle = duty %
|
||
|
*/
|
||
|
static void brushed_motor_backward(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num , float duty_cycle)
|
||
|
{
|
||
|
mcpwm_set_signal_low(mcpwm_num, timer_num, MCPWM_OPR_A);
|
||
|
mcpwm_set_duty(mcpwm_num, timer_num, MCPWM_OPR_B, duty_cycle);
|
||
|
mcpwm_set_duty_type(mcpwm_num, timer_num, MCPWM_OPR_B, MCPWM_DUTY_MODE_0); //call this each time, if operator was previously in low/high state
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief motor stop
|
||
|
*/
|
||
|
static void brushed_motor_stop(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
|
||
|
{
|
||
|
mcpwm_set_signal_low(mcpwm_num, timer_num, MCPWM_OPR_A);
|
||
|
mcpwm_set_signal_low(mcpwm_num, timer_num, MCPWM_OPR_B);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Configure MCPWM module for brushed dc motor
|
||
|
*/
|
||
|
static void mcpwm_example_brushed_motor_control(void *arg)
|
||
|
{
|
||
|
//1. mcpwm gpio initialization
|
||
|
mcpwm_example_gpio_initialize();
|
||
|
|
||
|
//2. initial mcpwm configuration
|
||
|
printf("Configuring Initial Parameters of mcpwm...\n");
|
||
|
mcpwm_config_t pwm_config;
|
||
|
pwm_config.frequency = 1000; //frequency = 500Hz,
|
||
|
pwm_config.cmpr_a = 0; //duty cycle of PWMxA = 0
|
||
|
pwm_config.cmpr_b = 0; //duty cycle of PWMxb = 0
|
||
|
pwm_config.counter_mode = MCPWM_UP_COUNTER;
|
||
|
pwm_config.duty_mode = MCPWM_DUTY_MODE_0;
|
||
|
mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &pwm_config); //Configure PWM0A & PWM0B with above settings
|
||
|
while (1) {
|
||
|
brushed_motor_forward(MCPWM_UNIT_0, MCPWM_TIMER_0, 50.0);
|
||
|
vTaskDelay(2000 / portTICK_RATE_MS);
|
||
|
brushed_motor_backward(MCPWM_UNIT_0, MCPWM_TIMER_0, 30.0);
|
||
|
vTaskDelay(2000 / portTICK_RATE_MS);
|
||
|
brushed_motor_stop(MCPWM_UNIT_0, MCPWM_TIMER_0);
|
||
|
vTaskDelay(2000 / portTICK_RATE_MS);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void app_main()
|
||
|
{
|
||
|
printf("Testing brushed motor...\n");
|
||
|
xTaskCreate(mcpwm_example_brushed_motor_control, "mcpwm_examlpe_brushed_motor_control", 4096, NULL, 5, NULL);
|
||
|
}
|