OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5721|回复: 7

硬件I2C,求指导

[复制链接]

25

主题

123

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
262
金钱
262
注册时间
2012-8-29
在线时间
2 小时
发表于 2013-1-11 15:06:46 | 显示全部楼层 |阅读模式
准备使用硬件I2C,efm32芯片,和STM32内核一样。现在还没搞懂硬件I2C怎么使用,希望大侠们指点指点。1)硬件I2C和IO模拟的一样吗?是不是也要按照时序送起始条件,应答之类的? 2)硬件I2C是不是可以不管时序,配置好从机地址,可以直接通过寄存器读取数据?··········  总之,我调了半天,没什么进展,谢谢指导!!!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

27

主题

274

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
472
金钱
472
注册时间
2011-11-2
在线时间
11 小时
发表于 2013-1-13 18:58:21 | 显示全部楼层
回复 支持 反对

使用道具 举报

1

主题

4

帖子

0

精华

新手入门

积分
28
金钱
28
注册时间
2013-3-13
在线时间
0 小时
发表于 2013-3-30 15:25:29 | 显示全部楼层
回复【楼主位】fangjun0221:
---------------------------------
楼主调试成功了没有?我也在学习这方面的,刚着手不知道该如何下手啊!
回复 支持 反对

使用道具 举报

25

主题

123

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
262
金钱
262
注册时间
2012-8-29
在线时间
2 小时
 楼主| 发表于 2013-4-1 09:42:55 | 显示全部楼层
回复【3楼】donghuiyun6668:
---------------------------------
调通了!你遇上了什么问题?
回复 支持 反对

使用道具 举报

1

主题

4

帖子

0

精华

新手入门

积分
28
金钱
28
注册时间
2013-3-13
在线时间
0 小时
发表于 2013-4-1 19:45:57 | 显示全部楼层
回复【4楼】fangjun0221:
---------------------------------
我想采用操作寄存器的方法,请问你是用的库函数还是操作寄存器?没接触过这方面的,能否发一下你的例程我学习一下!不胜感激!
回复 支持 反对

使用道具 举报

25

主题

123

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
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;
}
回复 支持 反对

使用道具 举报

1

主题

4

帖子

0

精华

新手入门

积分
28
金钱
28
注册时间
2013-3-13
在线时间
0 小时
发表于 2013-4-5 21:46:30 | 显示全部楼层
回复【6楼】fangjun0221:
---------------------------------
你能给我一份这个efm32tg822的资料吗?网上的这个而资料很少,我对照着这个的写stm32的。谢谢
回复 支持 反对

使用道具 举报

25

主题

123

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
262
金钱
262
注册时间
2012-8-29
在线时间
2 小时
 楼主| 发表于 2013-4-7 14:20:37 | 显示全部楼层
`

TinyGecko_um_en[1].pdf

8.51 MB, 下载次数: 109

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-22 02:16

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表