OpenEdv-开源电子网

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

求各位大大能指点下菜鸟我

[复制链接]

4

主题

13

帖子

0

精华

新手上路

积分
49
金钱
49
注册时间
2015-1-12
在线时间
0 小时
发表于 2015-1-13 11:34:32 | 显示全部楼层 |阅读模式
5金钱
关于硬件I2C,最近几天才开始碰,感觉毫无头绪,不知道从哪里下手。各位大神能指点下,需要怎么做么。

最佳答案

查看完整内容[请看2#楼]

我给你发个STM32F407的,只要修改下IO定义就可以用到STM32F103了.用了一年多了,目前没出现过问题。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

1385

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
12081
金钱
12081
注册时间
2013-3-8
在线时间
1284 小时
发表于 2015-1-13 11:34:33 | 显示全部楼层
我给你发个STM32F407的,只要修改下IO定义就可以用到STM32F103了.用了一年多了,目前没出现过问题。

I2C.rar

3.29 KB, 下载次数: 207

回复

使用道具 举报

21

主题

2205

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
5141
金钱
5141
注册时间
2014-8-26
在线时间
1317 小时
发表于 2015-1-13 12:13:25 | 显示全部楼层
没做过,官方有相关的库,
回复

使用道具 举报

70

主题

6763

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
13135
金钱
13135
注册时间
2012-11-26
在线时间
3814 小时
发表于 2015-1-13 12:17:07 | 显示全部楼层
帮顶  没用过  都是IO口模拟的
学无止境
回复

使用道具 举报

3

主题

48

帖子

0

精华

初级会员

Rank: 2

积分
96
金钱
96
注册时间
2012-10-15
在线时间
4 小时
发表于 2015-1-13 14:36:01 | 显示全部楼层
听说st的硬件iic就是鸡肋
回复

使用道具 举报

4

主题

13

帖子

0

精华

新手上路

积分
49
金钱
49
注册时间
2015-1-12
在线时间
0 小时
 楼主| 发表于 2015-1-14 11:56:26 | 显示全部楼层
回复【2楼】login_FAE:
---------------------------------
官方给的好像也是模拟的 大哥知道哪里有下硬件的么 可否给个链接
回复

使用道具 举报

4

主题

13

帖子

0

精华

新手上路

积分
49
金钱
49
注册时间
2015-1-12
在线时间
0 小时
 楼主| 发表于 2015-1-14 11:57:34 | 显示全部楼层
回复【3楼】jermy_z:
---------------------------------
是啊 模拟的已经实现了 可是要求是用硬件 没办法啊- -
回复

使用道具 举报

21

主题

2205

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
5141
金钱
5141
注册时间
2014-8-26
在线时间
1317 小时
发表于 2015-1-14 15:57:27 | 显示全部楼层
回复【6楼】_____503___:
---------------------------------
没用过   我同事在调这个库,看下是不是
http://www.st.com/web/en/catalog/tools/FM147/CL1794/SC961/SS1743/LN1734/PF258336?s_searchtype=keyword
回复

使用道具 举报

9

主题

1385

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
12081
金钱
12081
注册时间
2013-3-8
在线时间
1284 小时
发表于 2015-1-14 16:41:28 | 显示全部楼层
回复【5楼】_____503___:
---------------------------------
I2C控制什么,我这儿有一个控制24c01和24c256的。硬件控制。
回复

使用道具 举报

4

主题

13

帖子

0

精华

新手上路

积分
49
金钱
49
注册时间
2015-1-12
在线时间
0 小时
 楼主| 发表于 2015-1-15 09:11:12 | 显示全部楼层
回复【7楼】login_FAE:
---------------------------------
多谢
回复

使用道具 举报

4

主题

13

帖子

0

精华

新手上路

积分
49
金钱
49
注册时间
2015-1-12
在线时间
0 小时
 楼主| 发表于 2015-1-15 09:15:34 | 显示全部楼层
回复【9楼】augustedward:
---------------------------------
多谢~
我看到大哥你好像没用中断啊 是怎么收发的呢
回复

使用道具 举报

4

主题

13

帖子

0

精华

新手上路

积分
49
金钱
49
注册时间
2015-1-12
在线时间
0 小时
 楼主| 发表于 2015-1-15 09:20:07 | 显示全部楼层
回复【9楼】augustedward:
---------------------------------
这是昨天根据网上的资料改的,在中断中收发。可是SCK都没有产生时钟。。。

void I2C_Init(void)
{
////////////////I2C GPIO配置
RCC->APB2ENR |= 1<<3;     //使能PORTB时钟

GPIOB->CRH &= 0xFFFF00FF;   //I2C2:PB10->SCL, B11->SDL  
GPIOB->CRH |= 0x0000FF00;   //复用开漏输出 

////////////////I2C 寄存器配置
  RCC->APB1ENR |= 1<<22;    //使能外设I2C2时钟

I2C2->CR1 |= 0<<0;              //禁用I2C2

RCC->APB1RSTR |= 1<<22;   //复位I2C2
RCC->APB1RSTR &= ~(1<<22); //复位结束I2C2

I2C2->CR2 |= 36;                //000010:2MHz ... 100100:36MHz,其他禁用(此处为36MHZ)  

I2C2->CCR |= 0<<15; //I2C主模式  0:标准模式的I2C    1:快速模式的I2C
I2C2->CCR |= 90<<0;            //时钟控制分频系数 = CLK1/2/f(f为想得到的频率,此处PCLK1=36MHZ,f=200KHZ) 

I2C2->TRISE |= 37; //最大允许SCL上升时间为1000ns,故TRISE[5:0]中必须写入(1us/(1/36)us = 36+1)

I2C2->CR1 |= 1<<10;             //打开ACK应答,在接收到一个字节后返回一个应答
I2C2->CR1 |= 1<<6;              //广播呼叫使能

I2C2->OAR1 |= 0<<15;            //寻址模式   1 响应10位地址  0  响应7位地址
I2C2->OAR1 |= 1<<14;            //必须始终由软件保持为 1
I2C2->OAR1 |= 0xBC<<1;          //设置接口地址的 7~1位(接口地址设为0XBC)

I2C2->CR2 |= 1<<9;              //事件中断使能
I2C2->CR2 |= 1<<8;              //出错中断使能

I2C2->CR1 |= 1<<0;              //开启I2C2

////////////////I2C 开中断
MY_NVIC_Init(1,0,I2C2_EV_IRQChannel,2);      //设置抢占优先级为4,响应优先级为0,中断分组为4 
MY_NVIC_Init(0,0,I2C2_ER_IRQChannel,2);      //设置I2C错误中断抢占优先级为3
}

void I2C_Start(void)   //I2C2产生起始条件
{  
    I2C2->CR1 |= 1<<8;                
}
  
void I2C_Stop(void)   //I2C2产生停止条件
{  
    I2C2->CR1 |= 1<<9;                


void I2C_End(void)                  //关闭I2C   
{  
I2C2->CR1 &= ~(1<<0);        
}

void I2C_Write(u8 data)   //I2C2写一个字节 
{  
I2C2->DR = data;  
}

u8 I2C_Read(void)   //I2C2读一个字节
{  
while(!(I2C2->SR1 & 1<<6));     //接收到数据标志位  
return I2C2->DR;  
}

u8 go = 0;
void I2C2_EV_IRQHandler(void)
{

u16 clear = 0;

if(I2C2 -> SR1 & 1<<0 )          //已发送起始条件,写数据寄存器的操作将清除该位  
{
switch(go)
{
case 0:
{
I2C_Write(WRITE_ADDR);        //写入从机地址,写指令操作地址  
break;
}
case 1:
{
I2C_Write(WRITE_ADDR);        //写入从机地址,写指令操作地址  
break;

case 2:
{
I2C_Write(READ_ADDR);        //写入从机地址,读数据操作地址  
break;
}
}
}
if(I2C2 -> SR1 & 1<<1 )        //从机地址已发送 
{
clear = I2C2 -> SR2; //读取SR2可以清除该位中断  
switch(go)
{
case 0:
{
I2C_Write(0x81);    //写入待写入的EEPROM单元地址 
break;
}
case 1:
{
I2C_Write(0x4E);    //写入待写入的EEPROM单元地址  
break;
}
case 2:
{
I2C_Stop();
break;
}
}
}
if(I2C2 -> SR1 & 1<<2 )        //字节发送结束  发送地址字节时,不触发此中断  
{
switch(go)
{
case 0:
{
I2C_Write(0x00);            //写入数据            
go = 1;
I2C_Start();
break;
}
case 1:
{
go = 2;
I2C_Start();
break;
}
case 2:
{
break;
}
}
}  
}
void I2C2_ER_IRQHandler(void)
{
if(I2C2->SR1 & 1<<10)          //应答失败  
{
I2C2->SR1 &=~(1<<10);      //清除中断  
}
if(I2C2->SR1 & 1<<14)          //超时  

I2C2->SR1 &=~(1<<14);      //清除中断  
}
if(I2C2->SR1 & 1<<11)          //过载/欠载  
{
I2C2->SR1 &=~(1<<11);      //清除中断  
}
if(I2C2->SR1 & 1<<9)           //仲裁丢失  
{
I2C2->SR1 &=~(1<<9);       //清除中断  

if(I2C2->SR1 & 1<<8)           //总线出错  
{
I2C2->SR1 &=~(1<<8);       //清除中断  
}
}
回复

使用道具 举报

9

主题

1385

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
12081
金钱
12081
注册时间
2013-3-8
在线时间
1284 小时
发表于 2015-1-15 10:22:11 | 显示全部楼层
回复【11楼】_____503___:
---------------------------------
我没用中断啊,判断状态就行了。开中断干嘛?
回复

使用道具 举报

9

主题

1385

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
12081
金钱
12081
注册时间
2013-3-8
在线时间
1284 小时
发表于 2015-1-15 10:23:23 | 显示全部楼层
回复【12楼】_____503___:
---------------------------------
我写的只是STM32做主机模式,只用查状态就行了。如果做从机,那可能就要开中断了!
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-27 00:58

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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