Add initial board, HAL, and executor modules

This commit is contained in:
wang committed 2026-05-07 17:24:10 +08:00
1 parent 3b9e129c88
commit 0b2eebe76d
82 files changed
+20611

No files matched your search

@@ -0,0 +1,311 @@
/**
* @file board.cc
* @brief 板级外设初始化类,包含步进电机、毫米波雷达、I2C总线等外设的初始化函数。
* @author zouyuhua
* @date 2025年8月7日
*
*/
extern "C" {
#include "esp_log.h"
#include "driver/gpio.h"
#include "driver/uart.h"
#include "driver/ledc.h"
#include "driver/gptimer.h"
#include "esp_err.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "hal/gpio_types.h"
#include "hal/uart_types.h"
#include "esp_check.h"
#include "sdkconfig.h"
#include "i2c_bus.h"
}
#include "board_sweekar.h"
#include "config.h"
#define TAG "board_sweekar"
/*========================== 步进电机相关驱动 ==========================*/
/**
* @brief 步进电机初始化函数
* 配置步进电机所需的GPIO引脚模式,通过IO扩展板设置步进驱动芯片的工作模式
* 在 stepper_motor.cc 中完成 GPTimer + GPIO 翻转 STEP 脉冲的初始化
*/
void BoardSweekar::StepperMotorInit(void)
{
esp_err_t err = ESP_OK;
// 1) STEP 引脚改为普通 GPIO(不再用 LEDC)
gpio_config_t io_cfg;
io_cfg.pin_bit_mask = 1ULL << STEPPER_STEP_IO;
io_cfg.mode = GPIO_MODE_OUTPUT;
io_cfg.pull_up_en = GPIO_PULLUP_DISABLE;
io_cfg.pull_down_en = GPIO_PULLDOWN_DISABLE;
io_cfg.intr_type = GPIO_INTR_DISABLE;
err = gpio_config(&io_cfg);
if (err != ESP_OK)
{
ESP_LOGE(TAG_BOARD, "步进电机 STEP GPIO 配置失败, 错误码: 0x%x", err);
}
// 初始电平拉低,保证上电不乱跳
gpio_set_level(STEPPER_STEP_IO, 0);
// 2) 检查 I2C 总线是否已初始化
if (bus_handle_ == nullptr)
{
ESP_LOGE(TAG_BOARD, "I2C总线未初始化,请先调用I2CMasterInit()");
return;
}
// 3) 通过 IO 扩展板配置步进驱动芯片:睡眠/使能/细分/方向
err = io_expansion_.SetMotorSleepMode(
STEPPER_MOTOR_WORK,
STEPPER_MOTOR_SLEEP_PORT,
STEPPER_MOTOR_WORK
);
if (err != ESP_OK)
{
ESP_LOGE(TAG_BOARD, "步进电机睡眠模式配置失败, 错误码: 0x%x", err);
}
err = io_expansion_.SetMotorEnableMode(
STEPPER_MOTOR_ENABLE_DISABLE,
STEPPER_MOTOR_ENABLE_PORT,
STEPPER_MOTOR_ENABLE_PIN
);
if (err != ESP_OK)
{
ESP_LOGE(TAG_BOARD, "步进电机使能配置失败, 错误码: 0x%x", err);
}
// 细分设置:这里仍然用原来的 1/8 细分
io_expansion_.SetStepperMicrostepMode(
4,
STEPPER_MOTOR_M0_MADE_PORT,
STEPPER_MOTOR_M0_PIN,
STEPPER_MOTOR_M1_MADE_PORT,
STEPPER_MOTOR_M1_PIN
);
if (err != ESP_OK)
{
ESP_LOGE(TAG_BOARD, "步进电机细分模式配置失败, 错误码: 0x%x", err);
}
// 默认方向先设一个(比如“上升”方向)
err = io_expansion_.StepperMotorSetDir(
STEPPER_MOTOR_LEFT,
STEPPER_MOTOR_DIR_PORT,
STEPPER_MOTOR_DIR_PIN
);
if (err != ESP_OK)
{
ESP_LOGE(TAG_BOARD, "步进电机方向配置失败, 错误码: 0x%x", err);
}
}
/*========================== 毫米波雷达相关驱动 ==========================*/
/**
* @brief 毫米波雷达串口初始化函数
*
* 配置毫米波雷达所使用的串口参数(波特率、数据位、校验位、停止位等),设置串口引脚,
* 并安装串口驱动。采用较大的RX/TX FIFO深度以处理突发数据,禁用驱动自带事件队列以避免
* 与自定义中断冲突。
*/
void BoardSweekar::MillimeterWaveRadarUartInit(void)
{
uart_config_t uart_config = {
.baud_rate = RADAR_BAUD_RATE,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_DEFAULT,
};
// 1. 设置串口参数
ESP_ERROR_CHECK(uart_param_config(RADAR_UART_NUM, &uart_config));
// 2. 设置 UART 引脚
ESP_ERROR_CHECK(uart_set_pin(RADAR_UART_NUM, UART_TX_PIN, UART_RX_PIN,
UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
// 3. 安装 UART 驱动(禁用驱动自带事件队列,避免与自定义中断冲突)
// 增加 RX/TX FIFO 深度以处理突发数据
ESP_ERROR_CHECK(uart_driver_install(RADAR_UART_NUM, RADAR_BUF_SIZE * 4, RADAR_BUF_SIZE * 4,
0, NULL, 0));
}
/**
* @brief 毫米波雷达中断引脚初始化函数
*
* 配置毫米波雷达中断引脚为输入模式,禁用上拉电阻,使能下拉电阻,初始禁用中断功能
* (如需使用中断需单独进行配置)。
*/
void BoardSweekar::MillimeterWaveRadarGpioInit(void)
{
// GPIO配置结构体
gpio_config_t io_conf = {
.pin_bit_mask = (1ULL << MILLIMETER_WAVE_RADAR_PIN), // 选择GPIO引脚
.mode = GPIO_MODE_INPUT, // 设置为输入模式
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_ENABLE, // 使能下拉
.intr_type = GPIO_INTR_DISABLE // 禁用中断(如需中断需单独配置)
};
// 配置GPIO
gpio_config(&io_conf);
}
/*========================== I2C总线及挂载的从设备相关驱动 ==========================*/
/**
* @brief I2C总线及从机设备初始化函数
*
* 首先配置并创建I2C主机总线,然后依次添加IO扩展板和线性马达作为I2C从机设备到总线上。
* 若总线创建或设备添加失败,会输出错误信息并进行相应的资源清理(删除已创建的总线)。
* 初始化成功后,会通过ESP_LOGI输出IO扩展板和线性马达的从机地址信息。
*
* @return esp_err_t 初始化结果,ESP_OK表示成功,其他错误码表示相应的失败原因
*/
esp_err_t BoardSweekar::I2CMasterInit(void)
{
static const char *I2C_INIT = "I2C_INIT";
// 初始化IO扩展板复位引脚
gpio_config_t reset_io_conf = {
.pin_bit_mask = (1ULL << IO_EXPAND_RSTN),
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = GPIO_PULLUP_ENABLE, // 使能上拉
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE
};
gpio_config(&reset_io_conf);
// 执行复位时序:先拉低100ms,再拉高并等待100ms
gpio_set_level(IO_EXPAND_RSTN, 0); // 拉低复位
vTaskDelay(pdMS_TO_TICKS(100)); // 等待100ms
gpio_set_level(IO_EXPAND_RSTN, 1); // 释放复位
vTaskDelay(pdMS_TO_TICKS(100)); // 等待设备启动
ESP_LOGI(I2C_INIT, "IO扩展板复位完成");
// 创建统一的I2C总线(使用ESP-ADF的i2c_bus)
i2c_config_t i2c_cfg = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C0_MASTER_SDA_IO,
.scl_io_num = I2C0_MASTER_SCL_IO,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master = {
.clk_speed = 100000,
},
};
// 创建I2C总线(ESP-ADF的audio_board_init会复用这个总线)
bus_handle_ = i2c_bus_create(I2C0_MASTER_PORT, &i2c_cfg);
if (bus_handle_ == NULL) {
ESP_LOGE(TAG, "Failed to create I2C bus");
return ESP_FAIL;
}
vTaskDelay(pdMS_TO_TICKS(100)); // 等待设备启动
// ESP-ADF的i2c_bus不需要单独添加设备,直接通过总线句柄和设备地址进行通信
// 验证线性马达设备是否存在
esp_err_t err = i2c_bus_probe_addr(bus_handle_, LINEAR_MOTOR_I2C_SLAVE_ADDR << 1);
if (err != ESP_OK) {
ESP_LOGE(I2C_INIT, "线性马达设备未找到(地址:0x%02X),错误码: 0x%x", LINEAR_MOTOR_I2C_SLAVE_ADDR, err);
// 不返回错误,继续初始化
} else {
ESP_LOGI(I2C_INIT, "线性马达设备检测成功(地址:0x%02X)", LINEAR_MOTOR_I2C_SLAVE_ADDR);
}
// 验证IO扩展板设备是否存在
err = i2c_bus_probe_addr(bus_handle_, I2C_IO_EXPAND_SLAVE_ADDR << 1);
if (err != ESP_OK) {
ESP_LOGE(I2C_INIT, "IO扩展板设备未找到(地址:0x%02X),错误码: 0x%x", I2C_IO_EXPAND_SLAVE_ADDR, err);
// 不返回错误,继续初始化其他设备
} else {
ESP_LOGI(I2C_INIT, "IO扩展板设备检测成功(地址:0x%02X)", I2C_IO_EXPAND_SLAVE_ADDR);
}
// 验证陀螺仪设备是否存在
err = i2c_bus_probe_addr(bus_handle_, GYROSCOPE_I2C_SLAVE_ADDR << 1);
if (err != ESP_OK) {
ESP_LOGE(I2C_INIT, "陀螺仪设备未找到(地址:0x%02X),错误码: 0x%x", GYROSCOPE_I2C_SLAVE_ADDR, err);
// 不返回错误,继续初始化
} else {
ESP_LOGI(I2C_INIT, "陀螺仪设备检测成功(地址:0x%02X)", GYROSCOPE_I2C_SLAVE_ADDR);
}
// 为IO扩展板设置总线句柄和设备地址(使用7位地址)
io_expansion_.bus_handle_ = bus_handle_;
io_expansion_.device_addr_ = I2C_IO_EXPAND_SLAVE_ADDR << 1;
// 为线性马达设置总线句柄和设备地址(使用7位地址)
linear_motor_.bus_handle_ = bus_handle_;
linear_motor_.device_addr_ = LINEAR_MOTOR_I2C_SLAVE_ADDR << 1;
ESP_LOGI(I2C_INIT, "I2C总线初始化完成");
return ESP_OK;
}
/*========================== VBAT to VBAT_5V相关驱动 ==========================*/
/**
* @brief 开启VBAT to VBAT_5V
*
* 创建开启升压的电源管理单元
*
*/
void BoardSweekar::VbatToVbat5vInit(void)
{
// 配置VBAT_5V引脚为输出模式
gpio_config_t io_conf = {
.pin_bit_mask = (1ULL << VBAT_5V_PIN),
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE
};
gpio_config(&io_conf);
// 使能VBAT_5V
gpio_set_level(VBAT_5V_PIN, 1);
}
/*========================== 底座控制串口相关驱动 ==========================*/
/**
* @brief 底座控制命令串口初始化函数
*/
void BoardSweekar::BaseBoardControlUartInit(void)
{
uart_config_t uart_config = {
.baud_rate = BASE_BOARD_CTL_UART_BAUDRATE,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_DEFAULT,
};
// 1. 设置串口参数
ESP_ERROR_CHECK(uart_param_config(BASE_BOARD_CTL_UART_PORT, &uart_config));
// 2. 设置 UART 引脚
ESP_ERROR_CHECK(uart_set_pin(BASE_BOARD_CTL_UART_PORT, BASE_BOARD_CTL_UART_TX_PIN, BASE_BOARD_CTL_UART_RX_PIN,
UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
// 3. 安装 UART 驱动
ESP_ERROR_CHECK(uart_driver_install(BASE_BOARD_CTL_UART_PORT,
BASE_BOARD_CTL_UART_BUF_SIZE,
BASE_BOARD_CTL_UART_BUF_SIZE,
0, NULL, 0));
base_board_control_.SetUartPort(BASE_BOARD_CTL_UART_PORT);
}
@@ -0,0 +1,45 @@
#ifndef __BOARD_H__
#define __BOARD_H__
#include "config.h"
#include "io_expansion_board.h"
#include "stepper_motor.h"
#include "i2c_bus.h"
#include "gyroscope.h"
#include "touch_sensor.h"
#include "base_board_control.h"
class BoardSweekar
{
private:
i2c_bus_handle_t bus_handle_ = nullptr; // 使用ESP-ADF的I2C总线句柄
public:
IOExpansionBoard io_expansion_; // IO扩展板对象
LinearMotor linear_motor_; // 线性马达对象
Gyroscope gyroscope_; // 陀螺仪对象
TouchSensor touch_sensor_; // 触摸传感器对象
BaseBoardControl base_board_control_; // 底座控制对象
// 初始化步进电机
void StepperMotorInit(void);
// 初始化串口
void MillimeterWaveRadarUartInit(void);
//初始化毫米波雷达的中断引脚
void MillimeterWaveRadarGpioInit(void);
// 初始化I2C总线
esp_err_t I2CMasterInit(void);
// 初始化VBAT toVBAT_5V引脚
void VbatToVbat5vInit(void);
// 初始化底座控制串口
void BaseBoardControlUartInit(void);
// 获取I2C总线句柄
i2c_bus_handle_t GetBusHandle() const { return bus_handle_; }
};
#endif
@@ -0,0 +1,145 @@
/* 定义引脚分配 */
#ifndef _BOARD_CONFIG_H_
#define _BOARD_CONFIG_H_
/**
* @file config.h
* @brief 定义了引脚的分配。
* @author zouyuhua
* @date 2025年8月7日
*
*/
#include "driver/gpio.h"
#include "driver/i2c_master.h"
#include "driver/i2s.h"
#include "esp_log.h"
#include "esp_rom_sys.h" // 用于 esp_rom_delay_us
#include "esp_timer.h"
#include "esp_mac.h"
#include "driver/ledc.h"
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "driver/timer.h"
#include "esp_intr_alloc.h"
#include "soc/timer_group_struct.h" // 包含TIMERG0、TIMERG1的结构体定义
#include "soc/timer_group_reg.h" // 包含定时器相关寄存器宏定义
#include "driver/uart.h"
#include "esp_err.h"
#include "freertos/queue.h"
#include "soc/uart_reg.h"
#include "linear_motor.h"
#include "gyroscope.h"
#define TAG_BOARD "SWEEKAR_ESP32"
/*I2C总线引脚定义*/
#define I2C0_MASTER_PORT I2C_NUM_0
#define I2C0_MASTER_SDA_IO GPIO_NUM_2
#define I2C0_MASTER_SCL_IO GPIO_NUM_3
/* 步进电机配置 */
#define STEPPER_STEP_IO GPIO_NUM_42 // 步进电机脉冲输入引脚
#define STEPPER_TIMER_RES_HZ 1000000 // 步进电机定时器分辨率 1 MHz(1 us 步进)
/* 定义屏幕驱动控制引脚 */
#define ST7789_PIN_CLK GPIO_NUM_48 // SPI时钟引脚
#define ST7789_PIN_DC GPIO_NUM_38 // 数据/命令选择引脚RSEL
#define ST7789_PIN_MOSI GPIO_NUM_47 // SPI数据输出引脚
#define ST7789_PIN_CS GPIO_NUM_46 // SPI片选引脚
#define ST7789_PIN_BL GPIO_NUM_NC // 背光引脚
#define ST7789_PIN_RST GPIO_NUM_NC // 复位引脚
#define LCD_BL_ACTIVE_LEVEL 0 // 背光有效电平:1=高电平有效(NMOS),0=低电平有效(PMOS)
#define LCD_WIDTH 172 // 屏幕宽度(水平方向像素数)
#define LCD_HEIGHT 320 // 屏幕高度(垂直方向像素数)
/* 毫米波雷达配置参数 */
/* 定义毫米波雷达的中断引脚 */
#define MILLIMETER_WAVE_RADAR_PIN GPIO_NUM_35
// UART 配置参数
#define RADAR_UART_NUM UART_NUM_1 // 使用 UART1
#define UART_TX_PIN GPIO_NUM_40 // GPIO40 作为 TX(根据实际硬件连接调整)
#define UART_RX_PIN GPIO_NUM_39 // GPIO39 作为 RX
#define RADAR_BAUD_RATE 9600 // 雷达波特率
#define RADAR_BUF_SIZE 100 // 雷达接收缓冲区大小
/* IO扩展硬件配置常量 */
#define I2C_MASTER_FREQ_HZ 100000 // I2C通信频率(100kHz)(可更改至400000)
#define I2C_IO_EXPAND_SLAVE_ADDR 0x58 // AW9523BTQR器件地址,v1_1_13的addr1和addr0是0
#define GPIO_INPUT_PIN_SEL GPIO_NUM_10 // 中断检测引脚
#define ESP_INTR_FLAG_DEFAULT 0 // 中断标志默认值
#define IO_EXPAND_RSTN GPIO_NUM_45 // IO扩展板复位引脚
/* 定义线性马达的I2C从机配置常量 */
#define LINEAR_MOTOR_I2C_SLAVE_ADDR 0x5A // 线性马达的I2C从机地址
/* 定义陀螺仪的I2C从机配置常量 */
#define GYROSCOPE_I2C_SLAVE_ADDR 0x6A // 陀螺仪的I2C从机地址
#define GYROSCOPE_INPUT_PIN_SEL GPIO_NUM_21 // 陀螺仪中断引脚
/* 原生触摸引脚配置 */
// 触摸按键数量配置
#define TOUCH_BUTTON_NUM 3
// 触摸通道定义
#define TOUCH_PAD_CHANNEL_1 TOUCH_PAD_NUM11 // GPIO11
#define TOUCH_PAD_CHANNEL_2 TOUCH_PAD_NUM12 // GPIO12
#define TOUCH_PAD_CHANNEL_3 TOUCH_PAD_NUM13 // GPIO13
/* ES8311音频编解码器配置 (ESP-ADF兼容) */
#define AUDIO_INPUT_SAMPLE_RATE 24000
#define AUDIO_OUTPUT_SAMPLE_RATE 24000
#define AUDIO_INPUT_REFERENCE true
/* I2S GPIO定义 */
#define AUDIO_I2S_GPIO_MCLK GPIO_NUM_15
#define AUDIO_I2S_GPIO_WS GPIO_NUM_4
#define AUDIO_I2S_GPIO_BCLK GPIO_NUM_5
#define AUDIO_I2S_GPIO_DIN GPIO_NUM_6
#define AUDIO_I2S_GPIO_DOUT GPIO_NUM_7
/* PA引脚定义 */
#define AUDIO_CODEC_PA_PIN GPIO_NUM_NC
/* I2C配置 */
#define AUDIO_CODEC_I2C_SDA_PIN GPIO_NUM_2
#define AUDIO_CODEC_I2C_SCL_PIN GPIO_NUM_3
#define AUDIO_CODEC_ES8311_ADDR 0x18
#define AUDIO_CODEC_ES7210_ADDR 0x40
/* WS2812 RGB LED配置 */
#define WS2812_PIN GPIO_NUM_41 // WS2812数据引脚
#define WS2812_NUM_LEDS 2 // WS2812 LED数量
/* 创建VBAT to VBAT_5V */
#define VBAT_5V_PIN GPIO_NUM_NC // VBAT_5V引脚
/* 定义按键的中断引脚 */
#define BUTTON_PIN GPIO_NUM_0 // 按键中断引脚
#define RIGHT_BUTTON_PIN GPIO_NUM_8 // 按键中断引脚
/* 底座控制命令串口配置 */
#define BASE_BOARD_CTL_UART_PORT UART_NUM_0
#define BASE_BOARD_CTL_UART_TX_PIN GPIO_NUM_43
#define BASE_BOARD_CTL_UART_RX_PIN GPIO_NUM_44
#define BASE_BOARD_CTL_UART_BAUDRATE 115200
#define BASE_BOARD_CTL_UART_BUF_SIZE 256
#endif // _BOARD_CONFIG_H_
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,419 @@
#ifndef IO_EXPANSION_BOARD_H
#define IO_EXPANSION_BOARD_H
#include <cstdint>
#include <esp_log.h>
#include <esp_check.h>
#include <esp_timer.h>
#include <driver/gpio.h>
#include <functional>
#include "i2c_bus.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/queue.h>
#include <freertos/semphr.h>
#include "esp_err.h"
#include "config.h"
#include "portmacro.h"
// 前向声明,避免循环引用
class MillimeterWaveRadar;
class PhotoInterrupter;
class AdcBatteryMonitor;
// 回调函数类型定义
typedef std::function<void()> RadarCallback;
typedef std::function<void()> PhotoInterrupterStartCallback;
typedef std::function<void()> PhotoInterrupterEndCallback;
typedef std::function<void()> BatteryChargingCallback;
typedef std::function<void()> BatteryFullCallback;
typedef std::function<void()> BatteryNotChargingCallback;
/* 寄存器地址 */
#define INPUT_PORT0 0x00 // 输入端口0寄存器
#define INPUT_PORT1 0x01 // 输入端口1寄存器 0为低电平(仅支持读取)
#define OUTPUT_PORT0 0x02 // 输出端口0寄存器
#define OUTPUT_PORT1 0x03 // 输出端口1寄存器 0为低电平
#define CONFIG_PORT0 0x04 // 配置端口0寄存器
#define CONFIG_PORT1 0x05 // 配置端口1寄存器 0为输出模式
#define INT_PORT0 0x06 // 中断端口0寄存器
#define INT_PORT1 0x07 // 中断端口1寄存器 0为使能中断(根据手册默认是使能的)
#define CTL 0x11 // 全局控制寄存器
#define ID 0x23 // 芯片ID寄存器(0x23)
/***********************************IO扩展板电机引脚配置参数*************************************/
/* 设置步进电机方向 */
#define STEPPER_MOTOR_LEFT false //步进电机的方向为左转
#define STEPPER_MOTOR_RIGHT true //步进电机的方向为右转
#define STEPPER_MOTOR_DIR_PORT OUTPUT_PORT0 //步进电机方向引脚挂载在IO扩展板的输出端口OUTPUT_PORT0
#define STEPPER_MOTOR_DIR_PIN 4 //步进电机方向引脚对应的IO扩展板引脚P0_4
#define STEPPER_MOTOR_DIR_CONFIG CONFIG_PORT0 //步进电机方向引脚配置在P0_4
/* 设置步进电机细分模式 */
#define STEPPER_MOTOR_M0_PIN 5 //步进电机细分模式选择引脚对应IO扩展板引脚P1_5
#define STEPPER_MOTOR_M0_MADE_PORT OUTPUT_PORT1 //步进电机模式选择引脚挂载在IO扩展板的输出端口OUTPUT_PORT1
#define STEPPER_MOTOR_M0_CONFIG CONFIG_PORT1 //步进电机细分模式选择引脚配置在P1_5
#define STEPPER_MOTOR_M1_PIN 4 //步进电机细分模式选择引脚对应IO扩展板引脚P1_4
#define STEPPER_MOTOR_M1_MADE_PORT OUTPUT_PORT1 //步进电机模式选择引脚挂载在IO扩展板的输出端口OUTPUT_PORT1
#define STEPPER_MOTOR_M1_CONFIG CONFIG_PORT1 //步进电机细分模式选择引脚配置在P1_4
/* 设置步进电机睡眠引脚 */
#define STEPPER_MOTOR_SLEEP false //步进电机进入睡眠模式
#define STEPPER_MOTOR_WORK true //步进电机进入工作模式
#define STEPPER_MOTOR_SLEEP_PIN 6 //步进电机睡眠引脚对应IO扩展板引脚P1_6
#define STEPPER_MOTOR_SLEEP_CONFIG CONFIG_PORT1 //步进电机睡眠引脚配置在P1_6
#define STEPPER_MOTOR_SLEEP_PORT OUTPUT_PORT1 //步进电机睡眠引脚挂载在IO扩展板的输出端口OUTPUT_PORT1
/* 设置电机的使能引脚 */
#define STEPPER_MOTOR_ENABLE_PIN 7 //电机使能引脚对应IO扩展板引脚P0_7
#define STEPPER_MOTOR_ENABLE_PORT OUTPUT_PORT0 //电机使能引脚挂载在IO扩展板的输出端口OUTPUT_PORT0
#define STEPPER_MOTOR_ENABLE_CONFIG CONFIG_PORT0 //电机使能引脚配置在P0_7
#define STEPPER_MOTOR_ENABLE_ENABLE true //电机使能引脚状态为高电平
#define STEPPER_MOTOR_ENABLE_DISABLE false //电机使能引脚状态为低电平
/* 设置毫米波雷达对应IO扩展板的中断引脚 */
#define RADAR_INTERRUPT_PIN 7 //毫米波雷达中断引脚对应IO扩展板引脚P1_7
#define RADAR_INTERRUPT_CONFIG CONFIG_PORT1 //毫米波雷达中断引脚挂载在IO扩展板的输入端口
#define RADAR_INTERRUPT_INPUT INPUT_PORT1 //毫米波雷达中断引脚输入状态检测在INPUT_PORT1
#define RADAR_INTERRUPT_ENABLE true //毫米波雷达中断引脚状态为输入状态
#define RADAR_INTERRUPT_DISABLE false //毫米波雷达中断引脚状态为输出状态
/* 任务配置常量 */
#define WRITE_BUF_SIZE 2 // I2C单次写入字节数
#define READ_BUF_SIZE 2 // I2C单次读取字节数
#define I2C_TASK_PRIORITY 2 // 任务优先级(中等)
#define I2C_TASK_STACK 4096 // 任务栈大小(4KB)
// 光学传感器引脚定义
#define START_PHOTO_INTERRUPTER_PIN 2 // 光学传感器引脚(P0_2)
#define START_PHOTO_INTERRUPTER_CONFIG CONFIG_PORT0 // 光学传感器引脚挂载在IO扩展板的输入端口
#define START_PHOTO_INTERRUPTER_INPUT INPUT_PORT0 // 光学传感器引脚输入状态检测在INPUT_PORT0
#define START_PHOTO_INTERRUPTER_HIGH true // 光学传感器引脚状态为高电平
#define START_PHOTO_INTERRUPTER_LOW false // 光学传感器引脚状态为低电平
#define END_PHOTO_INTERRUPTER_PIN 3 // 光学传感器引脚(P0_3)
#define END_PHOTO_INTERRUPTER_PORT_CONFIG CONFIG_PORT0 // 光学传感器引脚挂载在IO扩展板的输入端口
#define END_PHOTO_INTERRUPTER_INPUT INPUT_PORT0 // 光学传感器引脚输入状态检测在INPUT_PORT0
#define END_PHOTO_INTERRUPTER_HIGH true // 光学传感器引脚状态为高电平
#define END_PHOTO_INTERRUPTER_LOW false // 光学传感器引脚状态为低电平
/***********************************IO扩展板LCD引脚配置参数*************************************/
/* 设置LCD的BL引脚 */
#define LCD_BL_PIN 6 //LCD背光引脚对应IO扩展板引脚P0_6
#define LCD_BL_PORT OUTPUT_PORT0 //LCD背光引脚挂载在IO扩展板的输出端口OUTPUT_PORT0
#define LCD_BL_CONFIG CONFIG_PORT0 //LCD背光引脚配置在P0_6
#define LCD_BL_HIGH true //LCD背光引脚状态为高电平
#define LCD_BL_LOW false //LCD背光引脚状态为低电平
/* 设置LCD的RST引脚 */
#define LCD_RST_PIN 1 //LCD复位引脚对应IO扩展板引脚P1_1
#define LCD_RST_CONFIG CONFIG_PORT1 //LCD复位引脚配置在P1_1
#define LCD_RST_PORT OUTPUT_PORT1 //LCD复位引脚挂载在IO扩展板的输出端口OUTPUT_PORT1
#define LCD_RST_HIGH true //LCD复位引脚状态为高电平
#define LCD_RST_LOW false //LCD复位引脚状态为低电平
/* 设置PA控制引脚 */
#define PA_CTRL_PIN 2 //PA控制引脚对应IO扩展板引脚P1_2
#define PA_CTRL_CONFIG CONFIG_PORT1 //PA控制引脚配置在P1_2
#define PA_CTRL_PORT OUTPUT_PORT1 //PA控制引脚挂载在IO扩展板的输出端口OUTPUT_PORT1
#define PA_CTRL_HIGH true //PA控制引脚状态为高电平
#define PA_CTRL_LOW false //PA控制引脚状态为低电平
// 电池充电检测引脚定义
#define BATTERY_FULL_INPUT INPUT_PORT1 // 电池充满检测引脚挂载在IO扩展板的输入端口
#define BATTERY_FULL_PIN 3 // 电池充满检测引脚对应IO扩展板引脚P1_3
#define BATTERY_FULL_CONFIG CONFIG_PORT1 // 电池充满检测引脚配置在P1_3
#define BATTERY_CHRG_INPUT INPUT_PORT0 // 充电检测引脚挂载在IO扩展板的输入端口
#define BATTERY_CHRG_PIN 5 // 充电检测引脚(P0_5)
#define BATTERY_CHRG_CONFIG CONFIG_PORT0 // 充电检测引脚挂载在IO扩展板的输入端口
#define TAG_GPIO_IO_EXPAND_DETECT "GPIO_IO_EXPAND_DETECT" // GPIO中断检测日志标签
#define TAG_I2C_IO_EXPAND_TASK "I2C_IO_EXPAND_TASK" // I2CIO扩展板任务日志标签
// GPIO引脚定义
#define GPIO_INPUT_PIN_SEL GPIO_NUM_10 // IO扩展板中断检测引脚
#define IO_EXPAND_RSTN GPIO_NUM_45 // IO扩展板复位引脚
/**
* @class IOExpansionBoard
* @brief I/O扩展板驱动类,封装AW9523BTQR芯片操作
*/
class IOExpansionBoard
{
public:
/**
* @brief 构造函数
*/
IOExpansionBoard();
/**
* @brief 设置毫米波雷达指针
* @param radar 毫米波雷达对象指针
*/
void SetRadar(MillimeterWaveRadar* radar) { radar_ = radar; };
/**
* @brief 设置限位开关指针
* @param photo_interrupter 限位开关对象指针
*/
void setPhotoInterrupter(PhotoInterrupter* photo_interrupter) { photo_interrupter_ = photo_interrupter; };
/**
* @brief 设置电池监控器指针
* @param battery_monitor 电池监控器对象指针
*/
void setBatteryMonitor(AdcBatteryMonitor* battery_monitor) { battery_monitor_ = battery_monitor; };
/**
* @brief 析构函数
*/
~IOExpansionBoard();
/**
* @brief 初始化GPIO中断检测
* @param gpio_num 中断引脚编号
* @return esp_err_t 初始化结果
*/
esp_err_t InterruptGpioInit(gpio_num_t gpio_num);
/**
* @brief 初始化IO扩展板复位引脚
* @param gpio_num 复位引脚编号
* @return esp_err_t 初始化结果
*/
esp_err_t ResetGpioInit(gpio_num_t gpio_num);
/**
* @brief 初始化IO扩展板复位引脚
* @param gpio_num 复位引脚编号
* @return esp_err_t 初始化结果
*/
esp_err_t ResetIoExpand();
/**
* @brief 初始化I2C主机通信
* @return esp_err_t 初始化结果
*/
// esp_err_t IoExpansionI2cInit();
/**
* @brief 创建I2C数据读取任务
*/
void CreateI2cReadTask();
/**
* @brief 启动I2C任务(整合初始化和任务创建)
* @return esp_err_t 操作结果
*/
esp_err_t StartTask();
/**
* @brief 写寄存器数据
* @param reg_addr 寄存器地址
* @param data 要写入的数据
* @return esp_err_t 操作结果
*/
esp_err_t IoexpandWriteReg(uint8_t reg_addr, uint8_t data);
/**
* @brief 读寄存器数据
* @param reg_addr 寄存器地址
* @param data 要读出的数据
* @return esp_err_t 操作结果
*/
esp_err_t IoexpandReadReg(uint8_t reg_addr, uint8_t *data);
/**
* @brief 读取输入端口0寄存器数据
* @param data 输出参数,用于存储读取到的数据
* @return esp_err_t 操作结果
*/
esp_err_t ReadInputPort0(uint8_t *data);
/**
* @brief 读取输入端口1寄存器数据
* @param data 输出参数,用于存储读取到的数据
* @return esp_err_t 操作结果
*/
esp_err_t ReadInputPort1(uint8_t *data);
// /**
// * @brief 设置IO扩展板GPIO中断状态 通过读取Input_Port0 和 Input_Port1 寄存器可以清除中断
// * @param reg_addr 寄存器地址
// * @return esp_err_t 操作结果
// */
// esp_err_t SetInterruptStatus(bool status);
/**
* @brief 配置IO扩展版上的IO口为输出还是输入,并且设置初始为高电平
* @return esp_err_t 操作结果
*/
esp_err_t IoexpandSetMode();
/**
* @brief 设置步进电机的细分模式
* @param mode 模式:1/2/4/8/16/32/64
* @return esp_err_t 操作结果
*/
void SetStepperMicrostepMode(uint8_t mode, uint8_t OUTPUT_PORT_m0, uint8_t m0_pin, uint8_t OUTPUT_PORT_m1, uint8_t m1_pin);
/**
* @brief 设置步进电机的方向
* @param dir 方向
* @param OUTPUT_PORT 输出端口
* @param pin 引脚号
* @return esp_err_t 操作结果
*/
esp_err_t StepperMotorSetDir(bool dir, uint8_t OUTPUT_PORT, uint8_t pin);
/**
* @brief 设置步进电机的睡眠模式
* @param 是否进入睡眠模式
* @param 输出端口
* @param 引脚号
* @return esp_err_t 操作结果
*/
esp_err_t SetMotorSleepMode(bool mode, uint8_t OUTPUT_PORT, uint8_t nsleep_pin);
/**
* @brief 设置步进电机的使能引脚状态
* @param 使能状态
* @return esp_err_t 操作结果
*/
esp_err_t SetMotorEnableMode(bool enable, uint8_t OUTPUT_PORT, uint8_t enable_pin);
/**
* @brief 设置LCD的BL引脚状态
* @param BL状态
* @return esp_err_t 操作结果
*/
esp_err_t SetLcdBlMode(bool mode, uint8_t OUTPUT_PORT, uint8_t bl_pin);
/**
* @brief 设置LCD的RST引脚状态
* @param RST状态
* @return esp_err_t 操作结果
*/
esp_err_t SetLcdResetMode(bool mode, uint8_t OUTPUT_PORT, uint8_t rst_pin);
/**
* @brief 设置PA控制引脚状态
* @param PA_CTRL状态(低电平为选中状态,高电平为不选中状态)
* @return esp_err_t 操作结果
*/
esp_err_t SetPaCtrlMode(bool mode, uint8_t OUTPUT_PORT, uint8_t pa_ctrl_pin);
/**
* @brief 设置雷达中断引脚
* @param 毫米波雷达的中断引脚模式
* @param 输入端口
* @param 引脚号
* @return esp_err_t 操作结果
*/
esp_err_t SetRadarInterruptPin(bool mode, uint8_t INPUT_PORT, uint8_t interrupt_pin);
/**
* @brief 计算Port0的字节值
* @return uint8_t 操作结果
*/
uint8_t ByteCalculatePort0();
/**
* @brief 计算Port1的字节值
* @return uint8_t 操作结果
*/
uint8_t ByteCalculatePort1();
/**
* @brief 设置雷达中断回调函数
* @param callback 雷达中断回调函数
*/
void SetRadarCallback(RadarCallback callback) { radar_callback_ = callback; }
/**
* @brief 设置光学传感器开始中断回调函数
* @param callback 光学传感器开始中断回调函数
*/
void SetPhotoInterrupterStartCallback(PhotoInterrupterStartCallback callback) { photo_start_callback_ = callback; }
/**
* @brief 设置光学传感器结束中断回调函数
* @param callback 光学传感器结束中断回调函数
*/
void SetPhotoInterrupterEndCallback(PhotoInterrupterEndCallback callback) { photo_end_callback_ = callback; }
/**
* @brief 设置电池充电中断回调函数
* @param callback 电池充电中断回调函数
*/
void SetBatteryChargingCallback(BatteryChargingCallback callback) { battery_charging_callback_ = callback; }
/**
* @brief 设置电池充满中断回调函数
* @param callback 电池充满中断回调函数
*/
void SetBatteryFullCallback(BatteryFullCallback callback) { battery_full_callback_ = callback; }
/**
* @brief 设置电池非充电中断回调函数
* @param callback 电池非充电中断回调函数
*/
void SetBatteryNotChargingCallback(BatteryNotChargingCallback callback) { battery_not_charging_callback_ = callback; }
// 公共成员变量
i2c_bus_handle_t bus_handle_ = nullptr; // I2C总线句柄
uint8_t device_addr_; // I2C设备地址
private:
// 静态成员函数
MillimeterWaveRadar* radar_ = nullptr; // 毫米波雷达指针,用于触发回调
PhotoInterrupter* photo_interrupter_ = nullptr; // 限位开关指针,用于触发回调
AdcBatteryMonitor* battery_monitor_ = nullptr; // 电池监控器指针,用于触发回调
static void IRAM_ATTR GpioIsrHandler(void* arg); // 中断处理函数
static void I2cReadTask(void* pvParameters); // I2C数据读取任务函数
// 成员变量用于状态跟踪
uint8_t last_port0_state_ = 0; // 上次检测到的Port0状态
uint8_t last_port1_state_ = 0; // 上次检测到的Port1状态
bool radar_last_state_ = false; // 雷达引脚上一次的状态
bool battery_charging_last_state_ = false; // 电池充电状态上一次的状态
bool battery_full_last_state_ = false; // 电池充满状态上一次的状态
// 回调函数成员变量
RadarCallback radar_callback_ = nullptr;
PhotoInterrupterStartCallback photo_start_callback_ = nullptr;
PhotoInterrupterEndCallback photo_end_callback_ = nullptr;
BatteryChargingCallback battery_charging_callback_ = nullptr;
BatteryFullCallback battery_full_callback_ = nullptr;
BatteryNotChargingCallback battery_not_charging_callback_ = nullptr;
// PhotoInterrupter* photo_interrupter_ = nullptr; // 光学传感器指针,用于触发回调
// /**
// * @brief 分配静态任务所需的内存
// * @return bool 分配是否成功
// */
// bool AllocateStaticTaskMemory();
// /**
// * @brief 释放静态任务分配的内存
// */
// void FreeStaticTaskMemory();
// 实例成员变量
EventGroupHandle_t i2c_task_event_group_ = nullptr; // 事件组
TaskHandle_t xI2CReadTaskHandle_ = nullptr; // 任务句柄
bool is_initialized_ = false; // 初始化状态标记(新增)
gpio_num_t interrupt_gpio_ = GPIO_NUM_NC; // 中断引脚
gpio_num_t reset_gpio_ = GPIO_NUM_NC; // 复位引脚
// StackType_t* pI2CReadTaskStackBuffer = nullptr; // 任务栈指针(PSRAM)
// StaticTask_t* pxI2CReadTaskBuffer = nullptr; // 任务控制块指针(内部RAM)
};
#endif