102集成了一个I2C控制器,可以作为主机或者从机工作,作为主机时,设备可以通过轮询或者中断方式工作; 作为从机时,设备通过中断方式工作。
102上的I2C控制器支持standard-mode(100Kbit/s)和fast-mode(400Kbit/s)两种模式,不支持HS-mode(3.4Mbit/s)模式。
I2C控制器的基地址是0xbfe90000。
I2C控制器的初始化流程:
typedef struct
{
uint8_t I2C_modeEN;
uint32_t I2C_ClockSpeed;
uint8_t I2C_Mode;
uint8_t I2C_OwnAddress1;
uint8_t I2C_BuslockCheckEn;
uint8_t I2C_SlvAutoresetEn;
}I2C_InitTypeDef;
void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct)
{
uint32_t tmp = 0;
uint32_t pclk1 = SystemFreq;
I2Cx->CTRL = 0x20;
tmp = pclk1 / I2C_InitStruct->I2C_ClockSpeed;
tmp = (tmp >> 2) -1;
I2Cx->PRERL = tmp;
I2Cx->PRERH = tmp >> 8;
I2Cx->CTRL = (I2C_InitStruct->I2C_modeEN)|(I2C_InitStruct->I2C_Mode)|(I2C_InitStruct->I2C_BuslockCheckEn)|(I2C_InitStruct->I2C_SlvAutoresetEn) ;
if (I2C_InitStruct->I2C_BuslockCheckEn){
I2Cx->CR_SR = 0x04;
}
I2Cx->SADDR = I2C_InitStruct->I2C_OwnAddress1;
I2C_wait(I2C);
}
如定时器的控制一样,初始化I2C_InitTypeDef和I2C_TypeDef以保存I2C总线配置和各寄存器状态,再调用I2C_Init
接口进行初始化,完成后即可正常使用I2C总线。
给出再封装的读写工具函数,如果不了解I2C总线的通讯方式,请参考:I2C总线通讯协议。
void myI2C_write(unsigned char dev_addr, unsigned char reg_addr, unsigned char w_data)
{
I2C_GenerateSTART(I2C,ENABLE);
I2C_wait(I2C);
I2C_Send7bitAddress(I2C, dev_addr & 0xff, I2C_Direction_Transmitter);
I2C_wait(I2C);
if(I2C->CR_SR & 0x80)
{
printf("I2C send 7 bit address failed\n");
goto exit_point;
}
I2C_SendData(I2C, reg_addr);
I2C_wait(I2C);
if(I2C->CR_SR & 0x80)
{
printf("I2C send reg address failed\n");
goto exit_point;
}
I2C_SendData(I2C, w_data);
I2C_wait(I2C);
if(I2C->CR_SR & 0x80)
{
printf("I2C send data failed\n");
goto exit_point;
}
I2C_GenerateSTOP(I2C,ENABLE);
I2C_wait(I2C);
exit_point:
return;
}
unsigned char myI2C_read(unsigned char dev_addr, unsigned char reg_addr)
{
unsigned char ret = 0xff;
I2C_GenerateSTART(I2C,ENABLE);
I2C_wait(I2C);
I2C_Send7bitAddress(I2C, dev_addr & 0xff, I2C_Direction_Transmitter);
I2C_wait(I2C);
if(I2C->CR_SR & 0x80)
{
printf("I2C send 7 bit address failed\n");
goto exit_point;
}
I2C_SendData(I2C,reg_addr);
I2C_wait(I2C);
if(I2C->CR_SR & 0x80)
{
printf("I2C send reg address failed\n");
goto exit_point;
}
I2C_Send7bitAddress(I2C, dev_addr & 0xff, I2C_Direction_Receiver);
I2C_wait(I2C);
if(I2C->CR_SR & 0x80)
{
printf("I2C send 7 bit address failed\n");
goto exit_point;
}
I2C_ReceiveData(I2C,I2C_NACK,I2C_STOP);
I2C_wait(I2C);
ret = (uint8_t)I2C->DR;
exit_point:
return ret;
}
以上给出基于I2C协议的对某一寄存器读写接口,也可根据此接口编写多写多读功能。