开发平台
- Board:野火RT1052-MINI
- IDE:Keil 5.28
再来说说I2C
I2C是由 Phiilps提出的,目前被广泛应用在系统内多个IC间的通讯。I2C是一个能够支持多个设备的总线,包含一条双向串行数据线SDA,一条串行时钟线SCL。每个连接到总线的设备都有一个独立的地址,主机可以通过该地址来访问不同设备。主机通过SDA线发送设备地址(SLAVE_ADDRESS)查找从机,SLAVE_ADDRESS可以是7位或10位,紧跟着SLAVE_ADDRESS的一个数据位用来表示数据传输方向,即第8位或11位。为0时表示写数据,为1时表示读数据。
相关时序:
什么是LPI2C
em…LPI2C是啥呢?I2C倒是经常听经常用,那LPI2C又是什么鬼?翻译一下就是LPI2C(Low Power I2C),直译就是低功耗I2C。所以,其实它是能兼容标准I2C协议的。RT1052 的 I2C 外设可用作通讯的主机及从机,支持标准模式 100Kbit/s、快速模式
400Kbit/s、高速模式 3.4Mbit/s 以及超高速模式 5Mbit/s 的传输速率,支持 7 位、10 位设备地址,支持 DMA 数据传输,并具有数据校验功能。
LPI2C的初始化代码
void I2C_Init(void)
{
lpi2c_master_config_t masterConfig;
/*
* @时钟配置
* LPI2C1的时钟来源于,选择0:来自PLL3,选择1:来自osc_clk
* 由于这里选择0---来自PLL3(480MHz),所以分频系数选择5,即(6-1)
*/
CLOCK_SetMux(kCLOCK_Lpi2cMux, 0);
CLOCK_SetDiv(kCLOCK_Lpi2cDiv,(6-1));
/* IO复用配置 */
IOMUXC_SetPinMux(I2C_SCL_MUX,1U);
IOMUXC_SetPinMux(I2C_SDA_MUX,1U);
/* IO PAD配置 */
IOMUXC_SetPinConfig(I2C_SCL_MUX,I2C_PAD_CONFIG_DATA);
IOMUXC_SetPinConfig(I2C_SDA_MUX,I2C_PAD_CONFIG_DATA);
/* 获取默认配置 */
LPI2C_MasterGetDefaultConfig(&masterConfig);
/* 配置LPI2C速度400k */
masterConfig.baudRate_Hz = 400000;
LPI2C_MasterInit(I2Cx, &masterConfig, I2C_CLOCK);
}
I2C通讯接口
bool I2C_WriteByte(uint8_t SalveAddr,uint8_t RegAddr,uint8_t *DateByte)
{
lpi2c_master_transfer_t transfer;
status_t err_flag;
/*
* @data :要发送的数据
* @datasize :发送的数据个数
* @direction :读写模式选择
* @flags :传输失败的标志位
* @slaveAaddress:从机地址
* @subaddress :寄存器/内存地址
* @subaddressSize:地址寄存器大小
*/
transfer.data = DateByte;
transfer.dataSize = 1;
transfer.direction = kLPI2C_Write;
transfer.flags = kLPI2C_TransferDefaultFlag;
transfer.slaveAddress =(SalveAddr>>1);
transfer.subaddress = RegAddr;
transfer.subaddressSize = 0x01;
err_flag = LPI2C_MasterTransferBlocking(LPI2C1,&transfer);
if(err_flag != kStatus_Success) return false;
return true;
}
bool I2C_ReadByte(uint8_t SalveAddr,uint8_t RegAddr,uint8_t *DateByte)
{
lpi2c_master_transfer_t transfer;
status_t err_flag;
/*
* @data :发送、接受的数据
* @datasize :发送的数据个数
* @direction :读写模式选择
* @flags :传输失败的标志位
* @slaveAaddress:从机地址
* @subaddress :寄存器/内存地址
* @subaddressSize:地址寄存器大小
*/
transfer.data = DateByte;
transfer.dataSize = 1;
transfer.direction = kLPI2C_Read;
transfer.flags = kLPI2C_TransferDefaultFlag;
transfer.slaveAddress =(SalveAddr>>1);
transfer.subaddress = RegAddr;
transfer.subaddressSize = 0x01;
err_flag = LPI2C_MasterTransferBlocking(LPI2C1,&transfer);
if(err_flag != kStatus_Success) return false;
return true;
}
bool I2C_WriteBuffer(uint8_t SalveAddr,uint8_t RegAddr,uint8_t *DateByte,uint32_t DataNum)
{
lpi2c_master_transfer_t transfer;
status_t err_flag;
/*
* @data :要发送的数据
* @datasize :发送的数据个数
* @direction :读写模式选择
* @flags :传输失败的标志位
* @slaveAaddress:从机地址
* @subaddress :寄存器/内存地址
* @subaddressSize:地址寄存器大小
*/
transfer.data = DateByte;
transfer.dataSize = DataNum;
transfer.direction = kLPI2C_Write;
transfer.flags = kLPI2C_TransferDefaultFlag;
transfer.slaveAddress =(SalveAddr>>1);
transfer.subaddress = RegAddr;
transfer.subaddressSize = 0x01;
err_flag = LPI2C_MasterTransferBlocking(LPI2C1,&transfer);
if(err_flag != kStatus_Success) return false;
return true;
}
bool I2C_ReadBuffer(uint8_t SalveAddr,uint8_t RegAddr,uint8_t *DateByte,uint32_t DataNum)
{
lpi2c_master_transfer_t transfer;
status_t err_flag;
/*
* @data :发送、接受的数据
* @datasize :发送的数据个数
* @direction :读写模式选择
* @flags :传输失败的标志位
* @slaveAaddress:从机地址
* @subaddress :寄存器/内存地址
* @subaddressSize:地址寄存器大小
*/
transfer.data = DateByte;
transfer.dataSize = DataNum;
transfer.direction = kLPI2C_Read;
transfer.flags = kLPI2C_TransferDefaultFlag;
transfer.slaveAddress =(SalveAddr>>1);
transfer.subaddress = RegAddr;
transfer.subaddressSize = 0x01;
err_flag = LPI2C_MasterTransferBlocking(LPI2C1,&transfer);
if(err_flag != kStatus_Success) return false;
return true;
}