Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/44.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Embedded 设置I2C通信_Embedded_I2c_Stm32f4_Adafruit_Nucleo - Fatal编程技术网

Embedded 设置I2C通信

Embedded 设置I2C通信,embedded,i2c,stm32f4,adafruit,nucleo,Embedded,I2c,Stm32f4,Adafruit,Nucleo,我正在尝试在核子STM32F466RE板上的两个Adafruit TOF传感器VL6180X之间建立I²C通信。我使用的是cubeMX和VS代码,也有助于x-nucleo-6180xa1上的VL6180X API,我想进行设置,以便可以分别测试这两个传感器。到目前为止,我只成功地测量了一个传感器,但当我试图将两个传感器连接到NucleoSTM32F466RE上的SHDN和GPIO时,我遇到了问题。我正试图管理一些主从操作,但我是这方面的新手,有人知道怎么做吗 我要找的是示例代码,这样我就可以看到

我正在尝试在核子STM32F466RE板上的两个Adafruit TOF传感器VL6180X之间建立I²C通信。我使用的是cubeMX和VS代码,也有助于x-nucleo-6180xa1上的VL6180X API,我想进行设置,以便可以分别测试这两个传感器。到目前为止,我只成功地测量了一个传感器,但当我试图将两个传感器连接到NucleoSTM32F466RE上的SHDN和GPIO时,我遇到了问题。我正试图管理一些主从操作,但我是这方面的新手,有人知道怎么做吗

我要找的是示例代码,这样我就可以看到它是如何实现的。这不是生产运行,而是供我在家使用。为了管理这两个TOF传感器,我一直无法找到任何代码进行研究

这是我的主要代码:

/*私有变量---------------------------------------------------------*/
I2C_手柄类型定义hi2c1;
UART_HandleTypeDef huart2;
/*用户代码开始PV*/
/*用户代码结束PV*/
/*私有函数原型-----------------------------------------------*/
无效系统时钟配置(无效);
静态void MX_GPIO_Init(void);
静态void MX_I2C1_Init(void);
静态void MX_USART2_UART_Init(void);
/*用户代码开始PFP*/
/*用户代码端PFP*/
/*专用用户代码---------------------------------------------------------*/
/*用户代码从0开始*/
无效等待毫秒(整数毫秒);
VL6180xDev,即VL6180xDev;
结构MyVL6180Dev_t BoardDevs[2]={
[0]={.DevID=0},
[1] ={.DevID=1}
};
VL6180xDev_t VL6180xDev=&BoardDevs[0];
/**
*VL6180x CubeMX F401多设备i2c实现
*/
#定义i2c_总线(&hi2c1)
#定义def_i2c_超时100
内部VL6180x_I2CWrite(VL6180xDev_t dev,uint8_t*buff,uint8_t len){
智力状态;
状态=HAL_I2C_Master_传输(I2C_总线、开发->I2cAddr、buff、len、def_I2C_超时);
如果(状态){
HAL_I2C_MspInit(&hi2c1);
}
退货状态?-1:0;
}
内部VL6180x_I2CRead(VL6180xDev_t dev,uint8_t*buff,uint8_t len){
智力状态;
状态=HAL_I2C_Master_Receive(I2C_总线、开发->I2cAddr、buff、len、def_I2C_超时);
如果(状态){
HAL_I2C_MspInit(&hi2c1);
}
退货状态?-1:0;
}
无效等待毫秒(整数毫秒){
HAL_延迟(毫秒);/*这是毫秒,因为我们将systick设置为1KHz*/
}
/*用户代码结束0*/
/**
*@简要介绍应用程序入口点。
*@retval int
*/
内部主(空)
{
/*用户代码开始1*/
#定义MAX_DEV 1
VL6180x量程数据量程[最大偏差];
智力状态;
int i;
int n_dev=1;
int PresentDevMask;
int nPresentDevs;
int presentDevices[MAX_DEV];
国际研究所;
/*用户代码结束1*/
/*微控制器配置--------------------------------------------------------*/
/*重置所有外围设备,初始化闪存接口和Systick*/
HAL_Init();
/*用户代码开始初始化*/
/*用户代码结束初始化*/
/*配置系统时钟*/
SystemClock_Config();
/*用户代码BEGIN SysInit*/
/*用户代码结束SysInit*/
/*初始化所有配置的外围设备*/
MX_GPIO_Init();
MX_I2C1_Init();
MX_USART2_UART_Init();
/*用户代码开始2*/
/*检测存在并初始化设备i2c地址*/
/*为dev[i]=0x52+(i+1)*2设置设备i2c地址*/
PresentDevMask=0;
nPresentDevs=0;
//strcpy(DisplayStr,“TLBR”);

对于(i=0;i我进入这类问题的方式如下所示

  • 从任何来源下载该传感器的Arduino库
  • 仔细阅读源文件,找出使用i2c通信的核心功能
  • 根据您的任务修改该核心函数。(实现适当的i2c调用)
  • 将修改后的头文件和源文件包含到项目中并使用它们

我解决了我的问题。您可能知道,对于一些Adafruit TOF VL6180X传感器来说,它们必须从SHDN连接到板上的GPIO。事实上,缺少的是所有传感器的重置以及这些传感器的地址设置。在找到解决方案时,我遇到的问题之一是命令顺序。需要注意的是,我们首先重置所有传感器,然后在分配它们的地址后进行设置。如果您也感兴趣,请附上对代码的更正。您可以在代码中看到if查询,该查询依赖于循环中的一个变量i,以分离两个传感器。我这样做只是为了找到它们具体的组件。有一种更聪明的方法可以做到这一点,它只是为了理解命令的顺序

请参见注释中的“我的解决方案”:


/* USER CODE BEGIN PV */
// global vars only for debugging with STMStudio
VL6180x_RangeData_t Range[MAX_DEV];
VL6180x_RangeData_t RangeDB1;
VL6180x_RangeData_t RangeDB2;

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

void WaitMilliSec(int ms);

VL6180xDev_t theVL6180xDev;
struct MyVL6180Dev_t BoardDevs[MAX_DEV] = { 
                                        [0]= { .DevID = 0 }, 
                                        [1]= { .DevID = 1 }, 
                                    };

VL6180xDev_t theVL6180xDev = &BoardDevs[0];


/**
 * VL6180x CubeMX F401 multiple device i2c implementation
 */

#define i2c_bus      (&hi2c1)
#define def_i2c_time_out 100


int VL6180x_I2CWrite(VL6180xDev_t dev, uint8_t *buff, uint8_t len) {
    int status;
    status = HAL_I2C_Master_Transmit(i2c_bus, dev->I2cAddr, buff, len, def_i2c_time_out);
    if (status) {
        HAL_I2C_MspInit(&hi2c1);
    }
    return status? -1 : 0;
}

int VL6180x_I2CRead(VL6180xDev_t dev, uint8_t *buff, uint8_t len) {
    int status;
    status = HAL_I2C_Master_Receive(i2c_bus, dev->I2cAddr, buff, len, def_i2c_time_out);
    if (status) {
        HAL_I2C_MspInit(&hi2c1);
    }

    return status? -1 : 0;
}

void WaitMilliSec(int ms) {
    HAL_Delay(ms); /* it's milli sec  cos we do set systick to 1KHz */
}



/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
  

  int status;
  int i;
  int n_dev=2;
  int PresentDevMask;
  int nPresentDevs;
  int PresentDevIds[MAX_DEV];
  int nReady;
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  // here I put all my devices under reset <<<<-------------------------RESET----- 
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_RESET);
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET);


  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */


  /* detect presence and initialize devices i2c address  */
  /*set device i2c address for dev[i] = 0x52+(i+1)*2 */
  PresentDevMask = 0;
  nPresentDevs = 0;
  //strcpy(DisplayStr,"TLBR");
  for (i = 0; i <= n_dev - 1; i++) {
      int FinalI2cAddr;
      uint8_t id;
      // here I put all my devices under set <<<<-------------------------SET-----
      if (i==0){
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_SET);
      }
      if (i==1){
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_SET);
      }
      /* unreset device that wake up at default i2c addres 0x52 */
      WaitMilliSec(2);    /* at least 400usec before to acces device */
      BoardDevs[i].I2cAddr = 0x52;
      /* to detect device presence try to read it's dev id */
      status = VL6180x_RdByte(&BoardDevs[i], IDENTIFICATION_MODEL_ID, &id);
      if (status) {
          /* these device is not present skip init and clear it's letter on string */
          /*we can add here some debug prints*/
          //BoardDevs[i].Present = 0;
          //DisplayStr[i]=' ';
          continue;
      }
      /* device present only */
      BoardDevs[i].Present = 1;
      PresentDevMask |= 1 << i;
      PresentDevIds[nPresentDevs]=i;
      nPresentDevs++;
      status = VL6180x_InitData(&BoardDevs[i]);

      FinalI2cAddr = 0x52 + ((i+1) * 2);
      if (FinalI2cAddr != 0x52) {
          status = VL6180x_SetI2CAddress(&BoardDevs[i], FinalI2cAddr);
          if( status ){
              //HandleError("VL6180x_SetI2CAddress fail");
          }
          BoardDevs[i].I2cAddr = FinalI2cAddr;
      }

      WaitMilliSec(1);
      status = VL6180x_RdByte(&BoardDevs[i], IDENTIFICATION_MODEL_ID, &id);
      WaitMilliSec(1);
      status= VL6180x_Prepare(&BoardDevs[i]);
      if( status<0 ){
          //HandleError("VL6180x_Prepare fail");
      }
      /* Disable Dmax computation */
      VL6180x_DMaxSetState(&BoardDevs[i], 0);

    }
    
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    VL6180xDev_t dev;
    
    // kick off measure on all device 
    for( i=0; i<nPresentDevs; i++){
        dev =  BoardDevs + PresentDevIds[i];
        status = VL6180x_RangeStartSingleShot(dev);
        if( status<0 ){
            //TODO: print error : debug
        }
        dev->Ready=0;
    }

    // wait for all present device to have a measure  
    nReady=0;
    
    do{
        //DISP_ExecLoopBody();
        for( i=0; i<nPresentDevs; i++){
            dev =  BoardDevs + PresentDevIds[i];
            if( !dev->Ready ){
                status = VL6180x_RangeGetMeasurementIfReady(dev, &Range[i]);
                if (i==0)
                  RangeDB1 = Range[i];
                if (i==1)
                  RangeDB2 = Range[i];
                if( status == 0 ){
                    if(Range[i].errorStatus == DataNotReady)
                        continue;
                    // New measurement ready 
                    dev->Ready=1;
                    nReady++;
                } else {
                    //HandleError("VL6180x_RangeStartSingleShot fail");
                }
            }
        }
    }
    while( nReady<nPresentDevs);
    
    HAL_Delay(10);
      
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}