void Driver_I2CON(void)
{
//开I2C时钟
CLK_PCKENR1 |= SETBIT0;
//I2C模式选择 标准模式
I2C_CCRH &= CLRBIT7;
//设置输入时钟fck 标准模式>1M(配置2M)
I2C_FREQR = 0x02;
//则标准(fsc为通信速率):
//tck=1/fck=0.5us
//CCR=1/(2fsc*tck) = 1000000/2fsc*0.5 = 1000000/fsc
//按速率设置宏定义 配置通信速率 10Kbps
I2C_CCRH = 0;
I2C_CCRL = 100;
//配置上升时间寄存器
I2C_TRISER = 3;
//开启I2C模块
I2C_CR1 |= SETBIT0;
}
/********************************************************************************************************
* Function: Driver_I2CSend
* Object: 硬件I2C发送
* 输入: 从设备地址; 待发送数据的头指针; 待发数据的长;
* 输出: 无
* 备注: 通信中如果出现超时故障 则直接返回 避免长等待
********************************************************************************************************/
void Driver_I2CSend(u8 Address,u8 *DataBuff,u16 DataLen)
{
u8 temp;
u16 time;
//等待总线空闲
time = 500;
while(I2C_SR3&CHSBIT1)
if(!--time)
return;
//发起始条件
I2C_CR2 |= SETBIT0;
//等待发送完毕
time = 500;
while((I2C_SR1&CHSBIT0)==0)
if(!--time)
return;
//短暂延时
_asm("nop");
_asm("nop");
_asm("nop");
temp = I2C_SR1;
//发从地址
I2C_DR = Address;
//等待ACK应答
time = 500;
while((I2C_SR1&CHSBIT1)==0)
if(!--time)
{
//超时无应答 失败
//发停止 退出
I2C_CR2 |= SETBIT1;
return;
}
//短暂延时
_asm("nop");
_asm("nop");
_asm("nop");
temp = I2C_SR1;
//清ADDR标志
temp = I2C_SR3;
//发送数据
for(;DataLen>0;DataLen--,DataBuff++)
{
//等待寄存器为空
time = 500;
while(!(I2C_SR1&CHSBIT7))
if(!--time)
return;
I2C_DR = *DataBuff;
//等待发送完毕
time = 500;
while(!(I2C_SR1&CHSBIT2))
if(!--time)
return;
_asm("nop");
_asm("nop");
_asm("nop");
}
//发停止条件,关闭通信
//清BTF位
temp = I2C_SR1;
temp = I2C_DR;
//发停止
I2C_CR2 |= SETBIT1;
}
/********************************************************************************************************
* Function: Driver_I2CRecv
* Object: 硬件I2C接收
* 输入: 从设备地址;待接收数据的头指针;待接收数据的长;
* 输出: 无
* 备注: 通信中如果出现超时故障 则直接返回 避免长等待
********************************************************************************************************/
void Driver_I2CRecv(u8 Address,u8 *DataBuff,u16 DataLen)
{
u8 temp;
u16 time;
//等待总线空闲
time = 500;
while(I2C_SR3&CHSBIT1)
if(!--time)
return;
//发起始条件
I2C_CR2 |= SETBIT0;
//等待发送完毕
time = 500;
while(!(I2C_SR1&CHSBIT0))
if(!--time)
return;
_asm("nop");
_asm("nop");
_asm("nop");
temp = I2C_SR1;
//发从地址
I2C_DR = Address;
//等待ACK应答
time = 500;
while(!(I2C_SR1&CHSBIT1))
if(!--time)
{
//超时无应答 失败
//发停止 退出
I2C_CR2 |= SETBIT1;
return;
}
_asm("nop");
_asm("nop");
_asm("nop");
temp = I2C_SR1;
//清ADDR标志
temp = I2C_SR3;
//接收数据,读DataLen-1个数
//使能ACK应答
I2C_CR2 |= SETBIT2;
for(;DataLen>1;DataLen--,DataBuff++)
{
//等待寄存器为满
time = 500;
while(!(I2C_SR1&CHSBIT6))
if(!--time)
return;
*DataBuff = I2C_DR;
}
//关闭ACK应答
I2C_CR2 &= CLRBIT2;
//发停止条件,关闭通信
//清BTF位
temp = I2C_SR1;
temp = I2C_DR;
//发停止
I2C_CR2 |= SETBIT1;
_asm("nop");
_asm("nop");
_asm("nop");
//读最后一个数
time = 500;
while(!(I2C_SR1&CHSBIT6))
if(!--time)
return;
*DataBuff = I2C_DR;
}
//程序从这里开始运行
main()
{
//初始化I2C接口
Driver_I2CON();
//可以开始进行I2C通信编程
//发送
//Driver_I2CSend...
//接收
//Driver_I2CRecv...
//OK
while (1);
}