ESP8266 使用 DRV8833驅動板驅動N20電機

2022-07-25 12:01:45

RT

手裡這塊ESP8266是塗鴉的板子,鹹魚上三塊一個買了一堆,看ESP8266-12F引腳都差不多的。裸焊了個最小系統,加兩個按鈕(一個燒錄,一個復位)

1. 準備工作

搜尋過程中發現 DRV8833四路輸入口需要PWM,而8266中的PWM口有4個IO口。但是我看到網上有人說「RSP8266中基本上數位IO都可以作為PWM複用引腳」,我不清楚。

之前我把GPIO15接地了。因為網上一些人說要接地,以及塗鴉檔案中有說GPIO15涉及到初始化過程,所以我以為這個引腳是不能用的

試著去掉後,發現可以正常燒錄和執行。那就這麼著了,反正你引腳都引出來了,我應該可以隨便折騰,我也不用wifi功能,至於GPIO15能不能用還得等後續驗證。

下面是現在的燒錄和復位最小系統圖:去掉GPIO15到GND這條線

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 驅動板連線

網上找到接線圖,來試試

放在我的電路中的接線圖

焊接,焊接完成後,串列埠資訊報錯

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

應該是焊的時候碰到以前的引腳了或者新焊接的線影響了執行

重新燒錄下程式,燒錄按鈕按下,按復位毫無反應,排查下問題。

最後發現是GPIO2影響了,因為GPIO2在模組啟動的時候如果拉低會啟動失敗。我也搞不懂為什麼現在接的是VCC但是是低電平。和GPIO15換個位置吧。

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, 0);

供電後,驅動板上的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的邏輯控制:

現在IO12和IO13都是PWM輸出,就會肯定就動不了的。將IO13設為低電平就可以了。

速度不夠快,先把佔空比調大一些。確實快了。再將頻率設定為10Khz,速度相比1Khz好像沒提升。如果還想增加轉速是不是隻能增加電壓?現在只是3.3的電壓太小了。

不過現在總算是轉起來了

以及總覽圖:

完整程式碼:

#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();
    
}

其他參考: