中级会员
 
- 积分
- 262
- 金钱
- 262
- 注册时间
- 2012-8-29
- 在线时间
- 2 小时
|

楼主 |
发表于 2013-4-2 09:10:00
|
显示全部楼层
回复【5楼】donghuiyun6668:
---------------------------------
我是操作寄存器的!
这是我I2C部分的程序,用的是efm32tg822,和stm32f10x是差不多的:
#include "i2c.h"
#include "delay.h"
u32 timout;
void I2C_Initi(void) //工作在标准模式
{
GPIOA -> MODEL |= 0X88; //配置PA.0(SDA)为开漏输出,PA.1(SCL)为开漏输出,带上拉
// GPIOA -> DOUT |= 0X03; //SDA,SCL内部上拉
CMU -> HFPERCLKEN0 |= 1<<11; //开启I2C0的时钟
I2C0 -> CTRL |= 1<<0; //开启I2C模式
I2C0 -> CTRL |= 1<<15; //总线空闲会自动告诉I2C模块,允许初始化新的传输
I2C0 -> CLKDIV |= 1<<2; //设置I2C时钟分频
I2C0 -> IEN |= 1<<3 | 1<<5 | 1<<6 | 1<<7;
I2C0 -> ROUTE |= 0X03<<0; //使能SDA,SCL
}
void shut_i2c(void)
{
GPIOA -> MODEL &= ~0xff; //禁止SDA,SCL
CMU -> HFPERCLKEN0 &= ~(1<<11); //关闭I2C0的时钟
I2C0 -> CTRL &= ~(1<<0); //关闭I2C模式
}
void I2CStart(void)
{
I2C0 -> CMD = 1;
}
void I2CStop(void)
{
I2C0 -> CMD = 2;
}
void SendAck(u8 AckBit)
{
if(AckBit)
{
I2C0 -> CMD = 8;
}
else
{
I2C0 -> CMD = 4;
}
}
u8 I2CRdStr(u8 ucSla,u8 ucAddress,u8 *ucBuf,u8 ucCount)
{
u8 i;
I2C0 -> CMD = 0xc0; //清空TX和pending
I2C0 -> IFC = 0XFFFF;
while(I2C0->STATE&0x10); //判断总线是否空闲
I2C0 -> TXDATA = ucSla;
I2CStart();
timout = 0;
while( !(I2C0->IF&(1<<3)) )//等待发送完成
{
if(timout++>0xfff)
{
timout=0;
I2CStop();
return 0;
}
}
I2C0->IFC = 1<<3; //清标志位
timout = 0;
while( !(I2C0->IF&(1<<6)) ) //等待从器件应答
{
if(timout++>0xfff)
{
timout=0;
I2CStop();
return 0;
}
}
I2C0->IFC = 1<<6; //清标志位
I2C0 -> TXDATA = ucAddress;
I2CStop();
timout = 0;
while( !(I2C0->IF&(1<<3)) )//等待发送完成
{
if(timout++>0xfff)
{
timout=0;
I2CStop();
return 0;
}
}
I2C0->IFC = 1<<3; //清标志位
timout = 0;
while( !(I2C0->IF&(1<<6)) ) //等待从器件应答
{
if(timout++>0xfff)
{
timout=0;
I2CStop();
return 0;
}
}
I2C0->IFC = 1<<6; //清标志位
I2C0 -> TXDATA = ucSla+1;
I2CStart();
timout = 0;
while( !(I2C0->IF&(1<<3)) )//等待发送完成
{
if(timout++>0xfff)
{
timout=0;
I2CStop();
return 0;
}
}
I2C0->IFC = 1<<3; //清标志位
timout = 0;
while( !(I2C0->IF&(1<<6)) ) //等待从器件应答
{
if(timout++>0xfff)
{
timout=0;
I2CStop();
return 0;
}
}
I2C0->IFC = 1<<6; //清标志位
i=ucCount;
while(i--)
{
timout = 0;
while(!(I2C0->IF&(1<<5)))//等待接收寄存器的数据有效
{
if(timout++>0xfff)
{
timout=0;
I2CStop();
// RC522_RST();
return 0;
}
}
*ucBuf = I2C0->RXDATA;
I2C0->IFC = 1<<5;
if(i)
{
SendAck(0);
}
ucBuf++;
}
SendAck(1);
I2CStop();
delay_us(20);
return 1;
}
u8 I2CWrStr(u8 ucSla,u8 ucAddress,u8 *ucData,u8 ucNo)
{
u8 i;
I2C0 -> IFC = 0XFFFF;
I2C0 -> CMD = 0xc0; //清空TX和pending
while(I2C0->STATE&0x10); //判断总线是否空闲
I2C0 -> TXDATA = ucSla;
I2CStart();
timout = 0;
while( !(I2C0->IF&(1<<3)) )//等待发送完成
{
if(timout++>0xfff)
{
timout=0;
I2CStop();
return 0;
}
}
I2C0->IFC = 0xffff; //清标志位
if(I2C0->IF&(1<<7)) //如果接收到从器件的非应答信号
{
I2C0->IFC = 1<<7;
I2CStop();
return 0 ;
}
timout = 0;
while( !(I2C0->IF&(1<<6)) ) //等待从器件应答
{
if(timout++>0xfff)
{
timout=0;
I2CStop();
return 0;
}
}
I2C0->IFC = 0xffff; //清标志位
I2C0 -> TXDATA = ucAddress;
timout = 0;
while( !(I2C0->IF&(1<<3)) )//等待发送完成
{
if(timout++>0xfff)
{
timout=0;
I2CStop();
return 0;
}
}
I2C0->IFC = 1<<3; //清标志位
if(I2C0->IF&(1<<7)) //如果接收到从器件的非应答信号
{
I2C0->IFC = 1<<7;
I2CStop();
return 0 ;
}
timout = 0;
while( !(I2C0->IF&(1<<6)) ) //等待从器件应答
{
if(timout++>0xfff)
{
timout=0;
I2CStop();
return 0;
}
}
I2C0->IFC = 0xffff; //清标志位
i = ucNo;
while(i--)
{
I2C0 -> TXDATA = *ucData;
timout = 0;
while( !(I2C0->IF&(1<<3)) )//等待发送完成
{
if(timout++>0xfff)
{
timout=0;
I2CStop();
return 0;
}
}
I2C0->IFC = 1<<3; //清标志位
if(i)
{ if(I2C0->IF&(1<<7)) //如果接收到从器件的非应答信号
{
I2C0->IFC = 1<<7;
I2CStop();
return 0 ;
}
timout = 0;
while( !(I2C0->IF&(1<<6)) ) //等待从器件应答
{
if(timout++>0xfff)
{
timout=0;
I2CStop();
return 0;
}
}
I2C0->IFC = 0xffff; //清标志位
}
ucData++;
}
I2CStop();
delay_us(20);
return 1;
} |
|