1.IIC初始化
具体时钟设置参考此篇文章:https://blog.csdn.net/u014397533/article/details/46495905
void I2C_Init(void)
{
I2C_CR1 = 0x00; //禁止I2C外设,此句可省略
//CLK_PCKENR1 |= 0x01; //使能IIC外设时钟,可省略,因为上电默认开启所有时钟
I2C_FREQR|= 0x10; //输入时钟频率16M,对应系统时钟频率
I2C_CCRH=0x00;
I2C_CCRL=0x50; //16M / 100K / 2
I2C_TRISER=0x11;//0x10 + 1
//I2C_CR1 = 0x00; //禁止I2C外设
I2C_OARH = 0x40; //七位地址模式
I2C_OARL = 0xa0;//自身地址0xa0
//I2C_start();//发起始位
I2C_CR2 |= 0x04;//应答使能
//I2C_CR2_POS=0;//I2C->CR2&=~(0x08); //POS=0 这一位的设置很关键,它确定I2C主机返回的NACK在当前字节传输后起作用,而从机只有在收到NACK信号后才能释放总线;
I2C_CR1|= 0x01; //开启I2C外设
}
2.Optionbyte选项字节配置
因PB4/PB5默认是AD转换功能,需要配置选项字节,如果未配置会导致卡在Start condition检测,
while(I2C_SBask==0);///检测起始位是否发完
IAR配置方法:
AFR6配置为Active即可
也可将配置文件存下,然后在项目属性里添加该文件,实测不添加也可以
没有其他问题的话就可以通信成功了
void I2C_Start(void)
{
I2C_busy();//测忙
I2C_start();//发起始位
while(I2C_SBask==0);///检测起始位是否发完
}
void I2C_SendDAdr(u8 Add)
{
I2C_writebyte(Add);//数据写入寄存器
while(I2C_addrask==0);//当收到地址的ACK后该位被置’1’。
I2C_busy();//测忙
}
void I2C_SendDat(u8 data)
{
I2C_writebyte(data);
I2C_busy();
while(I2C_TxEask==0);//1:数据寄存器空;
}
u8 I2C_RcvDat(void)
{
u8 i;
while(I2C_RxNeask==0);
abc:
if(I2C_BTF==0x04)
{i=I2C_DR;}
else goto abc;
if(I2C_BTF==0)
{}
else goto abc;
return i;
}
//--------------------------------------------------------------
// Prototype : void Write_24c02(uchar wdata)
// Calls : I2C_Start(), I2C_Stop(),I2C_SendByte()
// Parameters : RegAddr-- target memory address,
// wrdata--- data to be writing
// Description : Write one byte to target memory
//--------------------------------------------------------------
u8 I2C_Write88(u8 regadd,u8 wdata)
{
I2C_Start(); //起始信号
//Delay_5us();
//Delay_5us();
I2C_SendDAdr( SlaveAddress); //发送设备地址+写信号
I2C_SendDat(regadd); //内部寄存器地址,请参考中文pdf22页
I2C_SendDat(wdata); //内部寄存器数据,请参考中文pdf22页
I2C_stop(); //发送停止信号
//Delay_5us();
return 0;
}
//--------------------------------------------------------------
// Prototype : uchar Read_24c02(uchar regadd)
// Calls : I2C_Start(), I2C_Stop(),I2C_SendByte(),I2C_RecvByte(),I2C_SendACK()
// Parameters : RegAddr-- target memory address,
// Return Value : revDAT- received data
// Description : Read one byte from target memory
//--------------------------------------------------------------
u8 I2C_Read88(u8 regadd)
{
u8 revdata;
//CS = 0;
//Delay_5us();
I2C_Start(); //起始信号
I2C_SendDAdr(SlaveAddress); //发送设备地址+写信号
I2C_SendDat(regadd); //发送存储单元地址,从0开始
I2C_Start(); //起始信号
I2C_SendDAdr( SlaveAddress+1); //发送设备地址+读信号
//I2C_NAck();
//I2C_stop(); //停止信号
revdata = I2C_RcvDat(); //读出寄存器数据
//I2C_Ack();
I2C_NAck();//读倒数第二个数据字节之后清除ACK位
I2C_stop(); //读倒数第二个数据字节之后设置STOP/START位
//Delay_5us();
//CS = 1;
return revdata;
}