ESP32-IDF SDMMC读写BMI160保存陀螺仪加速度数据代码
时间: 2023-08-06 20:10:12 浏览: 184
以下是ESP32-IDF SDMMC读写BMI160保存陀螺仪加速度数据的示例代码:
```c
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_err.h"
#include "driver/sdmmc_host.h"
#include "sdmmc_cmd.h"
#include "driver/gpio.h"
#include "driver/i2c.h"
#define SDMMC_PIN_NUM_MISO 2
#define SDMMC_PIN_NUM_MOSI 15
#define SDMMC_PIN_NUM_CLK 14
#define SDMMC_PIN_NUM_CS 13
#define I2C_MASTER_SCL_IO 22 /*!< gpio number for I2C master clock */
#define I2C_MASTER_SDA_IO 23 /*!< gpio number for I2C master data */
#define I2C_MASTER_NUM I2C_NUM_0 /*!< I2C port number for master dev */
#define I2C_MASTER_FREQ_HZ 100000 /*!< I2C master clock frequency */
#define BMI160_I2C_ADDR 0x68 /*!< I2C address of BMI160 */
#define SDMMC_CARD_INTR_GPIO GPIO_NUM_34 /*!< GPIO number for SDMMC interrupt */
#define BUFFER_SIZE 512 /*!< Size of the buffer for SD card operations */
static sdmmc_card_t *card;
#define BMI160_REG_ACCD_X_LSB 0x12
#define BMI160_REG_ACCD_X_MSB 0x13
#define BMI160_REG_ACCD_Y_LSB 0x14
#define BMI160_REG_ACCD_Y_MSB 0x15
#define BMI160_REG_ACCD_Z_LSB 0x16
#define BMI160_REG_ACCD_Z_MSB 0x17
#define BMI160_REG_GYRD_X_LSB 0x0C
#define BMI160_REG_GYRD_X_MSB 0x0D
#define BMI160_REG_GYRD_Y_LSB 0x0E
#define BMI160_REG_GYRD_Y_MSB 0x0F
#define BMI160_REG_GYRD_Z_LSB 0x10
#define BMI160_REG_GYRD_Z_MSB 0x11
static esp_err_t i2c_master_init(void)
{
int i2c_master_port = I2C_MASTER_NUM;
i2c_config_t conf;
conf.mode = I2C_MODE_MASTER;
conf.sda_io_num = I2C_MASTER_SDA_IO;
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
conf.scl_io_num = I2C_MASTER_SCL_IO;
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
conf.master.clk_speed = I2C_MASTER_FREQ_HZ;
i2c_param_config(i2c_master_port, &conf);
return i2c_driver_install(i2c_master_port, conf.mode, 0, 0, 0);
}
static esp_err_t bmi160_write_reg(uint8_t reg_addr, uint8_t data)
{
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, BMI160_I2C_ADDR << 1 | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, reg_addr, true);
i2c_master_write_byte(cmd, data, true);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
return ret;
}
static esp_err_t bmi160_read_reg(uint8_t reg_addr, uint8_t *data)
{
if (data == NULL) {
return ESP_ERR_INVALID_ARG;
}
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, BMI160_I2C_ADDR << 1 | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, reg_addr, true);
i2c_master_start(cmd);
i2c_master_write_byte(cmd, BMI160_I2C_ADDR << 1 | I2C_MASTER_READ, true);
i2c_master_read_byte(cmd, data, I2C_MASTER_NACK);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
return ret;
}
static void sdmmc_card_init()
{
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
slot_config.gpio_cd = SDMMC_CARD_INTR_GPIO;
slot_config.width = 1;
sdmmc_card_t *card;
esp_err_t ret = sdmmc_host_init_slot(&host, &slot_config, &card);
if (ret != ESP_OK) {
printf("Failed to initialize SD card.\n");
return;
}
ret = sdmmc_card_init(&host, card);
if (ret != ESP_OK) {
printf("Failed to initialize SD card.\n");
return;
}
ret = sdmmc_card_set_voltage(card, 3.3);
if (ret != ESP_OK) {
printf("Failed to set SD card voltage.\n");
return;
}
printf("SD card initialized and ready to use.\n");
}
static void sdmmc_card_write(char *filename, void *data, size_t size)
{
FILE *file = fopen(filename, "w");
if (file == NULL) {
printf("Failed to open file for writing.\n");
return;
}
size_t write_size = fwrite(data, 1, size, file);
if (write_size != size) {
printf("Failed to write data to file.\n");
} else {
printf("Data written to file successfully.\n");
}
fclose(file);
}
void app_main()
{
// Initialize I2C master
esp_err_t ret = i2c_master_init();
if (ret != ESP_OK) {
printf("Failed to initialize I2C master.\n");
return;
}
// Initialize SD card
sdmmc_card_init();
// Initialize BMI160
bmi160_write_reg(0x7E, 0x15); // Reset
vTaskDelay(100 / portTICK_RATE_MS);
bmi160_write_reg(0x7E, 0x11); // Enable accelerometer and gyroscope
bmi160_write_reg(0x41, 0x28); // Accelerometer normal mode, 100Hz
bmi160_write_reg(0x42, 0x28); // Gyroscope normal mode, 100Hz
// Read data from BMI160 and save to SD card
while (1) {
uint8_t buffer[BUFFER_SIZE];
size_t buffer_size = 0;
uint8_t data[6];
bmi160_read_reg(BMI160_REG_ACCD_X_LSB, &data[0]);
bmi160_read_reg(BMI160_REG_ACCD_X_MSB, &data[1]);
bmi160_read_reg(BMI160_REG_ACCD_Y_LSB, &data[2]);
bmi160_read_reg(BMI160_REG_ACCD_Y_MSB, &data[3]);
bmi160_read_reg(BMI160_REG_ACCD_Z_LSB, &data[4]);
bmi160_read_reg(BMI160_REG_ACCD_Z_MSB, &data[5]);
buffer_size = sprintf((char *) buffer, "%d,%d,%d,%d,%d,%d\n", (int16_t) (data[1] << 8 | data[0]), (int16_t) (data[3] << 8 | data[2]), (int16_t) (data[5] << 8 | data[4]), 0, 0, 0);
sdmmc_card_write("/sdcard/acc.txt", buffer, buffer_size);
bmi160_read_reg(BMI160_REG_GYRD_X_LSB, &data[0]);
bmi160_read_reg(BMI160_REG_GYRD_X_MSB, &data[1]);
bmi160_read_reg(BMI160_REG_GYRD_Y_LSB, &data[2]);
bmi160_read_reg(BMI160_REG_GYRD_Y_MSB, &data[3]);
bmi160_read_reg(BMI160_REG_GYRD_Z_LSB, &data[4]);
bmi160_read_reg(BMI160_REG_GYRD_Z_MSB, &data[5]);
buffer_size = sprintf((char *) buffer, "%d,%d,%d,%d,%d,%d\n", 0, 0, 0, (int16_t) (data[1] << 8 | data[0]), (int16_t) (data[3] << 8 | data[2]), (int16_t) (data[5] << 8 | data[4]));
sdmmc_card_write("/sdcard/gyr.txt", buffer, buffer_size);
vTaskDelay(10 / portTICK_RATE_MS);
}
}
```
该示例代码通过初始化I2C总线、SD卡和BMI160加速度计陀螺仪,然后在一个while循环中不断读取BMI160的数据,并将其存储至SD卡中。其中,BMI160的读写操作使用了ESP32的I2C API,而SD卡的读写操作使用了标准的C文件操作API。注意,在使用SD卡前,需要将其格式化并挂载到ESP32的文件系统中。
阅读全文