IIC - aman396271/Flagchip_Study GitHub Wiki
概要
三种速度模式
1.Standard Mode
100kbit/s,不能向上兼容
2.Fast Mode
400kbit/s,可向下兼容,0-100kbit/s
3.High-Speed Mode
最高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操作流程
2.Slave Mode
错误机制
时钟延长
时序要求
代码
初始化
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;
}