esp32 读写flash idf完整代码
时间: 2023-09-03 21:12:15 浏览: 182
以下是 ESP32 IDF 中读写 Flash 的完整代码示例:
```c
#include <stdio.h>
#include "esp_log.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
#include "driver/spi_master.h"
#include "esp_partition.h"
static const char* TAG = "flash-example";
#define SPI_DMA_CHAN 2
#define FLASH_SECTOR_SIZE 0x1000
#define SPI_FLASH_MOSI_PIN 23
#define SPI_FLASH_MISO_PIN 19
#define SPI_FLASH_CLK_PIN 18
#define SPI_FLASH_CS_PIN 5
// Function to initialize SPI bus
static void spi_init()
{
// Define bus configuration
spi_bus_config_t buscfg = {
.miso_io_num = SPI_FLASH_MISO_PIN,
.mosi_io_num = SPI_FLASH_MOSI_PIN,
.sclk_io_num = SPI_FLASH_CLK_PIN,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = 0
};
// Define device configuration
spi_device_interface_config_t devcfg = {
.clock_speed_hz = 10*1000*1000, // Clock out at 10 MHz
.mode = 0, // SPI mode 0
.spics_io_num = SPI_FLASH_CS_PIN, // CS pin
.queue_size = 7, // We want to be able to queue 7 transactions at a time
.pre_cb = NULL, // No pre-transfer callback
.post_cb = NULL, // No post-transfer callback
.flags = SPI_DEVICE_NO_DUMMY
};
// Initialize the SPI bus
esp_err_t ret = spi_bus_initialize(VSPI_HOST, &buscfg, SPI_DMA_CHAN);
ESP_ERROR_CHECK(ret);
// Attach the flash chip to the SPI bus
spi_device_handle_t spi_handle;
ret = spi_bus_add_device(VSPI_HOST, &devcfg, &spi_handle);
ESP_ERROR_CHECK(ret);
}
// Function to read from flash
static void read_flash()
{
ESP_LOGI(TAG, "Reading flash...");
// Open flash partition
const esp_partition_t* partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, "my_partition");
if (!partition) {
ESP_LOGE(TAG, "Partition not found");
return;
}
// Initialize SPI bus
spi_init();
// Set up transfer
spi_transaction_t t = {
.flags = SPI_TRANS_USE_RXDATA | SPI_TRANS_USE_TXDATA,
.cmd = 0x03, // Read command
.addr = 0x0, // Start address of read
.length = 8*FLASH_SECTOR_SIZE // Read data size
};
// Read data from flash
uint8_t* data = malloc(FLASH_SECTOR_SIZE);
t.rx_buffer = data;
for (int i = 0; i < partition->size; i += FLASH_SECTOR_SIZE) {
t.addr = i;
esp_err_t ret = spi_device_polling_transmit(spi_handle, &t);
ESP_ERROR_CHECK(ret);
ESP_LOGI(TAG, "Data at address 0x%x:", i);
for (int j = 0; j < FLASH_SECTOR_SIZE; j++) {
printf("%02x ", data[j]);
}
printf("\n");
}
// Clean up
free(data);
spi_bus_remove_device(spi_handle);
spi_bus_free(VSPI_HOST);
}
// Function to write to flash
static void write_flash()
{
ESP_LOGI(TAG, "Writing flash...");
// Open flash partition
const esp_partition_t* partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, "my_partition");
if (!partition) {
ESP_LOGE(TAG, "Partition not found");
return;
}
// Initialize SPI bus
spi_init();
// Erase flash sector
esp_err_t ret = spi_flash_erase_sector(partition->address);
ESP_ERROR_CHECK(ret);
// Set up transfer
spi_transaction_t t = {
.flags = SPI_TRANS_USE_RXDATA | SPI_TRANS_USE_TXDATA,
.cmd = 0x02, // Write command
.addr = 0x0, // Start address of write
.length = 8*FLASH_SECTOR_SIZE // Write data size
};
// Write data to flash
uint8_t* data = malloc(FLASH_SECTOR_SIZE);
for (int i = 0; i < FLASH_SECTOR_SIZE; i++) {
data[i] = i % 255;
}
t.tx_buffer = data;
ret = spi_device_polling_transmit(spi_handle, &t);
ESP_ERROR_CHECK(ret);
// Clean up
free(data);
spi_bus_remove_device(spi_handle);
spi_bus_free(VSPI_HOST);
}
void app_main()
{
// Initialize NVS
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
// Write data to flash
write_flash();
// Read data from flash
read_flash();
}
```
这个示例代码演示了如何使用 ESP32 的 SPI 总线来读写 Flash。其中,`spi_init()` 函数初始化了 SPI 总线,`read_flash()` 函数从 Flash 中读取数据,`write_flash()` 函数将数据写入 Flash。在这个示例代码中,我们使用了 SPI 总线连接的 Flash,但是也可以连接其他的 SPI 设备。同时,我们使用了 ESP-IDF 中提供的 `spi_device_polling_transmit()` 函数来进行数据的读写。如果你需要进行更高级的操作,可以使用 `spi_device_queue_trans()` 函数来设置队列,并使用回调函数来处理数据。
阅读全文