7456|12

64

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

请教STM32的I2C通讯问题 [复制链接]

大家好,我最近在弄一个小东西,是用stm32的I2C和一个射频芯片的I2C通讯,主要目的是往我的射频芯片里面写数据。前几天我在网上找到了st的固件库和demo,结果一直没有调通,后来上网看到它的升级版,下下来跑了它的双地址通讯那个demo,跑通了。我把它做了一些更改,放在我自己的芯片上面跑,但是跑不通, while(!I2C_CheckEvent(I2C2, I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED)); 这一句过不去。我注释掉check函数后,让它循环发数据,用示波器看到的结果是我的每个数据都出现两次,不知道是为什么,我不知道是不是我的射频芯片有问题还是我的程序有问题。把程序贴下来,大侠们帮我看看,小妹在此谢过~~

/* Private define ------------------------------------------------------------*/
#define I2C1_SLAVE_ADDRESS7       0x30
#define RDA5800C_SLAVE_ADDRESS7   0x20          //我的射频芯片的地址
#define BufferSize                4 
#define ClockSpeed                200000

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
I2C_InitTypeDef  I2C_InitStructure;
u8 I2C1_Buffer1_Tx[BufferSize] = {0x00,0xff,0x00,0xff};
//为示波器看数据方便设为00,ff
u8 Buffer_Rx[BufferSize];
u8 Tx_Idx = 0, Rx_Idx = 0;


  /* System clocks configuration ---------------------------------------------*/
  RCC_Configuration();

  /* NVIC configuration ------------------------------------------------------*/
  NVIC_Configuration();

  /* GPIO configuration ------------------------------------------------------*/
  GPIO_Configuration();

  /* Enable I2C1 ----------------------------------------------------*/
  I2C_Cmd(I2C1, ENABLE);

  /* I2C1 configuration ------------------------------------------------------*/
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
  I2C_InitStructure.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7;
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  I2C_InitStructure.I2C_ClockSpeed = ClockSpeed;
  I2C_Init(I2C1, &I2C_InitStructure);
  
  /*-----  transmission Phase -----*/
  /* Send I2C1 START condition */
  I2C_GenerateSTART(I2C1, ENABLE);

  /* Test on I2C1 EV5 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); 

  /* Send slave Address for write */
  I2C_Send7bitAddress(I2C1, RDA5800C_SLAVE_ADDRESS7, I2C_Direction_Transmitter);

  /* Test on I2C1 EV6 and clear it */
//  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); 
 //程序就死在这里了,我注释掉后又会死在后面的check语句里面 

  /* Send data */
  while (Tx_Idx < BufferSize)
  {
    /* Send I2C1 data */
    I2C_SendData(I2C1, I2C1_Buffer1_Tx[Tx_Idx++]);

    /* Test on I2C1 EV8 and clear it */
 //   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));     //最后我这里面就只有一句了,就是不停的发数据,什么都不检查了,得到的示波器的波形就是一个byte的0,后接一个bit高位(也就是第九个脉冲,应该得到ack吧?)接着又是一个byte0,一个bit的高位,接着就是我的延时,然后就是1了,跟发0的情况一样,中间多出一个高位。。。。我想请问一下,这是为什么啊?是不是我没有收到应答,DR就又重新把我的数据发了一遍?还是别的原因啊?我的射频芯片是不是不用做配置,直接像我这里一样只要往里发数据就可以了?他的应答我怎么知道有没有呢?请指教。

   for(i=0;i<500;i++);   //为了观察方便做的延时

    if(Tx_Idx==4)   //为了观察示波器而做的死循环
    {
     Tx_Idx=0;
    } 
  }

  /* Send I2C1 STOP Condition */
  I2C_GenerateSTOP(I2C1, ENABLE);


这个问题困扰我很久了,希望这里的xdjm能够帮忙解答,不甚感激啊!!!
   
此帖出自stm32/stm8论坛

最新回复

                                 初始化后第一次是主写,可是就是就是在EV5那个循环内出不来,咋整呢?  详情 回复 发表于 2009-12-29 13:34
点赞 关注
 

回复
举报

73

帖子

0

TA的资源

一粒金砂(初级)

沙发
 

re

1.发送了地址后,死在/* Test on I2C1 EV6 and clear it */,应该是发送的slave地址没有得到响应。在示波器上看到了地址字节后的ACK么?第九个时钟脉冲应该是低电平才表示响应,这个你在上面似乎搞错了。

2.程序死在哪里了,你不要就盲目的注释掉代码,你应该读取一下当时的状态寄存器指,看是哪些位没有置位,不符合EV6/EV8等各种时间的标志定义。

3.你后来发数据看到“波形就是一个byte的0,后接一个bit高位”,显然就是跟本没有得到应答哦。估计从地址发送就没有得到应答了,后面的通信都建立不起来。
此帖出自stm32/stm8论坛
 
 

回复

60

帖子

0

TA的资源

一粒金砂(初级)

板凳
 

请好好看看你的射频芯片手册

                                 非常怀疑你的Slave地址搞错了。
此帖出自stm32/stm8论坛
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

4
 

谢谢楼上的朋友

多谢楼上的朋友的回答,我知道我没有得到应答,之前几天的调试中,我发现就算是我做测试的的那个demo程序I2C1和I2C2通信的时候,他也会有这样的问题,后面的程序不对,前面就没有应答,不知道是为什么,但是确实让我弄了好长时间,后来把固件库版本升级了才调通了。所以我现在根本就不知道是不是我的程序错了还是我自己画的射频模块错了。

呵呵,关于注释代码,我也知道不对,我也看了寄存器的值, 说是应答错误的,是不是这样就可以说明是我的模块错了呢?

关于在示波器上面看ack,这个我不会啊,因为示波器是捕捉的,这个我没法看啊,所以我才把程序死循环才能看到波形,难道有其它的方法?我不懂啊,请多多指教。
此帖出自stm32/stm8论坛
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

5
 

re

 还有一个问题,就是while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); 这个语句不是仅仅做的判断的作用吗?难道在这里它还会对寄存器的值做修改吗?datasheet中说“发送完start以后,主设备等待一次对SR1寄存器读之后对带从设备地址的DR寄存器写”这句话是什么意思?对SR1读会改变它寄存器的值吗?请指教。
此帖出自stm32/stm8论坛
 
 
 

回复

83

帖子

0

TA的资源

一粒金砂(初级)

6
 

你自己都看到应答错误了

AF -- acknowledge failure,没有收到应答位咯。

1.示波器不会用?不能用SCL或者SDA的下降沿来触发捕捉么?
从示波器上看看地址字节发出去没有,总线上电平对不对。

2.
SB: Start Bit (Master mode). 
0: No Start condition
1: Start condition generated.
– Set when a Start condition generated.
– Cleared by software by reading the SR1 register followed by writing the DR register, or by 
hardware when PE=0
意思就是说:发送完Start后,master要读取SR1寄存器,然后往DR寄存器中写入从设备的地址,以此来清掉SB位。

某些寄存器你读一下,它的值就变了,尤其是状态寄存器。这个在mcu中很常见哦。这也就是为什么很多时候不能通过在调试的时候,停下来查看寄存器窗口来得到某个时候寄存器的值。正确的办法是用一个语句,比如读取寄存器变量到一个全局变量中,然后停下来,读取全局变量的值。
此帖出自stm32/stm8论坛
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

7
 

谢谢lut1lut

“正确的办法是用一个语句,比如读取寄存器变量到一个全局变量中,然后停下来,读取全局变量的值。”

lut1lut大侠说的这句话,我有点不理解,当读取寄存器变量到一个全局变量中的过程,不是也读了寄存器吗?这样不是同样导致其状态位的改变吗?
此帖出自stm32/stm8论坛
 
 
 

回复

54

帖子

0

TA的资源

一粒金砂(初级)

8
 

状态位的改变是在读操作之后,读操作读出的是没有被改变

                                  
此帖出自stm32/stm8论坛
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

9
 

slave地址问题

The command byte includes a 7-bit chip address(0010000b) and a r/ w bit. The ACK ( or NACK) is always sent out by receiver

这个是我的芯片手册上写的,我在发送地址的时候就发的20h是写的,这样对吗?
此帖出自stm32/stm8论坛
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

10
 

示波器怎么调?

                                 还有弱弱的问一句,怎么调上升沿下降沿触发的?我的就是一直在运行,前面发送一个地址根本就看不见?具体的怎么调示波器啊?我的示波器是TDS3032B的那个。十分谢谢
此帖出自stm32/stm8论坛
 
 
 

回复

94

帖子

0

TA的资源

一粒金砂(初级)

11
 

谢谢大家的帮忙,已经可以发数据了

                                 已经解决了,呵呵,初次捣腾硬件,什么都不懂,多亏大家的帮忙了。
此帖出自stm32/stm8论坛
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

12
 

说说问题是如何解决的吧,大家帮你,你帮大家

                                 你自己也借此整理一下思路,总结一点经验与大家共享。
此帖出自stm32/stm8论坛
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

13
 
                                 初始化后第一次是主写,可是就是就是在EV5那个循环内出不来,咋整呢?
此帖出自stm32/stm8论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表