STM32
直播中

七上八下

8年用户 785经验值
私信 关注
[问答]

ASM330LHH使用FIFO阈值中断输出时工作异常的原因?

我使用FIFO的Continuous mode,并把FIFO的WATERMASK设置为2,然后将FIFO阈值中断路由到INT1,理论上应该每产生一组XL+GY数据,就产生一个中断,然后我就可以在中断处理函数中去读取一组XL+GY数据。实际运行发现,当产生第二次中断并读取数据后,就不再产生新的中断了。
部分代码如下:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){    if(GPIO_Pin == IMU_INT1_Pin)    {        asm330lhh_fifo_read();    }}void asm330lhh_fifo_init(ASM330LHH_FREQ freq){    /* Uncomment to configure INT 1 */    asm330lhh_pin_int1_route_t int1_route;    dev_ctx.write_reg = (stmdev_write_ptr)platform_write;    dev_ctx.read_reg = platform_read;    dev_ctx.handle =  SENSOR_BUS;    /* Check device ID */    asm330lhh_device_id_get( dev_ctx,  whoamI);    if (whoamI != ASM330LHH_ID)        while (1);    /* Restore default configuration */    asm330lhh_reset_set( dev_ctx, PROPERTY_ENABLE);    do    {        asm330lhh_reset_get( dev_ctx,  rst);    }    while (rst);    /* Start device configuration. */    asm330lhh_device_conf_set( dev_ctx, PROPERTY_ENABLE);    /* Enable Block Data Update */    asm330lhh_block_data_update_set( dev_ctx, PROPERTY_ENABLE);    /* Set full scale */    asm330lhh_xl_full_scale_set( dev_ctx, ASM330LHH_8g);    asm330lhh_gy_full_scale_set( dev_ctx, ASM330LHH_500dps);    /* Set FIFO mode to Stream mode (aka Continuous Mode) */    asm330lhh_fifo_mode_set( dev_ctx, ASM330LHH_STREAM_MODE);    /* Uncomment if interrupt generation on FIFO INT1 pin */    int1_route.int1_ctrl.int1_fifo_th = PROPERTY_ENABLE;    asm330lhh_pin_int1_route_set( dev_ctx,  int1_route);    /* Set FIFO watermark (number of unread sensor data TAG + 6 bytes     * stored in FIFO) to 2 samples     */    asm330lhh_fifo_watermark_set( dev_ctx, 2);    /* Set FIFO batch XL/Gyro ODR to freq */    /* Set Output Data Rate */    asm330lhh_fifo_xl_batch_set( dev_ctx, ASM330LHH_XL_BATCHED_AT_26Hz);    asm330lhh_fifo_gy_batch_set( dev_ctx, ASM330LHH_GY_BATCHED_AT_26Hz);    asm330lhh_xl_data_rate_set( dev_ctx, ASM330LHH_XL_ODR_26Hz);    asm330lhh_gy_data_rate_set( dev_ctx, ASM330LHH_GY_ODR_26Hz);}void asm330lhh_fifo_read(void){    asm330lhh_fifo_tag_t reg_tag;    uint8_t wmflag = 0;    uint16_t num = 0;    /* Read watermark flag */    asm330lhh_fifo_wtm_flag_get( dev_ctx,  wmflag);    if (wmflag > 0)    {        /* Read number of samples in FIFO */        asm330lhh_fifo_data_level_get( dev_ctx,  num);        while (num--)        {            /* Read FIFO tag */            asm330lhh_fifo_sensor_tag_get( dev_ctx,  reg_tag);            switch (reg_tag)            {            case ASM330LHH_XL_NC_TAG:            {                static unsigned long last_tick = 0;                memset(data_raw_acceleration.u8bit, 0x00, 3 * sizeof(int16_t));                asm330lhh_fifo_out_raw_get( dev_ctx, data_raw_acceleration.u8bit);                acceleration_mg[0] =                    asm330lhh_from_fs8g_to_mg(data_raw_acceleration.i16bit[0]);                acceleration_mg[1] =                    asm330lhh_from_fs8g_to_mg(data_raw_acceleration.i16bit[1]);                acceleration_mg[2] =                    asm330lhh_from_fs8g_to_mg(data_raw_acceleration.i16bit[2]);                /* read temperature */                memset( data_raw_temperature, 0x00, sizeof(int16_t));                asm330lhh_temperature_raw_get( dev_ctx,  data_raw_temperature);                temperature_degC = asm330lhh_from_lsb_to_celsius(data_raw_temperature);#if LOG_OUT                tx_com(tx_buffer, strlen((char const *)tx_buffer));#endif            }            break;            case ASM330LHH_GYRO_NC_TAG:            {                memset(data_raw_angular_rate.u8bit, 0x00, 3 * sizeof(int16_t));                asm330lhh_fifo_out_raw_get( dev_ctx, data_raw_angular_rate.u8bit);                angular_rate_mdps[0] =                    asm330lhh_from_fs500dps_to_mdps(data_raw_angular_rate.i16bit[0]);                angular_rate_mdps[1] =                    asm330lhh_from_fs500dps_to_mdps(data_raw_angular_rate.i16bit[1]);                angular_rate_mdps[2] =                    asm330lhh_from_fs500dps_to_mdps(data_raw_angular_rate.i16bit[2]);#if LOG_OUT                tx_com(tx_buffer, strlen((char const *)tx_buffer));#endif            }            break;            default:            {                /* Flush unused samples */                memset(dummy.u8bit, 0x00, 3 * sizeof(int16_t));                asm330lhh_fifo_out_raw_get( dev_ctx, dummy.u8bit);            }            break;            }        }    }}


回帖(1)

叹久

2024-7-22 16:54:16
ASM330LHH是一款集成了加速度计和陀螺仪的传感器,用于测量线性加速度和角速度。在使用FIFO(First In First Out,先进先出)阈值中断输出时,可能会遇到一些异常情况。根据您的描述,当产生第二次中断并读取数据后,就不再产生新的中断。以下是一些可能的原因和解决方案:

1. **中断服务例程(ISR)处理时间过长**:如果中断服务例程(如`asm330lhh_fifo_read()`)处理时间过长,可能会导致新的中断在处理旧中断时被忽略。请确保中断服务例程尽可能高效,以避免错过新的中断。

2. **FIFO阈值设置不当**:您提到将FIFO的`WATERMARK`设置为2,这意味着当FIFO中有2个数据时,就会触发中断。请确保这个设置符合您的需求,并且不会因设置过低而导致中断过于频繁。

3. **FIFO溢出**:如果FIFO中的数据显示没有被及时读取,可能会导致FIFO溢出。一旦FIFO溢出,中断可能会停止触发。请确保在中断服务例程中及时读取FIFO中的数据,并检查是否有溢出情况发生。

4. **中断路由配置错误**:请检查您的中断路由配置是否正确,确保FIFO阈值中断确实被路由到了`INT1`。

5. **硬件连接问题**:检查硬件连接是否稳定,确保`INT1`引脚与微控制器的GPIO引脚之间的连接没有问题。

6. **固件或驱动问题**:如果使用的是第三方库或驱动,请检查是否有已知的bug或问题。有时候,固件或驱动的更新可以解决这类问题。

7. **电源和时钟问题**:确保传感器的电源和时钟配置正确,因为这些问题可能会影响传感器的正常工作。

8. **传感器配置问题**:检查传感器的其他配置,如工作模式、量程等,确保它们符合您的应用需求。

9. **中断使能问题**:确保在中断服务例程结束后,重新使能中断,以便能够捕捉到新的中断。

10. **调试和日志记录**:增加调试信息和日志记录,以帮助您更好地了解中断服务例程的执行情况和中断触发的频率。

解决这些问题可能需要一些调试和实验。您可以尝试逐个排查上述可能的原因,并根据实际情况调整代码和硬件配置。如果问题仍然存在,您可能需要联系传感器的制造商或寻求专业的技术支持。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分