ESP8266 使用 DRV8833驱动板驱动N20电机

RT

手里这块ESP8266是涂鸦的板子,咸鱼上三块一个买了一堆,看ESP8266-12F引脚都差不多的。裸焊了个最小系统,加两个按钮(一个烧录,一个复位)

图1 现状

1. 准备工作

搜索过程中发现 DRV8833四路输入口需要PWM,而8266中的PWM口有4个IO口。但是我看到网上有人说“RSP8266中基本上数字IO都可以作为PWM复用引脚”,我不清楚。

图2 ESP8266中的PWM。来自乐鑫- ESP8266 技术参考手册.pdf

之前我把GPIO15接地了。因为网上一些人说要接地,以及涂鸦文档中有说GPIO15涉及到初始化过程,所以我以为这个引脚是不能用的

图3 涂鸦 TYWE3L 模组规格书中关于GPIO的描述

试着去掉后,发现可以正常烧录和运行。那就这么着了,反正你引脚都引出来了,我应该可以随便折腾,我也不用wifi功能,至于GPIO15能不能用还得等后续验证。

下面是现在的烧录和复位最小系统图:去掉GPIO15到GND这条线

图4 ESP8266最小系统图

2. PWM 呼吸灯测试

因为实在RTOS下开发的,所以手册先放上来。esp8266-rtos-sdk PWM

RTOS下也有示例代码:ESP8266_RTOS_SDK\examples\peripherals\pwm

PWM重要参数:

频率:1/Ts(周期)

占空比:Ton/Ts

在频率一定时,可通过不同占空比来改变LED亮度,就达到呼吸灯效果了。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "esp_system.h"
#include "esp_err.h"
#include "esp8266/gpio_register.h"
#include "esp8266/pin_mux_register.h"
#include "driver/pwm.h"


//#define PWM_0_OUT_IO_NUM   12
//#define PWM_1_OUT_IO_NUM   13
//#define PWM_2_OUT_IO_NUM   14
#define PWM_3_OUT_IO_NUM   15

// PWM period 1000us(1Khz), same as depth
// 周期
#define PWM_PERIOD    (1000)

static const char *TAG = "pwm_example";

// pwm pin number
const uint32_t pin_num[1] = {
    // PWM_0_OUT_IO_NUM,
    // PWM_1_OUT_IO_NUM,
    // PWM_2_OUT_IO_NUM,
    PWM_3_OUT_IO_NUM
};

// duties table, real_duty = duties[x]/PERIOD
// 占空比
uint32_t duties[1] = {
    // 10000, 10000, 10000, 
    500,
};

// phase table, delay = (phase[x]/360)*PERIOD
// 相位
float phase[1] = {
    0
};
// #define configTICK_RATE_HZ 1000
void app_main()
{
    pwm_init(PWM_PERIOD, duties, 1, pin_num);
    pwm_set_phases(phase);
    pwm_start();
    char flag = 0;
    uint16_t count = 1;
    while (1) {
        if(flag){
            count--;
        }else{
            count++;
        }

        if(count>=1000){
            flag=1;
            ESP_LOGI(TAG, "PWM 1000\n");
        }else if(count<=1){
            flag = 0;
            ESP_LOGI(TAG, "PWM 0\n");

            // 熄灭后停留
            vTaskDelay(pdMS_TO_TICKS(300));
        }
        // 设置占空比
        pwm_set_duty(0, count);
        pwm_start();

        vTaskDelay(pdMS_TO_TICKS(2));
    }
}

15号引脚上的PWM呼吸灯如下:

测试PWM的呼吸灯

3. DRV8833 驱动板连接

网上找到接线图,来试试

图5 DRV8833接线图

放在我的电路中的接线图

图6 自己系统中的接线图

焊接,焊接完成后,串口信息报错

Fatal exception (0): 
epc1=0x4013ffff, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000

应该是焊的时候碰到以前的引脚了或者新焊接的线影响了运行

重新烧录下程序,烧录按钮按下,按复位毫无反应,排查下问题。

最后发现是GPIO2影响了,因为GPIO2在模块启动的时候如果拉低会启动失败。我也搞不懂为什么现在接的是VCC但是是低电平。和GPIO15换个位置吧。

图7 修改GPIO2<>15

4. 代码部分

供电

首先GPIO15要供电,输出高电平:

#include "driver/gpio.h"
#define GPIO_15 15
void app_main()
{

    // 不是RTOS中的配置方式
    // 配置 IO15 为 GPIO功能
    // PIN_FUNC_SELECT(PERIPHS_GPIO_MUX_REG(15), FUNC_GPIO15);
    // 设置高电平
    // GPIO_OUTPUT_SET(15, 1);

    // 配置IO15为输出
    gpio_config_t ioConf;
    ioConf.intr_type = GPIO_INTR_DISABLE;
    ioConf.mode = GPIO_MODE_OUTPUT;
    ioConf.pin_bit_mask = (1ULL<<GPIO_15);
    ioConf.pull_down_en = 0;
    ioConf.pull_up_en = 0;
    gpio_config(&ioConf);
    // 输出高电平
    gpio_set_level(GPIO_15, 1);

供电后,驱动板上的LED亮了。

四路PWM输出

#define PWM_0_OUT_IO_NUM   12
#define PWM_1_OUT_IO_NUM   13
#define PWM_2_OUT_IO_NUM   14
#define PWM_3_OUT_IO_NUM   2

// PWM period 1000us(1Khz), same as depth
// 周期
#define PWM_PERIOD    (1000)

// pwm pin number
const uint32_t pin_num[4] = {
    PWM_0_OUT_IO_NUM,
    PWM_1_OUT_IO_NUM,
    PWM_2_OUT_IO_NUM,
    PWM_3_OUT_IO_NUM
};

// duties table, real_duty = duties[x]/PERIOD
// 占空比
uint32_t duties[4] = {
    500,
    500,
    500,
    500,
};

// phase table, delay = (phase[x]/360)*PERIOD
// 相位
float phase[4] = {
    0, 0, 0, 0,
};

void app_main()
{

   ...

    // 配置四路PWM口
    pwm_init(PWM_PERIOD, duties, 4, pin_num);
    pwm_set_phases(phase);
    pwm_start();

串口日志输出:

gpio: GPIO[15]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
gpio: GPIO[2]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
gpio: GPIO[12]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
gpio: GPIO[13]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
gpio: GPIO[14]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
pwm: --- PWM v3.4

现在通电后,电机没转动,但是有响声。

是因为驱动方式不对,看看DRV8833的逻辑控制:

图8 DRV8833逻辑控制1

图9 DRV8833逻辑控制2

现在IO12和IO13都是PWM输出,就会肯定就动不了的。将IO13设为低电平就可以了。

速度不够快,先把占空比调大一些。确实快了。再将频率设置为10Khz,速度相比1Khz好像没提升。如果还想增加转速是不是只能增加电压?现在只是3.3的电压太小了。

不过现在总算是转起来了

图10 看这残影

以及总览图:

图11 电路总览图

完整代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"

#include "esp_log.h"
#include "esp_system.h"
#include "esp_err.h"

#include "esp8266/gpio_register.h"
#include "esp8266/pin_mux_register.h"

#include "driver/pwm.h"
#include "driver/gpio.h"

#define PWM_0_OUT_IO_NUM   12

#define GPIO_15 15
#define GPIO_13 13

// PWM period 1000us(1Khz), same as depth
// 周期 1ms=1Khz 100us=10Khz
#define PWM_PERIOD    (1000)

// pwm pin number
const uint32_t pin_num[1] = {
    PWM_0_OUT_IO_NUM,
};

// duties table, real_duty = duties[x]/PERIOD
// 占空比
uint32_t duties[1] = {
    999,
};

// phase table, delay = (phase[x]/360)*PERIOD
// 相位
float phase[1] = {
    0
};


void app_main()
{
    // 配置IO15为输出
    gpio_config_t ioConf;
    ioConf.intr_type = GPIO_INTR_DISABLE;
    ioConf.mode = GPIO_MODE_OUTPUT;
    ioConf.pin_bit_mask = (1ULL<<GPIO_15);
    ioConf.pull_down_en = 0;
    ioConf.pull_up_en = 0;
    gpio_config(&ioConf);
    // 输出高电平
    gpio_set_level(GPIO_15, 1);
    
    // 配置IO13为输出
    ioConf.intr_type = GPIO_INTR_DISABLE;
    ioConf.mode = GPIO_MODE_OUTPUT;
    ioConf.pin_bit_mask = (1ULL<<GPIO_13);
    ioConf.pull_down_en = 0;
    ioConf.pull_up_en = 0;
    gpio_config(&ioConf);
    // 输出高电平
    gpio_set_level(GPIO_13, 0);

    // 配置一路PWM口
    pwm_init(PWM_PERIOD, duties, 1, pin_num);
    pwm_set_phases(phase);
    pwm_start();
    
}

其他参考:

posted @ 2022-07-25 10:10  姜小豆  阅读(2869)  评论(0编辑  收藏  举报