你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

正在使用stm8作为从机与esp32进行i2c通讯,但是发现主机扫描的i2c地址与stm8从机设置的i2c地址不一样,请问如何解决?

[复制链接]
Troy-_Wong 提问时间:2024-10-24 10:51 / 未解决

这个是stm8从机代码

===



#include <Arduino.h>
// #include <stm8s.h> // 假设你使用了STM8标准库
// #include "i2c_slave.h"
#include "Wire.h"
#define I2C_SLAVE_ADDR 0x30

#define I2C_DATA_SIZE 8

#if ((I2C_DATA_SIZE > 0) && ((I2C_DATA_SIZE & (I2C_DATA_SIZE - 1)) != 0))
#error I2C_DATA_SIZE isnt a power of 2.
#endif

#define uint8_bits_def(x)         \
  union                           \
  {                               \
    unsigned char x;              \
    struct                        \
    {                             \
      unsigned char x##_Bit0 : 1, \
          x##_Bit1 : 1,           \
          x##_Bit2 : 1,           \
          x##_Bit3 : 1,           \
          x##_Bit4 : 1,           \
          x##_Bit5 : 1,           \
          x##_Bit6 : 1,           \
          x##_Bit7 : 1;           \
    };                            \
  }

uint8_bits_def(tagI2C);
uint8_t i2c_addr = 0;
uint8_t i2c_data[I2C_DATA_SIZE] = {0x00};
int tagI2C_Bit0 = 0;

// // I2C中断服务处理函数声明
// void I2C_ISR(void) __interrupt(19); // I2C中断向量号

void Serial_print(const char *str)
{
  while (*str)
  {
    Serial_write(*str++); // 逐个字符发送
  }
}

void I2C_Slave_IRQHandler(void)
{
  volatile I2C_Event_TypeDef Event = I2C_GetLastEvent();
  Serial_print("STM8 I2C_Slave_IRQHandler.");
  /* Slave address matched with the address sent by master */
  /* EV1: ADDR = 1, 顺序读SR1,SR3寄存器清除此标志位 */
  if (Event == (I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED))
  {
    tagI2C_Bit0 = 1;
  }
  /* Slave received the data byte from master */
  /* EV2: RxNE = 1, 读DR寄存器清除此位 */
  else if (Event == (I2C_EVENT_SLAVE_BYTE_RECEIVED))
  {
    uint8_t ch = I2C_ReceiveData();
    if (tagI2C_Bit0)
    {
      tagI2C_Bit0 = 0;
      i2c_addr = ch;
    }
    else
    {
      i2c_data[i2c_addr++ & (I2C_DATA_SIZE - 1)] = ch;
    }
  }
  /* Slave received STOP byte from master */
  /* EV4: STOPF = 1,读SR1寄存器后再写CR2清除 */
  else if (Event == (I2C_EVENT_SLAVE_STOP_DETECTED))
  {
    I2C_GetFlagStatus(I2C_FLAG_STOPDETECTION);
    I2C_GenerateSTOP(DISABLE);
  }
  /* SLAVE TRANSMITTER */
  /* Data transmited from slave to master */
  /* EV3: TxE = 1, 写DR寄存器清除DR */
  else if ((Event == (I2C_EVENT_SLAVE_BYTE_TRANSMITTED)) ||
           (Event == (I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED)))
  {
    uint8_t ch = i2c_data[i2c_addr++ & (I2C_DATA_SIZE - 1)];
    I2C_SendData(ch);
  }
  /* Acknowledge failure */
  /* EV3-2: AF = 1, AF is cleared by writing '0' in AF bit of SR2 register */
  else if (Event == (I2C_EVENT_SLAVE_ACK_FAILURE))
  {
    I2C_ClearFlag(I2C_FLAG_ACKNOWLEDGEFAILURE);
  }
}

// INTERRUPT_HANDLER(I2C_IRQHandler, 19)
// {
//   I2C_Slave_IRQHandler();
// }

void I2C_Slave_Init(void)
{
  // open I2C clk
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, ENABLE);
  I2C_DeInit();
  I2C_Init(50000, I2C_SLAVE_ADDR, I2C_DUTYCYCLE_2, I2C_ACK_CURR, I2C_ADDMODE_7BIT, (CLK_GetClockFreq() / 1000000));
  /* Enable Error Interrupt*/
  I2C_ITConfig((I2C_IT_TypeDef)(I2C_IT_ERR | I2C_IT_EVT | I2C_IT_BUF), ENABLE);
  /* enable IIC*/
  I2C_Cmd(ENABLE);
  // enableInterrupts();
}
void setup()
{
  // 初始化串口通信,波特率为9600
  Serial_begin(9600);

  // 给串口输出一条消息,表示系统已经启动
  Serial_print("STM8 initialized and ready.");

  I2C_Slave_Init();

  // pid_i2c_init();
}

void loop()
{
}

这个是esp32主机代码

===

#include <Arduino.h>
#include "Wire.h"
uint32_t I2C2_SPEED = 50000;
void setup()
{
  Serial.begin(115200);
  Wire.begin(21, 22, I2C2_SPEED);
}

void loop()
{
  byte error, address;
  int nDevices = 0;

  delay(3000);

  Serial.println("Scanning for I2C devices ...");
  for (address = 0x01; address < 0x7f; address++)
  {
    Wire.beginTransmission(address);
    // Wire.write(0x11);
    error = Wire.endTransmission();
    if (error == 0)
    {
      Serial.printf("I2C device found at address 0x%02X\n", address);
      nDevices++;
    }
    else if (error != 2)
    {

      Serial.printf("Error %d at address 0x%02X\n", error, address);
    }
  }
  if (nDevices == 0)
  {
    Serial.println("No I2C devices found");
  }
}
esp32 debug:
Scanning for I2C devices ...
I2C device found at address 0x18
Scanning for I2C devices ...
I2C device found at address 0x18
Scanning for I2C devices ...
I2C device found at address 0x18

当esp32扫描到这个i2c地址后stm8会重启,当前不知道是什么原因导致的
收藏 评论4 发布时间:2024-10-24 10:51

举报

4个回答
butterflyspring 回答时间:3 天前
通常可以调试看看地址寄存器的内容是否是设置的地址,同时看看响应时的寄存器标志位 ADDR 是否置位。


另外STM8速度通常只有16Mhz,响应中断要尽可能快,所以最好优化中断执行时间,可参考一下例程。
Troy-_Wong 回答时间:前天 11:48

butterflyspring 发表于 2024-10-25 11:00
通常可以调试看看地址寄存器的内容是否是设置的地址,同时看看响应时的寄存器标志位 ADDR 是否置位。</p>
<p>

`当esp32扫描到这个i2c地址后stm8会重启,这个重启会是什么原因导致的呢,而且debug一点报错都没有,stm直接是重启了,只要主机扫描到i2c设备从机stm8就重启了

Troy-_Wong 回答时间:前天 12:00

Troy-_Wong 发表于 2024-10-26 11:48
`当esp32扫描到这个i2c地址后stm8会重启,这个重启会是什么原因导致的呢,而且debug一点报错都没有, ...

[md]请问下有stm8作为从设备的案例吗

butterflyspring 回答时间:11 小时前

Troy-_Wong 发表于 2024-10-26 12:00
请问下有stm8作为从设备的案例吗

有的,在标准外设库里,注意中断尽可能快些。优先级高。

stm8sfwlib2.31\STM8S_StdPeriph_Lib\Project\STM8S_StdPeriph_Examples\I2C\I2C_TwoBoards\I2C_DataExchange\Slave

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版