【 ST NUCLEO-H743ZI测评】+ LIS25BA数据采集
[复制链接]
本帖最后由 sylar^z 于 2020-5-24 00:36 编辑
这是在EE之前的活动中获得的ST骨振动传感器板子,可以采集说话时通过骨头震动传递的音频信号,不受环境中其他声源的影响。具体可以参看论坛的帖子(http://bbs.eeworld.com.cn/thread-1080360-1-1.html)。
在之前活动中,我分享过一篇基于NUCLEO-F767ZI的LIS25BA骨振动传感器数据采集帖(http://bbs.eeworld.com.cn/thread-1089664-1-1.html),部分说明性内容这里不再复述了。本帖介绍一下NUCLEO-H743ZI设置LIS25BA骨振动传感器参数、基于SAI采集LIS25BA骨振动传感器具体实现。
控制通信部分,通过STM32CubeMX开启I2C1,配置为Fast Mode,速度为400Khz,其他默认。为了便于接线,将I2C1_SCL从默认的PB6调整为PB8,I2C1_SDA为PB9,可以在STM32CubeMX的pinout view界面直接点击引脚修改。
数据采集选用了SAI1_A,NUCLEO-H743ZI将SAI1的统一引出到CN9上,连接很方便。开启SAI1_A的DMA传输,选了DMA2 Stream1,并使能DMA中断。
关于LIS25BA骨振动传感器的数据采集时钟要求,在之前的帖子已经介绍过了。这里说一下H743ZI和F767ZI的SAI在这个应用中的不同之处。由于F767ZI的SAI中MCLK与FCLK的频率之间固定为256倍,使得F767ZI无法只是用一个SAI单独实现对LIS25BA骨振动传感器的数据采集。H743ZI则通过增加了一个OSR位,通过OSR位可以配置MCLK与FCLK的频率之间固定为256倍或512倍。MCLK频率为FCLK频率512倍刚好满足LIS25BA骨振动传感器24KHz采集时的始终要求。故H743ZI单个SAI就可以采集LIS25BA的数据。
LIS25BA骨振动传感器参数配置代码:
int32_t LIS25BA_Init()
{
uint8_t ret = LIS25BA_OK;
uint8_t id;
lis25ba_tmd_ctrl_t tmd_ctrl;
lis25ba_ctrl_t ctrl;
if(BSP_I2C1_ReadReg(LIS25BA_I2C_ADDRESS, LIS25BA_WHO_AM_I, &id, 1) != LIS25BA_OK)
{
return LIS25BA_ERROR;
}
if(LIS25BA_ID != id)
{
return LIS25BA_ERROR;
}
tmd_ctrl.not_used_01 = 0x0;
tmd_ctrl.WCLK_fq = 0x1;
tmd_ctrl.not_used_02 = 0x0;
tmd_ctrl.mapping = 0x1;
tmd_ctrl.data_valid = 0x0;
tmd_ctrl.Delayed = 0x0;
tmd_ctrl.TDM_pd = 0x0;
if(BSP_I2C1_WriteReg(LIS25BA_I2C_ADDRESS, LIS25BA_TDM_CTRL, (uint8_t *)&tmd_ctrl, 1) != LIS25BA_OK)
{
return LIS25BA_ERROR;
}
ctrl.not_used_01 = 0x0;
ctrl.PD = 0x0;
ctrl.not_used_02 = 0x0;
if(BSP_I2C1_WriteReg(LIS25BA_I2C_ADDRESS, LIS25BA_CTRL, (uint8_t *)&ctrl, 1) != LIS25BA_OK)
{
return LIS25BA_ERROR;
}
return ret;
}
LIS25BA骨振动传感器数据采集SAI初始化配置代码。其中红色字体代码为手动添加,用于设置OSR位。
static void MX_SAI1_Init(void)
{
/* USER CODE BEGIN SAI1_Init 0 */
/* USER CODE END SAI1_Init 0 */
/* USER CODE BEGIN SAI1_Init 1 */
hsai_BlockA1.Init.MckOverSampling = SAI_MCK_OVERSAMPLING_ENABLE;
/* USER CODE END SAI1_Init 1 */
hsai_BlockA1.Instance = SAI1_Block_A;
hsai_BlockA1.Init.AudioMode = SAI_MODEMASTER_RX;
hsai_BlockA1.Init.Synchro = SAI_ASYNCHRONOUS;
hsai_BlockA1.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;
hsai_BlockA1.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
hsai_BlockA1.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY;
hsai_BlockA1.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_22K;
hsai_BlockA1.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
hsai_BlockA1.Init.MonoStereoMode = SAI_STEREOMODE;
hsai_BlockA1.Init.CompandingMode = SAI_NOCOMPANDING;
if (HAL_SAI_InitProtocol(&hsai_BlockA1, SAI_I2S_STANDARD, SAI_PROTOCOL_DATASIZE_16BIT, 8) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SAI1_Init 2 */
/* USER CODE END SAI1_Init 2 */
}
开启、关闭LIS25BA骨振动传感器DMA数据采集功能。LIS25BA_AUDIO_IN_Record传入的指针地址和空间大小即DMA接收的数据缓冲区空间。
void LIS25BA_AUDIO_IN_Record(uint8_t* pbuf, uint16_t size)
{
/* 开启 SAI1 BLOCK A外设 */
// HAL_SAI_Receive_DMA(&hsai_BlockA2, dataTmp, SAI2_DATA_LEN);
HAL_SAI_Receive_DMA(&hsai_BlockA1, pbuf, size);
}
uint8_t BSP_LIS25BA_AUDIO_IN_Stop(void)
{
/* 禁能 SAI1 BLOCK A外设 */
__HAL_SAI_DISABLE(&hsai_BlockA1);
HAL_SAI_DMAStop(&hsai_BlockA1);
return 0;
}
DMA接收缓冲区半满及全满时中断的处理函数,具体功能待实现。
void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai)
{
if(&hsai_BlockA1 == hsai)
{
BSP_AUDIO_IN_LIS25BA_TransferComplete_CallBack();
}
}
void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai)
{
if(&hsai_BlockA1 == hsai)
{
BSP_AUDIO_IN_LIS25BA_HalfTransfer_CallBack();
}
}
根据LIS25BA骨振动传感器书册的说明及配置。将提取有效数据,提取X,Y的数据作为左右声道数据。LIS25BA骨振动传感器的数据为8SLOT,程序中配置的图7模式。
上电
程序运行后,采集到缓冲区的数据。
|