打印
[STM8]

STM8 硬件I2C没反应

[复制链接]
12737|22
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lo_xiaohua_ve|  楼主 | 2010-5-4 11:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在做完模拟的I2C后,现在改用硬件的I2C,一点反应都没有,在仿真的情况下用示波器检测,就连Start信号也看不到,仿真软件中看到寄存器的值又是正确的,同志们帮忙分析下原因,下面是代码,用的是ST的DEMO和库函数

#define I2C_Speed              35000

void I2cInit(void)
{
/* Optional: put here as example only */
I2C_DeInit();
/* I2C Peripheral Enable */
I2C_Cmd(ENABLE);
/* Apply I2C configuration after enabling it */
I2C_Init(I2C_Speed, 0x88, I2C_DUTYCYCLE_2, I2C_ACK_CURR, I2C_ADDMODE_7BIT, 8);
}

void I2C_EE_BufferRead(u8* pBuffer, u16 ReadAddr, u8 NumByteToRead)
{  
    /* While the bus is busy */
  while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));
  
  /* Generate start & wait event detection */
    I2C_GenerateSTART(ENABLE);
  /* Test on EV5 and clear it */
  while (!I2C_CheckEvent(I2C_EVENT_MASTER_START_SENT));
  
  /* Send slave Address in write direction & wait detection event */
    I2C_Send7bitAddress(CP_Add, I2C_DIRECTION_TX);
   /* Test on EV6 and clear it */
    while (!I2C_CheckEvent(I2C_EVENT_MASTER_ADDRESS_ACKED));
    I2C_ClearFlag(I2C_FLAG_ADDRESSSENTMATCHED);
   
   /* Send Address of first byte to be read & wait event detection */
    //I2C_SendData((u8)(ReadAddr >> 8)); /* MSB */
    /* Test on EV8 and clear it */
    //while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    I2C_SendData((u8)(ReadAddr)); /* LSB */
  /* Test on EV8 and clear it */
    while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  
  /* Send STRAT condition a second time */  
  I2C_GenerateSTART(ENABLE);
    /* Test on EV5 and clear it */
   while (!I2C_CheckEvent(I2C_EVENT_MASTER_START_SENT));
  
  /* Send slave Address in read direction & wait event */
    I2C_Send7bitAddress(CP_Add, I2C_DIRECTION_RX);
   /* Test on EV6 and clear it */
    while (!I2C_CheckEvent(I2C_EVENT_MASTER_ADDRESS_ACKED));
    I2C_ClearFlag(I2C_FLAG_ADDRESSSENTMATCHED);
  
  /* While there is data to be read */
  while(NumByteToRead)  
  {
    if(NumByteToRead == 1)
    {
      /* Disable Acknowledgement */
      I2C_AcknowledgeConfig(I2C_ACK_NONE);
      
      /* Send STOP Condition */
      I2C_GenerateSTOP(ENABLE);
    }
    /* Test on EV7 and clear it */
    if(I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_RECEIVED))  
    {      
      /* Read a byte from the EEPROM */
      *pBuffer = I2C_ReceiveData();
      /* Point to the next location where the byte read will be saved */
      pBuffer++;
      
      /* Decrement the read bytes counter */
      NumByteToRead--;        
    }   
  }
  /* Enable Acknowledgement to be ready for another reception */
  I2C_AcknowledgeConfig(I2C_ACK_CURR);
}

设置I2C频率是35K,非标准的,输入给I2C的频率设为8M,我用的时钟是内部8M的时钟,用I2C这两个口做模拟I2C是可以用的,实在想不明白了
沙发
shizhewen| | 2010-5-4 12:00 | 只看该作者
应该是硬件的问题,ST的I2C好像不能用。

使用特权

评论回复
板凳
lo_xiaohua_ve|  楼主 | 2010-5-4 12:59 | 只看该作者
我问ST公司的工程师,他说这个例子在他们的DEMO板上读写EEPROM是可以的,我就纳闷勒,太奇怪了

使用特权

评论回复
地板
yybj| | 2010-5-4 20:42 | 只看该作者
ST的I2C不能用??

使用特权

评论回复
5
txcy| | 2010-5-4 20:52 | 只看该作者
应该不会吧,只是比较不好调

使用特权

评论回复
6
lo_xiaohua_ve|  楼主 | 2010-5-4 21:07 | 只看该作者
有人做过吗?给点意见啊,我都弄好几天了,郁闷得很啦

使用特权

评论回复
7
bili| | 2010-5-5 11:50 | 只看该作者
我没用过ST的Demo,但是我用使用内部I2C没有问题,最好你自己看规格书看看相关的寄存器是不是按照程序配置成功。

使用特权

评论回复
8
lo_xiaohua_ve|  楼主 | 2010-5-5 14:22 | 只看该作者
7楼的兄弟,是否可以参考下你的初始化程序呀?

使用特权

评论回复
9
CrazyST| | 2010-5-7 12:41 | 只看该作者
是不是你使用了第二复用功能的I2C接口但忘了改选项字节?

使用特权

评论回复
10
lo_xiaohua_ve|  楼主 | 2010-5-7 17:41 | 只看该作者
什么选项字节,没看到啊?

使用特权

评论回复
11
yechengyuan| | 2010-10-7 19:06 | 只看该作者
1# lo_xiaohua_ve
我今天终于找出问题了,ST的库没有问题,例程的一个函数有问题

void I2C_EE_ByteWrite(u8 WriteData, u16 WriteAddr)
在写完器件地址后就会死机,在

  while(!I2C_CheckEvent(I2C_EVENT_MASTER_ADDRESS_ACKED));
后面加上这个就好了
  I2C_ClearFlag(I2C_FLAG_ADDRESSSENTMATCHED);

使用特权

评论回复
12
hsbjb| | 2010-10-8 21:00 | 只看该作者
原来是例程的函数有问题

使用特权

评论回复
13
xyz160405| | 2010-10-20 22:43 | 只看该作者
学习学习
咱正要弄这个

使用特权

评论回复
14
lzymcu| | 2010-11-22 17:16 | 只看该作者
我也用iic,我也用库,做从iic还可以,做主iic就从来没有看见波形出来过,最后还得用模拟,实在想不明白!!

使用特权

评论回复
15
shuishuo615| | 2013-10-14 22:04 | 只看该作者
mark

使用特权

评论回复
16
wfmartin28| | 2013-10-15 10:16 | 只看该作者
给你贴一个我读取数字温度传感器ADT7410的程序
/* init i2c */
void Bsp_IIC_Config(void)
{
GPIO_Init(GPIOE,
     GPIO_PIN_1|GPIO_PIN_2,
     GPIO_MODE_OUT_PP_HIGH_SLOW); //push-pull high output.2MHz.
CLK->PCKENR1 |= 0x01; //open i2c clk.
I2C_DeInit();

I2C_Init(100000, //100khz.
    0xa0, //address.
    I2C_DUTYCYCLE_2, //50% duty cycle.
    I2C_ACK_CURR,
    I2C_ADDMODE_7BIT,
    16); //16MHz input clock.
}
void IIC_TEMP(void)
{
uint16_t Timeout;
  
//While the bus is busy,wait it.   
Timeout = 0x1000;
while(I2C_GetFlagStatus( I2C_FLAG_BUSBUSY))
{
  if((Timeout--) == 0)
  {
   nop();
  }
}

//Send START condition.
I2C_GenerateSTART(ENABLE);
// Test on EV5 and clear it (cleared by reading SR1 then writing to DR)
Timeout = 0x1000;
while(!I2C_CheckEvent( I2C_EVENT_MASTER_MODE_SELECT))
{
  if((Timeout--) == 0)
  {
   nop();
  }
}
// Send sensor address for write.
I2C_Send7bitAddress( (uint8_t)0x90, I2C_DIRECTION_TX);
// Test on EV6 and clear it.
Timeout = 0x1000;
while(!I2C_CheckEvent( I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
  if((Timeout--) == 0)
  {
   nop();
  }
}
//Send the register address.
I2C_SendData((uint8_t)0x00);   
// Test on EV8 and clear it.
Timeout = 0x1000;
while(!I2C_CheckEvent( I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
  if((Timeout--) == 0)
  {
   nop();
  }
}
// Send START condition.
I2C_GenerateSTART(ENABLE);
// Test on EV5 and clear it (cleared by reading SR1 then writing to DR).
Timeout = 0x1000;
while(!I2C_CheckEvent( I2C_EVENT_MASTER_MODE_SELECT))
{
  if((Timeout--) == 0)
  {
   nop();
  }
}

// Send sensor address for read
I2C_Send7bitAddress((uint8_t)0x90, I2C_DIRECTION_RX);
// Test on EV6 and clear it.
Timeout = 0x1000;
while(!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
{
  if((Timeout--) == 0)
  {
   nop();
  }
}  
// Test on EV7 and clear it.
Timeout = 0x1000;
while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_RECEIVED))
{
  if((Timeout--) == 0)
  {
   nop();
  }
}
// Read temperature high byte from the sensor.
CanTX[1] = I2C_ReceiveData();
// Disable Acknowledgement
    I2C_AcknowledgeConfig(I2C_ACK_NONE);
IIC_Delay(1); //at least delay 9*10us.

// Read temperature low byte from the sensor.
CanTX[2] = I2C_ReceiveData();
    // Program the STOP
I2C_GenerateSTOP(ENABLE);

// eable Acknowledgement
    I2C_AcknowledgeConfig(I2C_ACK_CURR);

CanTX[0] = 0x35;
CAN_Transmit(0x55a,
     CAN_Id_Standard,
     CAN_RTR_Data,
     3,
     CanTX);
}
/* delay 0.2ms*times */
void IIC_Delay(uint8_t times)
{
volatile uint8_t dly;

while(times--)
{
  for(dly=220; dly>0; dly--);
  for(dly=220; dly>0; dly--);
  for(dly=220; dly>0; dly--);
}
}

使用特权

评论回复
17
yangganglone| | 2013-12-5 13:26 | 只看该作者
我现在也是在做2个单片机的硬件iic通讯,主机发数据后,从机中断接收不到数据,很奇怪,我现在很急,谁帮我看下

使用特权

评论回复
18
feilusia| | 2013-12-5 14:28 | 只看该作者
我以前用硬件IIC也调了几天没调出来。后来改用模拟的就OK了。

使用特权

评论回复
19
yangganglone| | 2013-12-5 14:34 | 只看该作者
feilusia 发表于 2013-12-5 14:28
我以前用硬件IIC也调了几天没调出来。后来改用模拟的就OK了。

可是模拟,从机接收怎么模拟呢?

使用特权

评论回复
20
feilusia| | 2013-12-5 14:51 | 只看该作者
yangganglone 发表于 2013-12-5 14:34
可是模拟,从机接收怎么模拟呢?

IIC的双机通信我没试过,因为简单的双机通信可以用串口,速度快的双机通信能用SPI,感觉IIC用来做双机通信没有什么优势。
IIC我只用来读外接的EEPROM。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

33

帖子

1

粉丝