解释代码void I2C_reg_handle(uint8_t reg, uint8_t data) { if (reg < REG_LED0 || reg >= REG_NO_MAX) return; system_st.i2c_registers[reg] = data; if (reg == REG_WDI) system_st.emStateTmp = data; if (reg == REG_LED) { if (data) GPIO_WriteHigh(GPIOD, GPIO_PIN_4); else GPIO_WriteLow(GPIOD, GPIO_PIN_4); } if (reg == REG_SLEEP_START) { system_st.sleep_time_start[system_st.sleep_time_idx++] = data; if (system_st.sleep_time_idx >= 5) { system_st.sleep_time_idx = 0; system_st.sleep_time_start_cnt = system_st.sleep_time_start[0]*16*16*16*16 + system_st.sleep_time_start[1]*16*16*16 + system_st.sleep_time_start[2]*16*16 + system_st.sleep_time_start[3]*16 + system_st.sleep_time_start[4]; system_st.sleep_time_start_cnt *= 500; /* convert to jiffies counter */ main_st.sleep_time_start_jiffies = main_st.sys_jiffies; } } else if (reg == REG_SLEEP_STOP) { system_st.sleep_time_stop[system_st.sleep_time_idx++] = data; if (system_st.sleep_time_idx >= 5) { system_st.sleep_time_idx = 0; system_st.sleep_time_stop_cnt = system_st.sleep_time_stop[0]*16*16*16*16 + system_st.sleep_time_stop[1]*16*16*16 + system_st.sleep_time_stop[2]*16*16 + system_st.sleep_time_stop[3]*16 + system_st.sleep_time_stop[4]; system_st.sleep_time_stop_cnt *= 500; /* convert to jiffies counter */ main_st.sleep_time_stop_jiffies = main_st.sys_jiffies; } } }
时间: 2024-01-18 10:04:10 浏览: 28
这段代码是一个函数定义,函数名为 `I2C_reg_handle` ,接受两个参数 `reg` 和 `data` ,都是 uint8_t 类型。函数的作用是处理 I2C 寄存器的值。
首先,代码通过判断 `reg` 的取值范围,如果不在 `REG_LED0` 和 `REG_NO_MAX` 之间,则直接返回,不做任何处理。
然后,代码将 `data` 的值赋给 `system_st.i2c_registers[reg]` ,即将 I2C 寄存器的值更新为 `data` 。
接下来,代码根据不同的 `reg` 值做了一些特定的处理:
- 如果 `reg` 的值等于 `REG_WDI` ,则将 `data` 的值赋给 `system_st.emStateTmp` 。
- 如果 `reg` 的值等于 `REG_LED` ,则根据 `data` 的值来控制一个 LED 的状态。如果 `data` 为真,则将 GPIOD 的第 4 个引脚置高,否则将其置低。
- 如果 `reg` 的值等于 `REG_SLEEP_START` ,则将 `data` 的值存入 `system_st.sleep_time_start` 数组,并根据数组中的值计算出睡眠时间的计数器,并记录下当前的时间戳。
- 如果 `reg` 的值等于 `REG_SLEEP_STOP` ,则将 `data` 的值存入 `system_st.sleep_time_stop` 数组,并根据数组中的值计算出睡眠结束时间的计数器,并记录下当前的时间戳。
这段代码的作用是根据传入的寄存器和数据值,更新相应的状态和执行相应的操作。
相关问题
stm32如何使用HAL库实现硬件i2c
使用HAL库实现硬件I2C,需要按照以下步骤:
1. 初始化I2C总线,包括I2C的GPIO管脚初始化和I2C外设初始化。
2. 配置I2C的工作模式,包括传输速率、地址长度等。
3. 发送I2C起始信号。
4. 发送I2C设备地址和读写标志。
5. 写入数据或读取数据。
6. 发送I2C停止信号。
以下是一个使用HAL库实现I2C读写的例程:
```c
#include "stm32f4xx_hal.h"
I2C_HandleTypeDef hi2c1;
void MX_I2C1_Init(void)
{
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 100000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
}
}
void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(i2cHandle->Instance==I2C1)
{
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_I2C1_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
}
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle)
{
if(i2cHandle->Instance==I2C1)
{
__HAL_RCC_I2C1_FORCE_RESET();
__HAL_RCC_I2C1_RELEASE_RESET();
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);
}
}
void I2C_Read(uint8_t address, uint8_t reg, uint8_t* data, uint16_t size)
{
HAL_I2C_Mem_Read(&hi2c1, address, reg, I2C_MEMADD_SIZE_8BIT, data, size, 100);
}
void I2C_Write(uint8_t address, uint8_t reg, uint8_t* data, uint16_t size)
{
HAL_I2C_Mem_Write(&hi2c1, address, reg, I2C_MEMADD_SIZE_8BIT, data, size, 100);
}
```
上述代码中,MX_I2C1_Init()函数进行I2C总线的初始化配置。I2C_Read()和I2C_Write()函数分别实现了I2C的读取和写入操作。具体实现可参考HAL库的API文档。
ESP32-IDF SDMMC读写BMI160保存陀螺仪加速度数据代码
以下是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的文件系统中。