在Arduino平台给ESP32写代码时,if后的执行语句内包含return时发现的问题

文章描述了在使用C语言编写SCCB协议时,函数sccb_wack()的返回值对后续函数sccb_read()逻辑的影响。当在sccb_read()中加入return语句后,即使if条件不满足,也会执行后续的执行语句,这与在线编译环境的行为不符,引发作者困惑。

在给摄像头写SCCB协议时,主机发送完字节等待从机应答的函数如下。当从机应答时会返回0,不应答时返回1。因为没有给从机上电,所以这个函数是返回1的,并且会打印“[sccb_wack]no respond…”。

int sccb_wack()
{ 
  int timecount=0;
  sda_high();
  sda_in();
  delayMicroseconds(half_low_period_time);
  scl_high();
  while(digitalRead(sda))
  {
    timecount+=1;
    if(timecount>high_period_time)
    {
      timecount=0;
      Serial.println("[sccb_wack]no respond..");
      sccb_stop();
      return 1;
    }
    delayMicroseconds(1);
  }
  delayMicroseconds(high_period_time);
  scl_low();
  delayMicroseconds(half_low_period_time);
  Serial.println("[sccb_wack]got respond..");
  return 0;
}

在一个读取从机寄存器数值的函数中,对上述函数进行了调用,如下。其中return写在了最后一个if的执行语句中。由于sccb_wack()一直返回1,所以下面函数中的if是不应该执行的,该函数也不会返回什么数值。

unsigned char sccb_read(unsigned char reg)
{
  unsigned char receive=0;
  sccb_start();//起始信号
  sccb_send_byte(address_w);//从机写入地址
  if(!sccb_wack())
  {
    Serial.println("[sccb_read]respond for address_w..");
    sccb_send_byte(reg);//寄存器
    if(!sccb_wack())
    {
      Serial.println("[sccb_read]respond for resID..");
      sccb_start();//起始信号
      sccb_send_byte(address_r);//从机读取地址
      if(!sccb_wack())
      {
        Serial.println("[sccb_read]respond for address_r..");
        receive=sccb_read_byte();
        Serial.println("[sccb_read]read successfully..");
        sccb_stop();
        return receive;
      }
    } 
  } 
}

主函数如下:

void loop() 
{
  unsigned char receive=0;
  receive=sccb_read(0xf0);
  Serial.print("Camera Chip ID is:");
  Serial.println(receive,BIN);
  delay(1000);
}

所以运行主函数时,打印结果应该如下:
在这里插入图片描述
但是实际运行结果如下。sccb_wack()输出了"[sccb_wack]no respond…“,证明该函数返回值是1,所以sccb_read()三个if的判断条件都为0,不应该输出”[sccb_read]respond for address_w…“、”[sccb_read]respond for resID…“、”[sccb_read]respond for address_r…“和”[sccb_read]read successfully…"。图中结果与预期不同。在这里插入图片描述
调整1:当把sccb_read()中的return放到第一个if外,如下:

unsigned char sccb_read(unsigned char reg)
{
  unsigned char receive=0;
  sccb_start();//起始信号
  sccb_send_byte(address_w);//从机写入地址
  if(!sccb_wack())
  {
    Serial.println("[sccb_read]respond for address_w..");
    sccb_send_byte(reg);//寄存器
    if(!sccb_wack())
    {
      Serial.println("[sccb_read]respond for resID..");
      sccb_start();//起始信号
      sccb_send_byte(address_r);//从机读取地址
      if(!sccb_wack())
      {
        Serial.println("[sccb_read]respond for address_r..");
        receive=sccb_read_byte();
        Serial.println("[sccb_read]read successfully..");
        sccb_stop();
        
      }
    } 
  } 
  return receive;
}

输出结果如下,可见if后的执行语句都没有执行,符合预期。
在这里插入图片描述
调整2:当把sccb_read()中的return放到第二个if外,如下:

unsigned char sccb_read(unsigned char reg)
{
  unsigned char receive=0;
  sccb_start();//起始信号
  sccb_send_byte(address_w);//从机写入地址
  if(!sccb_wack())
  {
    Serial.println("[sccb_read]respond for address_w..");
    sccb_send_byte(reg);//寄存器
    if(!sccb_wack())
    {
      Serial.println("[sccb_read]respond for resID..");
      sccb_start();//起始信号
      sccb_send_byte(address_r);//从机读取地址
      if(!sccb_wack())
      {
        Serial.println("[sccb_read]respond for address_r..");
        receive=sccb_read_byte();
        Serial.println("[sccb_read]read successfully..");
        sccb_stop();
        
      }
    } 
    return receive;
  } 
}

输出结果如下,可见此时第一个if执行了
在这里插入图片描述
调整3:当把sccb_read()中的return放到第三个if外,如下:

unsigned char sccb_read(unsigned char reg)
{
  unsigned char receive=0;
  sccb_start();//起始信号
  sccb_send_byte(address_w);//从机写入地址
  if(!sccb_wack())
  {
    Serial.println("[sccb_read]respond for address_w..");
    sccb_send_byte(reg);//寄存器
    if(!sccb_wack())
    {
      Serial.println("[sccb_read]respond for resID..");
      sccb_start();//起始信号
      sccb_send_byte(address_r);//从机读取地址
      if(!sccb_wack())
      {
        Serial.println("[sccb_read]respond for address_r..");
        receive=sccb_read_byte();
        Serial.println("[sccb_read]read successfully..");
        sccb_stop();
        
      }
      return receive;
    } 
  } 
}

输出结果如下,可见此时第一个if和第二个if执行了。
在这里插入图片描述
所以观察到的现象是,在执行语句中加入return后,即便if的判断条件为假,但是执行语句仍然会执行。
在一个在线编译C语言的网页中,没有发生这样的情况。
困惑…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值