【FR801xH】富芮坤FR801xH之I2C

00. 目录

01. FR801xH概述

在这里插入图片描述

FR801xH 系列芯片是面向SOC(片上系统),易于快速开发的低功耗蓝牙芯片。基于 Freqchip 的蓝牙智能固件和协议栈的支持,完全兼容蓝牙 V5.3(LE 模式)协议。同时用户可以基于芯片内置的 ARM CorteM3 嵌入式 32 位高性能单片机开发各种应用程序。

蓝牙智能固件包括 L2CAP 服务层协议、安全管理器 (SM)、属性协议(ATT)、通用属性配置文件 (GATT)和通用访问配置文件(GAP)。此外,还 支持应用程序配置文件,例如接近度、健康温度计、 心率、血压、血糖、人机界面设备(HID)和 SDK (包括驱动程序、OS-API 等)。SDK 还集成了用于网络应用程序的 SIG Mesh 协议。

采用 Freqchip 的创新技术,将 PMU(锂电池充电 器+LDO)、带 XIP 模式的 QSPI FLASH ROM、 I2C、UART、GPIO、ADC、PWM 集成在一块芯片中,为客户提供:

  • 竞争力的功耗
  • 稳定的蓝牙连接
  • 极低的 BOM 成本

02. FR801xH功能框图

在这里插入图片描述

03. I2C相关类型

位于 components\driver\include\driver_iic.h

3.1 iic_channel_t

enum iic_channel_t
{
    IIC_CHANNEL_0,
    IIC_CHANNEL_1,
    IIC_CHANNEL_MAX,
};

3.2 enum_iic_int_indx_t

typedef enum
{
	 INT_TRANS_DONE                   = 0x00000001,
	 INT_ARB_FAIL                     = 0x00000002,
	 INT_NO_ACK                       = 0x00000004,
	 INT_MS_DATA_REQ                  = 0x00000008,
	 INT_SLV_DATA_REQ                 = 0x00000010,
	 INT_RX_FFF                       = 0x00000020,
	 INT_RX_FFNE                      = 0x00000040,
	 INT_MS_TX_FFNF                   = 0x00000080,
	 INT_SW_RST                       = 0x00000100,
	 INT_ADD_TYPE_SEL                 = 0x00000200,
	 INT_SLV_TX_FFNF                  = 0x00000400,
}enum_iic_int_indx_t;

04. I2C相关API

4.1 iic_init

/*********************************************************************
 * @fn      iic_init
 *
 * @brief   Initialize iic instance.
 *
 * @param   channel     - IIC_CHANNEL_0 or IIC_CHANNEL_1.
 *          speed       - SCL speed when working as master, N * 1000
 *          slave_addr  - local address when working as slave
 *
 * @return  None.
 */
void iic_init(enum iic_channel_t channel, uint16_t speed, uint16_t slave_addr);
功能:
	初始化 IIC 模块,默认配置为为 7 位地址模式
参数:
	channel 初始化对象,可选 IIC_CHANNEL_0、IIC_CHANNEL_1
	speed 配置总线时钟速率为 speed*1000
	slave_addr 当本机工作在从机模式时的从机地址
返回值:
	None

4.2 iic_write_byte

/*********************************************************************
 * @fn      iic_write_byte
 *
 * @brief   write one byte to slave.
 *
 * @param   channel     - IIC_CHANNEL_0 or IIC_CHANNEL_1.
 *          slave_addr  - slave address
 *          reg_addr    - which register to be writen
 *          data        - data to be writen
 *
 * @return  None.
 */
uint8_t iic_write_byte(enum iic_channel_t channel, uint8_t slave_addr, uint8_t reg_addr, uint8_t data);
功能:
	将一个字节数据发送给从机的特定地址
参数:
	channel  -  操作对象
	slave_addr  -  从机地址
	reg_addr  -  操作的从机寄存器地址
	data  -  待写入的数据
返回值:
	None

4.3 iic_write_bytes

/*********************************************************************
 * @fn      iic_write_bytes
 *
 * @brief   write multi-bytes to slave.
 *
 * @param   channel     - IIC_CHANNEL_0 or IIC_CHANNEL_1.
 *          slave_addr  - slave address
 *          reg_addr    - which register to be writen
 *          buffer      - pointer to data buffer
 *          length      - how many bytes to be written
 *
 * @return  None.
 */
uint8_t iic_write_bytes(enum iic_channel_t channel, uint8_t slave_addr, uint8_t reg_addr, uint8_t *buffer, uint16_t length);
功能:
	将多个字节数据发送给从机的特定地址
参数:
	channel  -  操作对象
	slave_addr  -  从机地址
	reg_addr  -  操作的从机寄存器起始地址
	buffer  -  待写入的数据
	length  -  待写入的数据长度
返回值:
	true:写入成功;false:写入失败

4.4 iic_read_byte

/*********************************************************************
 * @fn      iic_read_byte
 *
 * @brief   read one byte frome slave.
 *
 * @param   channel     - IIC_CHANNEL_0 or IIC_CHANNEL_1.
 *          slave_addr  - slave address
 *          reg_addr    - which register to be written
 *          buffer      - store data to buffer
 *
 * @return  None.
 */
uint8_t iic_read_byte(enum iic_channel_t channel, uint8_t slave_addr, uint8_t reg_addr, uint8_t *buffer);
功能:
	从从机的特定地址读取一个字节数据
参数:
	channel  -  操作对象
	slave_addr  -  从机地址
	reg_addr  -  操作的从机寄存器地址
	buffer  -  读取数据的保存地址
返回值:
	true:读取成功;false:读取失败

4.5 iic_read_bytes

/*********************************************************************
 * @fn      iic_read_bytes
 *
 * @brief   read multi-bytes frome slave.
 *
 * @param   channel     - IIC_CHANNEL_0 or IIC_CHANNEL_1.
 *          slave_addr  - slave address
 *          reg_addr    - which register to be written
 *          buffer      - buffer pointer to be written
 *          length      - how many bytes to be read
 *
 * @return  None.
 */
uint8_t iic_read_bytes(enum iic_channel_t channel, uint8_t slave_addr, uint8_t reg_addr, uint8_t *buffer, uint16_t length);
功能:
	从从机的特定地址读取多个字节数据
参数:
	channel  -  操作对象
	slave_addr  -  从机地址
	reg_addr  -  操作的从机寄存器起始地址
	buffer  -  读取数据的保存地址
	length  -  待读取的数据长度
返回值:
	true:读取成功;false:读取失败


05. I2C程序示例

mpu6050.h

#ifndef __MPU6050_H__

#define __MPU6050_H__

#include "mpu6050.h"
#include "driver_iic.h"

//0x68 默认左移1位
#define MPU6050_ADDRESS		    0xD0

#define	MPU6050_SMPLRT_DIV		0x19
#define	MPU6050_CONFIG			0x1A
#define	MPU6050_GYRO_CONFIG		0x1B
#define	MPU6050_ACCEL_CONFIG	0x1C

#define	MPU6050_ACCEL_XOUT_H	0x3B
#define	MPU6050_ACCEL_XOUT_L	0x3C
#define	MPU6050_ACCEL_YOUT_H	0x3D
#define	MPU6050_ACCEL_YOUT_L	0x3E
#define	MPU6050_ACCEL_ZOUT_H	0x3F
#define	MPU6050_ACCEL_ZOUT_L	0x40
#define	MPU6050_TEMP_OUT_H		0x41
#define	MPU6050_TEMP_OUT_L		0x42
#define	MPU6050_GYRO_XOUT_H		0x43
#define	MPU6050_GYRO_XOUT_L		0x44
#define	MPU6050_GYRO_YOUT_H		0x45
#define	MPU6050_GYRO_YOUT_L		0x46
#define	MPU6050_GYRO_ZOUT_H		0x47
#define	MPU6050_GYRO_ZOUT_L		0x48

#define	MPU6050_PWR_MGMT_1		0x6B
#define	MPU6050_PWR_MGMT_2		0x6C
#define	MPU6050_WHO_AM_I		0x75

void MPU6050_WriteReg(uint8_t regAddr, uint8_t data);
uint8_t MPU6050_ReadReg(uint8_t regAddr);
void MPU6050_init(void);
uint8_t MPU6050_getId(void);
void MPU6050_getData(int16_t *AccX, int16_t *AccY, int16_t *AccZ, 
						int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ);

#endif /*__MPU6050_H__*/

mpu6050.c


#include "mpu6050.h"
#include "sys_utils.h"
#include "driver_system.h"

void MPU6050_WriteReg(uint8_t regAddr, uint8_t data)
{

    iic_write_byte(IIC_CHANNEL_1, MPU6050_ADDRESS, regAddr, data);
}

uint8_t MPU6050_ReadReg(uint8_t regAddr)
{
    uint8_t data = 0;

    iic_read_byte(IIC_CHANNEL_1, MPU6050_ADDRESS, regAddr, &data);

    return data;
}

void MPU6050_init(void)
{
    // 设置引脚复用功能 SCL-- PA6  SDA -- PA7
    system_set_port_mux(GPIO_PORT_A, GPIO_BIT_6, PORTA6_FUNC_I2C1_CLK); 
    system_set_port_mux(GPIO_PORT_A, GPIO_BIT_7, PORTA7_FUNC_I2C1_DAT); 
    system_set_port_pull((GPIO_PA6 | GPIO_PA7), true);


    iic_init(IIC_CHANNEL_1, 1000, MPU6050_ADDRESS);
    co_delay_100us(1);
    
    // MPU6050初始化
    MPU6050_WriteReg(MPU6050_PWR_MGMT_1, 0x01);
    MPU6050_WriteReg(MPU6050_PWR_MGMT_2, 0x00);
    MPU6050_WriteReg(MPU6050_SMPLRT_DIV, 0x09);
    MPU6050_WriteReg(MPU6050_CONFIG, 0x06);
    MPU6050_WriteReg(MPU6050_GYRO_CONFIG, 0x18);
    MPU6050_WriteReg(MPU6050_ACCEL_CONFIG, 0x18);
}

uint8_t MPU6050_getId(void)
{
    return MPU6050_ReadReg(MPU6050_WHO_AM_I);
}

void MPU6050_getData(int16_t *AccX, int16_t *AccY, int16_t *AccZ,
                     int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ)
{
    uint8_t DataH, DataL;

    DataH = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_H);
    DataL = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_L);
    *AccX = (DataH << 8) | DataL;

    DataH = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_H);
    DataL = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_L);
    *AccY = (DataH << 8) | DataL;

    DataH = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_H);
    DataL = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_L);
    *AccZ = (DataH << 8) | DataL;

    DataH = MPU6050_ReadReg(MPU6050_GYRO_XOUT_H);
    DataL = MPU6050_ReadReg(MPU6050_GYRO_XOUT_L);
    *GyroX = (DataH << 8) | DataL;

    DataH = MPU6050_ReadReg(MPU6050_GYRO_YOUT_H);
    DataL = MPU6050_ReadReg(MPU6050_GYRO_YOUT_L);
    *GyroY = (DataH << 8) | DataL;

    DataH = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_H);
    DataL = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_L);
    *GyroZ = (DataH << 8) | DataL;
}

demo.c


#include "sys_utils.h"
#include "driver_exti.h"
#include "mpu6050.h"

void peripheral_demo(void)
{
    int16_t accx, accy, accz;
    int16_t gyrox, gyroy, gyroz;

    co_printf("MPU6050 Demo....\r\n");

    MPU6050_init();

    while(1)
    {
        co_printf("chipid: %x\r\n", MPU6050_getId());

        MPU6050_getData(&accx, &accy, &accz, &gyrox, &gyroy, &gyroz);

        co_printf("x: %d y: %d z: %d gx: %d gy: %d gz: %d\r\n", accx, accy, accz, gyrox, gyroy, gyroz);

        co_delay_100us(10000);
    }
}

程序运行结果

freqchipuser_entry_after_ble_init
MPU6050 Demo....
chipid: 68
x: -25 y: -1528 z: -1376 gx: -181 gy: 40 gz: -13
chipid: 68
x: -48 y: -1532 z: -1357 gx: -20 gy: -23 gz: 23
chipid: 68
x: -49 y: -1532 z: -1356 gx: -25 gy: -22 gz: 24
chipid: 68
x: -48 y: -1534 z: -1358 gx: -25 gy: -20 gz: 7
chipid: 68
x: -51 y: -1533 z: -1356 gx: -26 gy: -23 gz: 30
chipid: 68
x: -52 y: -1531 z: -1353 gx: -26 gy: -24 gz: 41

06. 附录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沧海一笑-dj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值