ICM42670陀螺仪可以使用iic驱动,单片机平台使用GD32f305VE。

iic初始化代码如下 .c文件
#include "M_IIC.h"
#include <stdio.h>
#include "systick.h"
/*!
\brief configure the GPIO ports
\param[in] none
\param[out] none
\retval none
*/
void iic_gpio_config(void)
{
/* enable GPIOB clock */
// gpio_pin_remap_config(GPIO_SWJ_SWDPENABLE_REMAP, ENABLE);
rcu_periph_clock_enable(RCU_GPIO_I2C);
// rcu_periph_clock_enable(RCU_AF);
/* connect PB6 to I2C_SCL */
/* connect PB7 to I2C_SDA */
gpio_init(I2C_SCL_PORT, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, I2C_SCL_PIN);
gpio_init(I2C_SDA_PORT, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, I2C_SDA_PIN);
}
/*!
\brief configure the I2C interfaces
\param[in] none
\param[out] none
\retval none
*/
void i2c_config(void)
{
iic_gpio_config();
/* enable I2C clock */
rcu_periph_clock_enable(RCU_I2C);
/* configure I2C clock */
i2c_clock_config(I2CX, I2C_SPEED, I2C_DTCY_2);
/* configure I2C address */
i2c_mode_addr_config(I2CX, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2CX_SLAVE_ADDRESS7);
/* enable I2CX */
i2c_enable(I2CX);
/* enable acknowledge */
i2c_ack_config(I2CX, I2C_ACK_ENABLE);
}
/*!
\brief reset i2c bus
\param[in] none
\param[out] none
\retval none
*/
void i2c_bus_reset()
{
i2c_deinit(I2CX);
/* configure SDA/SCL for GPIO */
GPIO_BC(I2C_SCL_PORT) |= I2C_SCL_PIN;
GPIO_BC(I2C_SDA_PORT) |= I2C_SDA_PIN;
gpio_init(I2C_SCL_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, I2C_SCL_PIN);
gpio_init(I2C_SDA_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, I2C_SDA_PIN);
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
GPIO_BOP(I2C_SCL_PORT) |= I2C_SCL_PIN;
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
GPIO_BOP(I2C_SDA_PORT) |= I2C_SDA_PIN;
/* connect I2C_SCL_PIN to I2C_SCL */
/* connect I2C_SDA_PIN to I2C_SDA */
gpio_init(I2C_SCL_PORT, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, I2C_SCL_PIN);
gpio_init(I2C_SDA_PORT, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, I2C_SDA_PIN);
/* configure the I2CX interface */
/* enable I2C clock */
rcu_periph_clock_enable(RCU_I2C);
/* configure I2C clock */
i2c_clock_config(I2CX, I2C_SPEED, I2C_DTCY_2);
/* configure I2C address */
i2c_mode_addr_config(I2CX, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2CX_SLAVE_ADDRESS7);
/* enable I2CX */
i2c_enable(I2CX);
/* enable acknowledge */
i2c_ack_config(I2CX, I2C_ACK_ENABLE);
}
.h文件
#ifndef _CAN
#define _CAN
#include "gd32f30x.h"
#define I2C_SPEED 400000
#define I2CX_SLAVE_ADDRESS7 0xD0
#define I2C_PAGE_SIZE 8
#define I2CX I2C1
#define RCU_GPIO_I2C RCU_GPIOB
#define RCU_I2C RCU_I2C1
#define I2C_SCL_PORT GPIOB
#define I2C_SDA_PORT GPIOB
#define I2C_SCL_PIN GPIO_PIN_10
#define I2C_SDA_PIN GPIO_PIN_11
/* configure the GPIO ports */
//void gpio_config(void);
/* configure the I2C interfaces */
void i2c_config(void);
/* reset i2c bus */
void i2c_bus_reset(void);
#endif
驱动ICM42670的iic时序如下:

所以开始写ICM42670的驱动
配置的寄存器主要有



配置好量程,频率和低噪声模式就可在寄存器中查到实时的数据,读取数据前首先要读取INT_STATUS_DRDY寄存器
确认数据已经准备好,然后是 .c如下:
#include "ICM42670.h"
#include <stdio.h>
#include "systick.h"
//在iic总线上发送起始位
uint8_t iic_start(void){
uint16_t timeout=0;
while(i2c_flag_get(I2CX, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)) {
timeout++;
}
if(timeout < I2C_TIME_OUT) {
i2c_start_on_bus(I2CX);
return 1;
} else {
return 0;
}
}
//在iic总线上发送从机地址并清除ADDSEND
uint8_t iic_slave_address(uint8_t addr,uint32_t trandirection){
uint16_t timeout=0;
while((!i2c_flag_get(I2CX, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)) {
timeout++;
}
if(timeout < I2C_TIME_OUT) {
i2c_master_addressing(I2CX,addr, trandirection);
timeout=0;
while((!i2c_flag_get(I2CX, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT)) {
timeout++;
}
if(timeout < I2C_TIME_OUT) {
i2c_flag_clear(I2CX, I2C_FLAG_ADDSEND);//根据要求清除ADDSEND位
return 1;
} else {
return 0;
}
} else {
return 0;
}
}
//查询TBE的方式写入数据,适用与前n-2个数据
uint8_t iic_datasendTBE(uint8_t iic_data){
uint16_t timeout=0;
while((! i2c_flag_get(I2CX, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)) {
timeout++;
}
if(timeout < I2C_TIME_OUT) {
i2c_data_transmit(I2CX, iic_data);
return 1;
} else {
return 0;
}
}
//检测TBC发送
uint8_t iic_datasendTBC(uint8_t iic_data){
uint16_t timeout=0;
/* wait until BTC bit is set */
while((!i2c_flag_get(I2CX, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) {
timeout++;
}
if(timeout < I2C_TIME_OUT) {
i2c_data_transmit(I2CX, iic_data);
return 1;
} else return 0;
}
//最后一位数据读取时调用
uint8_t iic_dataread_N_2(uint8_t* p_buffer){
uint16_t timeout=0;
/* wait until BTC bit is set */
// while(!i2c_flag_get(I2CX, I2C_FLAG_BTC));
/* disable acknowledge */
i2c_ack_config(I2CX, I2C_ACK_DISABLE);
/* wait until BTC bit is set */
// while(!i2c_flag_get(I2CX, I2C_FLAG_BTC));
/* send a stop condition to I2C bus */
i2c_stop_on_bus(I2CX);
while(timeout<I2C_TIME_OUT) {
timeout++;
/* wait until RBNE bit is set */
if(i2c_flag_get(I2CX, I2C_FLAG_RBNE)) {
/* read a byte from the EEPROM */
*p_buffer = i2c_data_receive(I2CX);
return 1;
/* point to the next location where the byte read will be saved */
}
}
return 0;
}
//前0-N-2个数据调用
uint8_t iic_dataread_N(uint8_t* p_buffer){
uint16_t timeout=0;
while(timeout<I2C_TIME_OUT) {
timeout++;
/* wait until RBNE bit is set */
if(i2c_flag_get(I2CX, I2C_FLAG_RBNE)) {
/* read a byte from the EEPROM */
*p_buffer = i2c_data_receive(I2CX);
return 1;
/* point to the next location where the byte read will be saved */
}

本文介绍了ICM42670陀螺仪使用iic驱动的实现,单片机平台采用GD32f305VE。给出了iic初始化代码、驱动iic时序,还介绍了配置寄存器、读取数据的方法,以及姿态解算和滤波算法。经测试功能正常,但偏航角因无磁力计矫正数据较差,并提供了参考资料。
最低0.47元/天 解锁文章
910

被折叠的 条评论
为什么被折叠?



