IIC - aman396271/Flagchip_Study GitHub Wiki

概要

三种速度模式

1.Standard Mode image 100kbit/s,不能向上兼容 2.Fast Mode image 400kbit/s,可向下兼容,0-100kbit/s 3.High-Speed Mode image 最高3.4Mbit/s,向下兼容,但仅在Slave Mode使用

##主从模式 1.Master Mode 多主机环境: 所有 master 会持续监控 SDA 和 SCL,如果检测到 SDA 为低但预期为高,则认为被仲裁失败,立即停止传输。 同步 SCL: 所有设备会通过有线与(wired-AND)连接生成同步 SCL,其低电平由最长 LOW 时间决定,高电平由最短 HIGH 时间决定 Start: SDA 从高变低,SCL 保持高。 Stop: SDA 从低变高,SCL 保持高。 Repeated Start: 不需要 STOP 就可以再次发起 START(非常重要,用于多字节读取) 若开启 MCFGR1[AUTOSTOP],数据发完或收完后会自动发送 STOP; 若发送 FIFO 为空但没设置 STOP,FCIIC 会自动补发 STOP。 Master Mode操作流程 image

2.Slave Mode 错误机制 image 时钟延长 image

时序要求

image

代码

初始化

FCIIC_MasterHandleType g_tFciicMasterHandle;

void Bsp_IIC_Init(void)
{
	FCIIC_MasterConfigType masterConfig;
    FCIIC_MasterGetDefaultConfig(&masterConfig);
    FCIIC_MasterInitHandle(&g_tFciicMasterHandle,FCIIC_INSTANCE_0);
    g_tFciicMasterHandle.tSettings.pCallback=FCIIC_CallBack;
    g_tFciicMasterHandle.tSettings.pErrorCallback=FCIIC_Error_CallBack;
    FCIIC_MasterInit(&g_tFciicMasterHandle, &masterConfig, PCC_GetPccFunctionClock(PCC_CLK_FCIIC0));
}

在其中,FCIIC_MasterGetDefaultConfig

        pMasterConfig->bEnableMaster          = true;//使能主模式
        pMasterConfig->bDebugEnable           = false;//关闭Debug模式
        pMasterConfig->ePinConfig             = FCIIC_OPENDRAIN;//引脚设置为开漏
        pMasterConfig->u32BaudRate            = 100000U;//波特率为100k
        pMasterConfig->u32BusIdleTimeout      = 0U; /* Set to 0 to disable the function */
        pMasterConfig->u32PinLowTimeout       = 0U; /* Set to 0 to disable the function */
        pMasterConfig->u8SdaGlitchFilterWidth = 0U; /* Set to 0 to disable the function */
        pMasterConfig->u8SclGlitchFilterWidth = 0U; /* Set to 0 to disable the function */

FCIIC_MasterInitHandle

        pFciicMasterHandle->eInstance = eInstance;//实例
        pFciicMasterHandle->tStatus.bUsed = false;//
        pFciicMasterHandle->tStatus.eDirection = FCIIC_DIRNOCONFIG;
        for (i = 0; i < FCIIC_MASTER_CMD_SIZE; i++)
        {
            pFciicMasterHandle->tStatus.u8Cmd[i] = FCIIC_TX_CMD_STOP;
            pFciicMasterHandle->tStatus.u16DmaCmdData[i] = 0;
            pFciicMasterHandle->tStatus.u8CmdData[i] = 0;
        }
        pFciicMasterHandle->tStatus.u8CmdSize = 0;
        pFciicMasterHandle->tStatus.eChannelStatus = FCIIC_CH_IDLE;
        pFciicMasterHandle->tStatus.u8CmdOffset = 0;
        pFciicMasterHandle->tStatus.u16DataSize = 0;
        pFciicMasterHandle->tStatus.u16DataOffset = 0;
        pFciicMasterHandle->tSettings.pCallback = NULL;
        pFciicMasterHandle->tSettings.pErrorCallback = NULL;
        pFciicMasterHandle->tSettings.pUserData = NULL;
        pFciicMasterHandle->tSettings.pData = NULL;
        pFciicMasterHandle->tStatus.u8DmaCmdSize = 0;
        pFciicMasterHandle->tStatus.u8DmaCmdOffset = 0;
        pFciicMasterHandle->tSettings.pFciicTxDmaConfig = NULL;
        pFciicMasterHandle->tSettings.pFciicRxDmaConfig = NULL;

IIC写

void FCIIC_Write(FCIIC_MasterHandleType *pFciicMasterHandle,uint8_t u8OriDevAddr, uint32_t subAddr, uint8_t subAddrLen, uint8_t *pData, uint16_t u16DataLen)
{
	FCIIC_MasterTransferType transfer;

	transfer.u8SlaveAddress = u8OriDevAddr;
	transfer.eDirection		= FCIIC_WRITE;
	transfer.subaddressSize	= subAddr;
	transfer.subaddressSize	= subAddrLen;
	transfer.pData			= pData;
	transfer.u16DataSize	= u16DataLen;
	FCIIC_MasterTransferBlocking(pFciicMasterHandle,transfer);
}

驱动AS5600读取角度

IO口初始化

	/* PE0  IIC SDA */
	g_tPortHandle.eInstance = PORT_E;
	tInitStruct.u32PortPins = PORT_PIN_0;
	tInitStruct.uPortPinMux.u32PortPinMode = PORTE_0_FCIIC1_SDA;
	tInitStruct.bPullEn = false;
	tInitStruct.ePortGpioLevel = PORT_GPIO_HIGH;
	PORT_InitPins(&g_tPortHandle, &tInitStruct);

	/* PD19 IIC SCL */
	g_tPortHandle.eInstance = PORT_D;
	tInitStruct.u32PortPins = PORT_PIN_19;
	tInitStruct.uPortPinMux.u32PortPinMode = PORTD_19_FCIIC1_SCL;
	tInitStruct.bPullEn = false;
	tInitStruct.ePortGpioLevel = PORT_GPIO_HIGH;
	PORT_InitPins(&g_tPortHandle, &tInitStruct);

IIC.c

#include "IIC.h"

static void FCIIC_CallBack(FCIIC_MasterHandleType *pFciicMasterHandle, FCIIC_StatusType Status);
static void FCIIC_Error_CallBack(FCIIC_MasterHandleType *pFciicMasterHandle, FCIIC_StatusType Status);

FCIIC_MasterHandleType g_tFciicMasterHandle;

void Bsp_IIC_Init(void)
{
	FCIIC_MasterConfigType masterConfig;
    FCIIC_MasterGetDefaultConfig(&masterConfig);
    FCIIC_MasterInitHandle(&g_tFciicMasterHandle,FCIIC_INSTANCE_1);
    g_tFciicMasterHandle.tSettings.pCallback=FCIIC_CallBack;
    g_tFciicMasterHandle.tSettings.pErrorCallback=FCIIC_Error_CallBack;
    FCIIC_MasterInit(&g_tFciicMasterHandle, &masterConfig, PCC_GetPccFunctionClock(PCC_CLK_FCIIC1));
}

void FCIIC_Write(FCIIC_MasterHandleType *pFciicMasterHandle,uint8_t u8OriDevAddr,
					uint32_t subAddr, uint8_t subAddrLen, uint8_t *pData, uint16_t u16DataLen)
{
	FCIIC_MasterTransferType transfer;

	transfer.u8SlaveAddress = u8OriDevAddr;
	transfer.eDirection		= FCIIC_WRITE;
	transfer.subaddressSize	= subAddr;
	transfer.subaddressSize	= subAddrLen;
	transfer.pData			= pData;
	transfer.u16DataSize	= u16DataLen;
	FCIIC_MasterTransferBlocking(pFciicMasterHandle,&transfer);
}

void FCIIC_WriteAndRead(FCIIC_MasterHandleType *pFciicMasterHandle, uint8_t u8OriDevAddr,
							uint32_t subAddr, uint8_t subAddrLen, uint8_t *pRxData, uint16_t u16RxDataLen)
{
	FCIIC_MasterTransferType transfer;

	transfer.u8SlaveAddress = u8OriDevAddr;
	transfer.eDirection = FCIIC_READ;
	transfer.subaddress = subAddr;
	transfer.subaddressSize = subAddrLen;
	transfer.pData = pRxData;
	transfer.u16DataSize = u16RxDataLen;
	FCIIC_MasterTransferBlocking(pFciicMasterHandle, &transfer);
}

static void FCIIC_CallBack(FCIIC_MasterHandleType *pFciicMasterHandle, FCIIC_StatusType Status)
{
    (void)pFciicMasterHandle;
    (void)Status;
}

static void FCIIC_Error_CallBack(FCIIC_MasterHandleType *pFciicMasterHandle, FCIIC_StatusType Status)
{
    (void)pFciicMasterHandle;
    (void)Status;
}

IIC_AS5600.c

#include "IIC_AS5600.h"
#include "IIC.h"

#define AS5600_ADDR        0x36
#define AS5600_RAW_ANGLE_H 0x0C
#define AS5600_RAW_ANGLE_L 0x0D

extern FCIIC_MasterHandleType g_tFciicMasterHandle;

/*
 * The 7-bit slave address of the AS5600 is 0x36 (0110110 in binary).
 * */
uint16_t AS5600_ReadAngle(void)
{
    uint8_t buffer[2] = {0};

    FCIIC_WriteAndRead(&g_tFciicMasterHandle,
                       AS5600_ADDR,
                       AS5600_RAW_ANGLE_H,
                       1,
                       buffer,
                       2);

    uint16_t angle = ((buffer[0] << 8) | buffer[1]) & 0x0FFF;
    return angle;
}

End