OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4312|回复: 0

请问Minifly 源码V1.2 是如何获取传感器数据的?

[复制链接]

9

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
184
金钱
184
注册时间
2020-9-24
在线时间
34 小时
发表于 2021-11-22 16:19:27 | 显示全部楼层 |阅读模式
1金钱
  1. /*传感器任务*/
  2. void sensorsTask(void *param)
  3. {
  4.         sensorsInit();        /*传感器初始化*/
  5.         vTaskDelay(150);
  6.         sensorsSetupSlaveRead();/*设置传感器从模式读取*/

  7.         while (1)
  8.         {
  9.                 if (pdTRUE == xSemaphoreTake(sensorsDataReady, portMAX_DELAY))
  10.                 {
  11.                         /*确定数据长度*/
  12.                         u8 dataLen = (u8) (SENSORS_MPU6500_BUFF_LEN +
  13.                                 (isMagPresent ? SENSORS_MAG_BUFF_LEN : 0) +
  14.                                 (isBaroPresent ? SENSORS_BARO_BUFF_LEN : 0));

  15.                         i2cdevRead(I2C1_DEV, MPU6500_ADDRESS_AD0_HIGH, MPU6500_RA_ACCEL_XOUT_H, dataLen, buffer);
  16.                        
  17.                         /*处理原始数据,并放入数据队列中*/
  18.                         processAccGyroMeasurements(&(buffer[0]));

  19.                         if (isMagPresent)
  20.                         {
  21.                                 processMagnetometerMeasurements(&(buffer[SENSORS_MPU6500_BUFF_LEN]));
  22.                         }
  23.                         if (isBaroPresent)
  24.                         {
  25.                                 processBarometerMeasurements(&(buffer[isMagPresent ?
  26.                                         SENSORS_MPU6500_BUFF_LEN + SENSORS_MAG_BUFF_LEN : SENSORS_MPU6500_BUFF_LEN]));
  27.                         }
  28.                        
  29.                         vTaskSuspendAll();        /*确保同一时刻把数据放入队列中*/
  30.                         xQueueOverwrite(accelerometerDataQueue, &sensors.acc);
  31.                         xQueueOverwrite(gyroDataQueue, &sensors.gyro);
  32.                         if (isMagPresent)
  33.                         {
  34.                                 xQueueOverwrite(magnetometerDataQueue, &sensors.mag);
  35.                         }
  36.                         if (isBaroPresent)
  37.                         {
  38.                                 xQueueOverwrite(barometerDataQueue, &sensors.baro);
  39.                         }
  40.                         xTaskResumeAll();
  41.                 }
  42.         }       
  43. }
复制代码


任务的流程:
  先初始化硬件I2C(Enable I2C_SENSORS error interrupts,IC DMA初始化),初始化传感器----->进入循环,等待传感器中断发送二值信号量------>得到信号量后读取传感器数据到buffer数组中---->处理buffer数据得到加速度,陀螺仪,磁力,气压等,然后把它们各自入到自己的队列中。
  1. /**
  2. * 事件中断服务函数
  3. */
  4. static void i2cdrvEventIsrHandler(I2cDrv* i2c);
  5. /**
  6. * 错误中断服务函数
  7. */
  8. static void i2cdrvErrorIsrHandler(I2cDrv* i2c);
  9. /**
  10. * DMA中断服务函数
  11. */
  12. static void i2cdrvDmaIsrHandler(I2cDrv* i2c);

  13. /**
  14. * 事件中断服务函数
  15. */
  16. static void i2cdrvDmaIsrHandler(I2cDrv* i2c)
  17. {
  18.         if (DMA_GetFlagStatus(i2c->def->dmaRxStream, i2c->def->dmaRxTCFlag)) // Tranasfer complete
  19.         {
  20.                 i2cdrvClearDMA(i2c);
  21.                 i2cNotifyClient(i2c);
  22.                 // Are there any other messages to transact?
  23.                 i2cTryNextMessage(i2c);
  24.         }
  25.         if (DMA_GetFlagStatus(i2c->def->dmaRxStream, i2c->def->dmaRxTEFlag)) // Transfer error
  26.         {
  27.                 DMA_ClearITPendingBit(i2c->def->dmaRxStream, i2c->def->dmaRxTEFlag);
  28.                 //TODO: Best thing we could do?
  29.                 i2c->txMessage.status = i2cNack;
  30.                 i2cNotifyClient(i2c);
  31.                 i2cTryNextMessage(i2c);
  32.         }
  33. }

  34. /**
  35. * 事件中断服务函数
  36. */
  37. static void i2cdrvEventIsrHandler(I2cDrv* i2c)
  38. {
  39.         uint16_t SR1;
  40.         uint16_t SR2;

  41.         // read the status register first
  42.         SR1 = i2c->def->i2cPort->SR1;

  43.         // Start bit event
  44.         if (SR1 & I2C_SR1_SB)
  45.         {
  46.                 i2c->messageIndex = 0;

  47.                 if(i2c->txMessage.direction == i2cWrite ||
  48.                 i2c->txMessage.internalAddress != I2C_NO_INTERNAL_ADDRESS)
  49.                 {
  50.                         I2C_Send7bitAddress(i2c->def->i2cPort, i2c->txMessage.slaveAddress << 1, I2C_Direction_Transmitter);
  51.                 }
  52.                 else
  53.                 {
  54.                         I2C_AcknowledgeConfig(i2c->def->i2cPort, ENABLE);
  55.                         I2C_Send7bitAddress(i2c->def->i2cPort, i2c->txMessage.slaveAddress << 1, I2C_Direction_Receiver);
  56.                 }
  57.         }
  58.         // Address event
  59.         else if (SR1 & I2C_SR1_ADDR)
  60.         {
  61.                 if(i2c->txMessage.direction == i2cWrite ||
  62.                 i2c->txMessage.internalAddress != I2C_NO_INTERNAL_ADDRESS)
  63.                 {
  64.                         SR2 = i2c->def->i2cPort->SR2;                               // clear ADDR
  65.                         // In write mode transmit is always empty so can send up to two bytes
  66.                         if (i2c->txMessage.internalAddress != I2C_NO_INTERNAL_ADDRESS)
  67.                         {
  68.                                 if (i2c->txMessage.isInternal16bit)
  69.                                 {
  70.                                         I2C_SendData(i2c->def->i2cPort, (i2c->txMessage.internalAddress & 0xFF00) >> 8);
  71.                                         I2C_SendData(i2c->def->i2cPort, (i2c->txMessage.internalAddress & 0x00FF));
  72.                                 }
  73.                                 else
  74.                                 {
  75.                                         I2C_SendData(i2c->def->i2cPort, (i2c->txMessage.internalAddress & 0x00FF));
  76.                                 }
  77.                                 i2c->txMessage.internalAddress = I2C_NO_INTERNAL_ADDRESS;
  78.                         }
  79.                         I2C_ITConfig(i2c->def->i2cPort, I2C_IT_BUF, ENABLE);        // allow us to have an EV7
  80.                 }
  81.                 else // Reading, start DMA transfer
  82.                 {
  83.                         if(i2c->txMessage.messageLength == 1)
  84.                         {
  85.                                 I2C_AcknowledgeConfig(i2c->def->i2cPort, DISABLE);
  86.                         }
  87.                         else
  88.                         {
  89.                                 I2C_DMALastTransferCmd(i2c->def->i2cPort, ENABLE); // No repetitive start
  90.                         }
  91.                         // Disable buffer I2C interrupts
  92.                         I2C_ITConfig(i2c->def->i2cPort, I2C_IT_EVT | I2C_IT_BUF, DISABLE);
  93.                         // Enable the Transfer Complete interrupt
  94.                         DMA_ITConfig(i2c->def->dmaRxStream, DMA_IT_TC | DMA_IT_TE, ENABLE);
  95.                         I2C_DMACmd(i2c->def->i2cPort, ENABLE); // Enable before ADDR clear

  96.                         __DMB();                         // Make sure instructions (clear address) are in correct order
  97.                         SR2 = i2c->def->i2cPort->SR2;    // clear ADDR
  98.                 }
  99.         }
  100.         // Byte transfer finished
  101.         else if (SR1 & I2C_SR1_BTF)
  102.         {
  103.                 SR2 = i2c->def->i2cPort->SR2;
  104.                 if (SR2 & I2C_SR2_TRA) // In write mode?
  105.                 {
  106.                         if (i2c->txMessage.direction == i2cRead) // internal address read
  107.                         {
  108.                                 /* Internal address written, switch to read */
  109.                                 i2c->def->i2cPort->CR1 = (I2C_CR1_START | I2C_CR1_PE); // Generate start
  110.                         }
  111.                         else
  112.                         {
  113.                                 i2cNotifyClient(i2c);
  114.                                 // Are there any other messages to transact? If so stop else repeated start.
  115.                                 i2cTryNextMessage(i2c);
  116.                         }
  117.                 }
  118.                 else // Reading. Shouldn't happen since we use DMA for reading.
  119.                 {
  120.                         ASSERT(1);
  121.                         i2c->txMessage.buffer[i2c->messageIndex++] = I2C_ReceiveData(i2c->def->i2cPort);
  122.                         if(i2c->messageIndex == i2c->txMessage.messageLength)
  123.                         {
  124.                                 i2cNotifyClient(i2c);
  125.                                 // Are there any other messages to transact?
  126.                                 i2cTryNextMessage(i2c);
  127.                         }
  128.                 }
  129.                 // A second BTF interrupt might occur if we don't wait for it to clear.
  130.                 // TODO Implement better method.
  131.                 while (i2c->def->i2cPort->CR1 & 0x0100) { ; }
  132.         }
  133.         // Byte received
  134.         else if (SR1 & I2C_SR1_RXNE) // Should not happen when we use DMA for reception.
  135.         {
  136.                 i2c->txMessage.buffer[i2c->messageIndex++] = I2C_ReceiveData(i2c->def->i2cPort);
  137.                 if(i2c->messageIndex == i2c->txMessage.messageLength)
  138.                 {
  139.                         I2C_ITConfig(i2c->def->i2cPort, I2C_IT_BUF, DISABLE);   // disable RXE to get BTF
  140.                 }
  141.         }
  142.         // Byte ready to be transmitted
  143.         else if (SR1 & I2C_SR1_TXE)
  144.         {
  145.                 if (i2c->txMessage.direction == i2cRead)
  146.                 {
  147.                         // Disable TXE to flush and get BTF to switch to read.
  148.                         // Switch must be done in BTF or strange things happen.
  149.                         I2C_ITConfig(i2c->def->i2cPort, I2C_IT_BUF, DISABLE);
  150.                 }
  151.                 else
  152.                 {
  153.                         I2C_SendData(i2c->def->i2cPort, i2c->txMessage.buffer[i2c->messageIndex++]);
  154.                         if(i2c->messageIndex == i2c->txMessage.messageLength)
  155.                         {
  156.                                 // Disable TXE to allow the buffer to flush and get BTF
  157.                                 I2C_ITConfig(i2c->def->i2cPort, I2C_IT_BUF, DISABLE);
  158.                         }
  159.                 }
  160.         }
  161. }
复制代码
上面这段就看不懂了????




正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-25 12:51

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表