Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
490 views
in Technique[技术] by (71.8m points)

interrupt - STM32 reading data from digimatic SPC and communication via I2C at the same time

I am working on an application running on STM32, which aims to read data from the digimatic spc protocol (mitutoyo device) and then send the data to the raspberry pi via the I2C bus. The Raspberry pi is the master on the I2C bus and the STM32 is the slave.

STM32 reads the data from the digimatic protocol in a cycle. I2C in STM32 operates over an interrupt. So when a request comes from raspberry in STM32, an interrupt is triggered and serviced immediately. The problem is that the reading of data from the digimatic is interrupted, and as soon as the program returns to where it left off before the interruption, it can read bad data.

Has anyone solved a similar problem?

Here is the code to read the data

int main(void)
{
  HAL_Init();
  SystemClock_Config();

  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_TIM2_Init();

  HAL_I2C_EnableListen_IT(&hi2c1);

  while (1)
  {
      //reading data
      RQST_LOW();
      HAL_Delay(5);
      RQST_HIGH();
      uint32_t timeout=200;

      time=0;
      TIM2->CNT=0;
      HAL_TIM_Base_Start_IT(&htim2);

      for(uint8_t i = 0; i < 13; i++ )
      {
          uint8_t k=0;
        for (uint8_t j = 0; j < 4; j++)
        {
          while(HAL_GPIO_ReadPin(DG_CLK_GPIO_Port,DG_CLK_Pin) == false && timeout>time)
          {
              time=(uint32_t)TIM2->CNT;
          }
          while( HAL_GPIO_ReadPin(DG_CLK_GPIO_Port,DG_CLK_Pin) == true && timeout>time)
          {
              time=(uint32_t)TIM2->CNT;
          }
          bitWrite(k, j, (HAL_GPIO_ReadPin(DG_DATA_GPIO_Port,DG_DATA_Pin) & 0x1));
        }
        rawdata[i] = k;
      }

      if(!(timeout>time))
      {
          aTxBuffer[0]=' ';
          aTxBuffer[1]=' ';
          aTxBuffer[2]=' ';
          aTxBuffer[3]=' ';
          aTxBuffer[4]=' ';
          aTxBuffer[5]=' ';
          aTxBuffer[6]=' ';
          aTxBuffer[7]=' ';
      }
      else
      {
          HAL_TIM_Base_Stop_IT(&htim2);
          char buf[7];
          for(int lp=0;lp<6;lp++)
          {
            buf[lp]=rawdata[lp+5]+'0';
          }
          uint64_t cur_value_int =atoi(buf);
          char buf_dec[2];
          buf_dec[0] = rawdata[11]+'0';
          decimal = atoi(buf_dec);
          float cur_value = (float)cur_value_int*(float)pow(10,-decimal);
          char buf_sign[2];
          buf_sign[0] = rawdata[4]+'0';
          int32_t temp = atoi(buf_sign);
          if(rawdata[4]==8)
          {
            cur_value = -cur_value;
          }
          char buf_unit[2];
          buf_unit[0] = rawdata[12]+'0';
          temp = atol(buf_unit);
          units = (bool)temp;
          RQST_LOW();
          HAL_Delay(50);
          float nearest = roundf(cur_value * 100) / 100;
          char array[8] = {0};
          sprintf(aTxBuffer, "%.2f", nearest);
      }
      HAL_Delay(300);
  }
}

Here is the I2C interrupt handler code

void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
{
  UNUSED(AddrMatchCode);

  if(hi2c->Instance==I2C1)
  {
      if(TransferDirection == TRANSFER_DIR_READ)
      {
          if(HAL_I2C_Slave_Seq_Receive_IT(&hi2c1, (uint8_t *)aRxBuffer, RXBUFFERSIZE, I2C_NEXT_FRAME)!=HAL_OK)
          {
              Error_Handler();
          }
      }
      else
      {
          HAL_I2C_Slave_Seq_Transmit_IT(&hi2c1, (uint8_t*)aTxBuffer, 8, I2C_LAST_FRAME);
      }
  }
}

void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c)
{
    HAL_I2C_EnableListen_IT(&hi2c1); // Restart
}

void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *I2cHandle)
{
  if (HAL_I2C_GetError(I2cHandle) != HAL_I2C_ERROR_AF)
  {
      Error_Handler();
  }
}

I will be happy for any advice

question from:https://stackoverflow.com/questions/65882669/stm32-reading-data-from-digimatic-spc-and-communication-via-i2c-at-the-same-time

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...