diff --git a/code/hello_world_01/.vscode/settings.json b/code/hello_world_01/.vscode/settings.json index fba648e..226b5d8 100644 --- a/code/hello_world_01/.vscode/settings.json +++ b/code/hello_world_01/.vscode/settings.json @@ -3,8 +3,8 @@ "idf.openOcdConfigs": [ "board/esp32s3-builtin.cfg" ], - "idf.portWin": "COM10", - "idf.currentSetup": "C:\\Users\\wuwen\\esp\\v5.5.1\\esp-idf", + "idf.portWin": "COM9", + "idf.currentSetup": "C:\\Users\\wuwen\\esp\\v5.5.2\\esp-idf", "idf.customExtraVars": { "OPENOCD_SCRIPTS": "C:\\Espressif\\tools\\openocd-esp32\\v0.11.0-esp32-20220411/openocd-esp32/share/openocd/scripts", "IDF_CCACHE_ENABLE": "1", diff --git a/code/hello_world_01/README.md b/code/hello_world_01/README.md index f3aa0c5..54d1077 100644 --- a/code/hello_world_01/README.md +++ b/code/hello_world_01/README.md @@ -1,53 +1,31 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | Linux | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | ----- | +# 工程备注 -# Hello World Example +## SPI 接口配置 -Starts a FreeRTOS task to print "Hello World". +### 1. 核心 IO 引脚 +| 引脚名称 | 引脚编号 | +|----------|----------| +| SCK | 36 | +| MOSI | 33 | +| MISO | 47 | -(See the README.md file in the upper level 'examples' directory for more information about examples.) +### 2. 外接设备引脚(SPI 从设备) +#### 2.1 E-Paper(电子纸) +| 引脚名称 | 引脚编号 | +|----------|----------| +| DC | 35 | +| SC | 34 | +| BUSY | 37 | -## How to use example +#### 2.2 Lora 模块 +| 引脚名称 | 引脚编号 | +|----------|----------| +| CS | 3 | +| BUSY | 6 | +| RST | 4 | +| INT | 5 | -Follow detailed instructions provided specifically for this example. - -Select the instructions depending on Espressif chip installed on your development board: - -- [ESP32 Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/stable/get-started/index.html) -- [ESP32-S2 Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/get-started/index.html) - - -## Example folder contents - -The project **hello_world** contains one source file in C language [hello_world_main.c](main/hello_world_main.c). The file is located in folder [main](main). - -ESP-IDF projects are built using CMake. The project build configuration is contained in `CMakeLists.txt` files that provide set of directives and instructions describing the project's source files and targets (executable, library, or both). - -Below is short explanation of remaining files in the project folder. - -``` -├── CMakeLists.txt -├── pytest_hello_world.py Python script used for automated testing -├── main -│ ├── CMakeLists.txt -│ └── hello_world_main.c -└── README.md This is the file you are currently reading -``` - -For more information on structure and contents of ESP-IDF projects, please refer to Section [Build System](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html) of the ESP-IDF Programming Guide. - -## Troubleshooting - -* Program upload failure - - * Hardware connection is not correct: run `idf.py -p PORT monitor`, and reboot your board to see if there are any output logs. - * The baud rate for downloading is too high: lower your baud rate in the `menuconfig` menu, and try again. - -## Technical support and feedback - -Please use the following feedback channels: - -* For technical queries, go to the [esp32.com](https://esp32.com/) forum -* For a feature request or bug report, create a [GitHub issue](https://github.com/espressif/esp-idf/issues) - -We will get back to you as soon as possible. +#### 2.3 SD-Card(SD 卡) +| 引脚名称 | 引脚编号 | +|----------|----------| +| CS | 48 | \ No newline at end of file diff --git a/code/hello_world_01/main/epaper.c b/code/hello_world_01/main/epaper.c new file mode 100644 index 0000000..616ea76 --- /dev/null +++ b/code/hello_world_01/main/epaper.c @@ -0,0 +1,35 @@ +#include "epaper.h" + +static const char *TAG = "E-PAPER"; + +void epd_gpio_init(void) +{ + // 1. 配置CS/DC为输出模式 + gpio_config_t io_conf = {0}; + io_conf.mode = GPIO_MODE_OUTPUT; + io_conf.pin_bit_mask = (1ULL << EPD_CS_PIN) | (1ULL << EPD_DC_PIN); + io_conf.pull_up_en = GPIO_PULLUP_DISABLE; + io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; + io_conf.intr_type = GPIO_INTR_DISABLE; + gpio_config(&io_conf); + + // 2. 配置BUSY为输入模式(上拉,防止电平飘移) + io_conf.mode = GPIO_MODE_INPUT; + io_conf.pin_bit_mask = (1ULL << EPD_BUSY_PIN); + io_conf.pull_up_en = GPIO_PULLUP_ENABLE; + io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; + gpio_config(&io_conf); + + // 3. 初始化引脚默认电平 + gpio_set_level(EPD_CS_PIN, 1); // CS默认拉高(未选中) + gpio_set_level(EPD_DC_PIN, 0); // DC默认拉低(指令模式) + + ESP_LOGI(TAG, "EPD GPIO init success (CS:%d, DC:%d)", + EPD_CS_PIN, EPD_DC_PIN); +} + +void epd_init() +{ + ESP_LOGI(TAG, "init_GPIO"); + epd_gpio_init(); +} \ No newline at end of file diff --git a/code/hello_world_01/main/epaper.h b/code/hello_world_01/main/epaper.h new file mode 100644 index 0000000..d48b2d4 --- /dev/null +++ b/code/hello_world_01/main/epaper.h @@ -0,0 +1,20 @@ +#ifndef EPAPER_H +#define EPAPER_H + + +#include +#include +#include "driver/gpio.h" +#include "esp_log.h" +#include "esp_system.h" + +#include "spi.h" + +#define EPD_CS_PIN 34 +#define EPD_DC_PIN 35 +#define EPD_BUSY_PIN 37 + + +void epd_init(); + +#endif \ No newline at end of file diff --git a/code/hello_world_01/main/hello_world_main.c b/code/hello_world_01/main/hello_world_main.c index 9f91c92..02939b6 100644 --- a/code/hello_world_01/main/hello_world_main.c +++ b/code/hello_world_01/main/hello_world_main.c @@ -18,7 +18,8 @@ #include "esp_timer.h" #include "spiffs.h" - +#include "spi.h" +#include "epaper.h" static const char *TAG = "SYS"; @@ -66,6 +67,9 @@ void app_main(void) ESP_LOGI(TAG,"PSRAM 总大小:%u KB,可用:%u KB\n", psram_total/1024, psram_free/1024); + spi_init(); + epd_init(); + // 1. 初始化 SPIFFS const char *spiffs_base_path = "/spiffs"; diff --git a/code/hello_world_01/main/spi.c b/code/hello_world_01/main/spi.c new file mode 100644 index 0000000..33a5a1f --- /dev/null +++ b/code/hello_world_01/main/spi.c @@ -0,0 +1,97 @@ +#include "spi.h" + +#define USE_SPI_HOST SPI2_HOST + +static const char *TAG = "SPI_2"; + +spi_device_handle_t spi2; + +void spi_init() +{ + ESP_LOGI(TAG, "初始化SPI IO总线"); + esp_err_t ret; + + // 1. SPI 总线配置 + spi_bus_config_t buscfg = { + .miso_io_num = VSPI_MISO, // MISO 引脚 + .mosi_io_num = VSPI_MOSI, // MOSI 引脚 + .sclk_io_num = VSPI_SCLK, // 时钟引脚 + .quadwp_io_num = -1, // 不使用 QWP + .quadhd_io_num = -1, // 不使用 QHD + .max_transfer_sz = 4096, // 最大传输大小 + // .flags = 0, + // .intr_flags = 0, + }; + + // 2. 初始化 SPI 总线 + ret = spi_bus_initialize(USE_SPI_HOST, &buscfg, SPI_DMA_DISABLED); + if (ret != ESP_OK) + { + ESP_LOGE(TAG, "IO总线初始化失败"); + return; + } + + ESP_LOGI(TAG, "SPI IO总线初始化成功"); + + ESP_LOGI(TAG, "SPI 设备配置"); + + spi_device_interface_config_t devcfg = { + .command_bits = 0, // 无命令位 + .address_bits = 0, // 无地址位 + .dummy_bits = 0, + .mode = 0, // SPI 模式 0 + .clock_speed_hz = 80000000, // + .spics_io_num = -1, + .queue_size = 1, // 队列深度,因为有几个设备共用了这个SPI,而有的设备有busy信号,准备整个专门的线程去控制如果有busy信号先跳过这次传输 + .flags = SPI_DEVICE_NO_DUMMY, // 禁用 dummy 周期 + .input_delay_ns = 0, + .pre_cb = NULL, + .post_cb = NULL, + + }; + + ret = spi_bus_add_device(USE_SPI_HOST, &devcfg, &spi2); + if (ret != ESP_OK) + { + ESP_LOGE(TAG, "SPI 设备配置失败"); + return; + } +} + + +/** + * @brief 同步SPI全双工传输函数(无队列,直接硬件收发) + * @param tx_data: 待发送数据缓冲区(NULL则仅接收) + * @param rx_data: 接收数据缓冲区(NULL则仅发送) + * @param len: 传输长度(字节数,收发长度一致) + * @return esp_err_t: 传输结果 + * @note 全双工模式下,发送和接收同时进行,len需匹配收发数据长度 + */ +esp_err_t epd_spi_send_sync_fullduplex(const uint8_t *tx_data, uint8_t *rx_data, size_t len) +{ + // 入参校验:长度为0 或 收发缓冲区同时为NULL + if (len == 0 || (tx_data == NULL && rx_data == NULL)) { + ESP_LOGE(TAG, "Invalid args: len=%d, tx=%p, rx=%p", len, tx_data, rx_data); + return ESP_ERR_INVALID_ARG; + } + + // 1. 初始化SPI传输结构体(全双工配置核心) + spi_transaction_t t = { + .length = len * 8, // 传输位数(1字节=8位,收发长度一致) + .tx_buffer = tx_data, // 发送缓冲区(NULL则发送0x00) + .rx_buffer = rx_data, // 接收缓冲区(NULL则丢弃接收数据) + .flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_USE_RXDATA, // 强制使用本地缓冲区 + // 全双工关键:无需额外flag,只要同时配置tx/rx_buffer即启用全双工 + }; + + // 2. 同步传输(无队列,阻塞等待硬件完成) + esp_err_t ret = spi_device_transmit(spi2, &t); + + if (ret != ESP_OK) { + ESP_LOGE(TAG, "SPI full duplex transmit failed: %s", esp_err_to_name(ret)); + } else { + ESP_LOGD(TAG, "SPI full duplex transmit success, len=%d", len); + } + + return ret; +} diff --git a/code/hello_world_01/main/spi.h b/code/hello_world_01/main/spi.h new file mode 100644 index 0000000..c6b8b26 --- /dev/null +++ b/code/hello_world_01/main/spi.h @@ -0,0 +1,22 @@ +#ifndef SPI_H +#define SPI_H + +#include +#include +#include "driver/gpio.h" +#include "driver/spi_master.h" +#include "esp_log.h" +#include "esp_system.h" + +#define VSPI_MISO 47 +#define VSPI_MOSI 33 +#define VSPI_SCLK 36 + + + +void spi_init(); + +extern spi_device_handle_t spi2; + + +#endif /* SPI_H */ \ No newline at end of file diff --git a/code/hello_world_01/sdkconfig b/code/hello_world_01/sdkconfig index 50898ae..1adbe58 100644 --- a/code/hello_world_01/sdkconfig +++ b/code/hello_world_01/sdkconfig @@ -1,6 +1,6 @@ # # Automatically generated file. DO NOT EDIT. -# Espressif IoT Development Framework (ESP-IDF) 5.5.1 Project Configuration +# Espressif IoT Development Framework (ESP-IDF) 5.5.2 Project Configuration # CONFIG_SOC_ADC_SUPPORTED=y CONFIG_SOC_UART_SUPPORTED=y @@ -124,7 +124,6 @@ CONFIG_SOC_GPIO_OUT_RANGE_MAX=48 CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0x0001FFFFFC000000 CONFIG_SOC_GPIO_CLOCKOUT_BY_IO_MUX=y CONFIG_SOC_GPIO_CLOCKOUT_CHANNEL_NUM=3 -CONFIG_SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP=y CONFIG_SOC_DEDIC_GPIO_OUT_CHANNELS_NUM=8 CONFIG_SOC_DEDIC_GPIO_IN_CHANNELS_NUM=8 CONFIG_SOC_DEDIC_GPIO_OUT_AUTO_ENABLE=y @@ -185,7 +184,7 @@ CONFIG_SOC_RMT_CHANNELS_PER_GROUP=8 CONFIG_SOC_RMT_MEM_WORDS_PER_CHANNEL=48 CONFIG_SOC_RMT_SUPPORT_RX_PINGPONG=y CONFIG_SOC_RMT_SUPPORT_RX_DEMODULATION=y -CONFIG_SOC_RMT_SUPPORT_TX_ASYNC_STOP=y +CONFIG_SOC_RMT_SUPPORT_ASYNC_STOP=y CONFIG_SOC_RMT_SUPPORT_TX_LOOP_COUNT=y CONFIG_SOC_RMT_SUPPORT_TX_LOOP_AUTO_STOP=y CONFIG_SOC_RMT_SUPPORT_TX_SYNCHRO=y @@ -856,6 +855,7 @@ CONFIG_SPIRAM_BOOT_HW_INIT=y CONFIG_SPIRAM_BOOT_INIT=y CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION=y # CONFIG_SPIRAM_IGNORE_NOTFOUND is not set +# CONFIG_SPIRAM_USE_MEMMAP is not set # CONFIG_SPIRAM_USE_CAPS_ALLOC is not set CONFIG_SPIRAM_USE_MALLOC=y CONFIG_SPIRAM_MEMTEST=y