- 2025-04-14
-
回复了主题帖:
测评入围名单: ADP5091智能能量收集 电源管理评估板
已查看我的测评计划,可在活动期间内完成并发帖分享
- 2025-04-08
-
发表了主题帖:
【STM32N6570-DK评测】#6 使用cubeAI识别声音的特征
1 概述
本部分的评测是使用cubeAI识别声音的特征。这个部分是在双麦克风录音测试的替代项目,相对于单麦克风,其实采用PCM格式输出的采样音频数据,是分为单声道mono和双声道stereo的配置的,单声道的数据是连续的,但是双声道在数据流上分为交替左右声道,在播放的时候也是需要预读取到缓存,然后线性同步输出的,因为时间间隔小,听觉效果能够满足要求。
所以,就代码的评测而言,其实差别不大。
编译通过后,采集的信号,回放的playback可以直接输入录音装置中,录制成标准音频文件。
[localvideo]c4da4827e02a3289ac7e0f4fa324cd74[/localvideo]
2 代码分析
2.1 功能描述
这个范例代码执行语音采样,预处理,然后送入NPU按照onnx的模型进行特征提取,识别声音的特征。
特征识别可以用直接polling也可以用RTOS来执行,这里选择baremetal硬编程。范例使用的RTOS是threadX,这个和freeRTOS类似,不过好像需要授权费才能使用的。
#ifdef APP_BARE_METAL
#define APP_CONF_STR "Bare Metal"
#else
#define APP_CONF_STR "RTOS"
#endif
2.2 音频捕捉
首先配置音频采集的有关结构体和函数
#define PLAYBACK_BUFFER_SIZE (PATCH_LENGTH*4)
typedef struct _AudioBM_play_back_t
{
AudioCapture_ring_buff_t ring_buff;
uint32_t cnt;
}AudioBM_play_back_t;
typedef struct _AudioBM_acq_t
{
int16_t acq_buf[CAPTURE_BUFFER_SIZE];
AudioCapture_ring_buff_t ring_buff;
uint32_t cnt;
}AudioBM_acq_t;
typedef struct _AudioBM_proc_t
{
int16_t proc_buff[PATCH_LENGTH];
int16_t audio_out[PATCH_LENGTH];
AudioPreProcCtx_t audioPreCtx;
AudioPostProcCtx_t audioPostCtx;
#if (CTRL_X_CUBE_AI_AUDIO_OUT==COM_TYPE_HEADSET)
AudioBM_play_back_t audioPlayBackCtx;
#endif
AIProcCtx_t aiCtx;
int8_t * ai_in_ptr;
const LL_Buffer_InfoTypeDef * ai_out_ptr;
uint32_t cnt;
}AudioBM_proc_t;
extern void init_bm(void);
extern void exec_bm(void);
extern void displaySystemSetting(void);
extern bool audio_process(AudioBM_acq_t * acq_ctx_ptr,\
AudioBM_proc_t * proc_ctx_ptr);
extern void initAudioCapture(AudioBM_acq_t *ctx_ptr);
extern void startAudioCapture(AudioBM_acq_t * ctx_ptr);
extern void stopAudioCapture(void);
extern void initAudioProc(AudioBM_proc_t * ctx_ptr);
extern void AudioCapture_half_buf_cb(AudioCapture_ring_buff_t *pHdle,\
int16_t *pData, uint8_t half_buf);
extern void printInferenceResults(const LL_Buffer_InfoTypeDef* pBuffRes);
extern void toggle_audio_proc(void);
#if (CTRL_X_CUBE_AI_AUDIO_OUT==COM_TYPE_HEADSET)
extern void stopAudioPlayBack(void);
随后主程序根据选择直接进入exec_bm()
int main(void)
{
init_bm();
#ifdef APP_BARE_METAL
exec_bm();
#else
tx_kernel_enter();
#endif
}
该函数直接进入音频处理loop
void exec_bm(void)
{
bool cont = true;
initAudioProc(&audio_proc_ctx);
initAudioCapture(&audio_acq_ctx);
startAudioCapture(&audio_acq_ctx);
my_printf("\r\n------------- Start Processing -------------------\r\n\n");
while(cont)
{
__NOP(); /* to be resilient to gcc optim ... to investigate */
#ifdef APP_LP
HAL_SuspendTick();
HAL_PWR_EnterSLEEPMode(0, PWR_SLEEPENTRY_WFI);
HAL_ResumeTick();
#endif /* APP_LP */
if (audio_acq_ctx.ring_buff.availableSamples >= AUDIO_ACQ_LEN)
{
cont = audio_process(&audio_acq_ctx,&audio_proc_ctx);
}
}
stopAudioCapture();
#if (CTRL_X_CUBE_AI_AUDIO_OUT==COM_TYPE_HEADSET)
stopAudioPlayBack();
#endif
test_dump();
my_printf("\n\r-------------- End Processing --------------------\n\r\n\r");
}
在audio_process()中实现采样和特征提取。
2.3 特征识别
bool audio_process(AudioBM_acq_t * acq_ctx_ptr,AudioBM_proc_t * proc_ctx_ptr)
{
uint8_t *proc_buf = (uint8_t *) proc_ctx_ptr->proc_buff;
uint8_t *proc_buf_ovl = (uint8_t *) (&proc_ctx_ptr->proc_buff[AUDIO_ACQ_LEN]);
uint8_t *acq_buf = (uint8_t *) (&proc_ctx_ptr->proc_buff[AUDIO_ACQ_OFFSET]);
bool cont = true;
/* prepare overlapping samples from previous patch */
memcpy(proc_buf,proc_buf_ovl,AUDIO_ACQ_OFFSET*sizeof(int16_t));
/* Audio samples acquisition */
AudioCapture_ring_buff_consume(acq_buf,&acq_ctx_ptr->ring_buff,AUDIO_ACQ_LEN);
/* Audio pre processing */
PreProc_DPU(&proc_ctx_ptr->audioPreCtx, proc_buf, proc_ctx_ptr->ai_in_ptr );
/* AI processing */
AiDPUProcess(&proc_ctx_ptr->aiCtx);
#if (CTRL_X_CUBE_AI_POSTPROC==CTRL_AI_ISTFT)
PostProc_DPU(&proc_ctx_ptr->audioPostCtx,
proc_ctx_ptr->audioPreCtx.pCplxSpectrum,
(float32_t *) LL_Buffer_addr_start(proc_ctx_ptr->ai_out_ptr),
proc_ctx_ptr->audio_out);
#endif
#if (CTRL_X_CUBE_AI_AUDIO_OUT==COM_TYPE_HEADSET)
int16_t * audioPtr = (AudioProcIsOn) ?
&proc_ctx_ptr->audio_out[AUDIO_OUT_FIRST] : (int16_t *)acq_buf ;
AudioPlayBack(&proc_ctx_ptr->audioPlayBackCtx, audioPtr , AUDIO_ACQ_LEN);
#endif
BSP_LED_Toggle(LED_GREEN);
return cont;
}
上述代码逻辑很清楚,是循环执行的。
其中在数据分块切片等预处理之后,执行识别的是
/* AI processing */
AiDPUProcess(&proc_ctx_ptr->aiCtx);
这句就是直接调用NPU,把memcpy复制进去的音频数据切片依次输入NPU,结合ONNX模型和参数,进行计算得出数据分类特征,直接输出结果。
具体涉及AI的部分包括AI模型训练和基于cubeAI的模型部署,具体需要单独的专题去分析和研究。
这里的代码经过编译后顺利生成elf文件
配置run运行configuration,并找到stlink
随后执行写入
代码就可以开始执行了。
3 演示效果
这个代码运行效果在串口输出,显示如下
这里需要按照14400bps的参数配置,否则就是乱码。
这里先测试硬件的主频以及采用NPU的主频,随后列出所采用模型的结构,
然后就进入处理过程,不断采集声音传感器的采样数据,切片进入buff缓存,经过预处理后导入NPU内进行数据处理,输出特征。
按照readme的格式,识别特征后就按照分类识别并输出类别特征,如钟表的滴答声就输出如下
使用这个代码,首先需要配置两个fuse参数为高,否则不能正确执行NPU
-VDDIO2_HSLV=1 I/O XSPIM_P1 High speed option enabled
- VDDIO3_HSLV=1 I/O XSPIM_P2 High speed option enabled
然后选择两个模型之一,一个是语音类别识别aed,另一个是语音增强se
模型和参数分别是两个bin文件,需要和程序代码的bin文件同时写入内存,才能正确执行本程序。
模型的训练和部署需要cubeAI的支持,这里只采用modelzoo的模型和参数进行测试。
4 总结
本次评测主要围绕音频录制和处理进行。音频捕捉,是通过mdf驱动来读取声音传感器的数据,probe探测并采样,随后可进行简单的带通滤波,也可以引入AI模型进行边缘智能计算,NPU支持的效果比较理想,速度快精度够用,最后,可以通过SAI输出到音频输出口。这个音频输出支持双声道,而且从MCU的角度,也支持双麦克的立体声采样。
STM32N6570-DK提供一个快速掌握和快速部署的评测开发板,展现了比较强大的功能。是一个入手边缘计算的首选工具。
-
回复了主题帖:
【STM32N6570-DK评测】#5 音频降噪和滤波测试
Jacktang 发表于 2025-4-8 07:30
源代码配置的声音可以比较清晰的重现,虽然评测效果用视频显示不是很直观,但还是有效果的
确实。
应该这么讲,经过测试,使用滤波函数配置后,声音降噪效果比较好。
随后,补上一个声音测试的视频,用手机录音机的显示部分展示一下效果。
- 2025-04-07
-
发表了主题帖:
【STM32N6570-DK评测】#5 音频降噪和滤波测试
本帖最后由 北方 于 2025-4-8 09:31 编辑
1 概述
前面的帖子已经描述了如何控制音频及录制。在原来的计划中有如何处理音频及降噪的方法,这个通常是用一个通道计算实现的,动态计算平均采集的声压水平,然后进行频率分解,对于地赋值的杂散频率进行直接抑制,只留下幅值比较高的频率组合,这样通常可以滤掉杂散噪音,但是同时也会使声音的深度和通透度大打折扣。这个方法对于语音降噪还是比较理想的,因为干巴巴的声音辨识度更高。
但是,经过代码分析,STM32N6570-DK的处理方法可以更简单,直接利用对于数字麦克风的过滤参数进行配置就可以简单实现降噪。其原理使使用带通抑制器,对于高频的低频的直接进行抑制,可以实现简单降噪。低频的声音多是杂散环境噪音,但是总体音量大,对于听力影响不大,但是杂散高频,听觉效果影响比较大,用带通抑制,效果比较好。
2 具体实现的代码
2.1 数字麦克风初始控制函数解析。主要是xxxx_hal_mdf.c代码中定义的.
在范例代码中是使用DMA控制实现的,其实还可以用轮询和中断控制的方法,也在下面介绍一下
2.1.1 *** 初始化和去初始化 ***
用户必须首先初始化 MDF 或 ADF 实例。
(#) 作为前提条件,填写 HAL_MDF_MspInit():
(++) 使用 __HAL_RCC_MDFz_CLK_ENABLE() 启用 MDFz 或 ADFz 时钟接口。
或 __HAL_RCC_ADFz_CLK_ENABLE() 启用 MDFz 或 ADFz 时钟接口。
(++) 通过__HAL_RCC_GPIOx_CLK_ENABLE()启用所用 GPIOS 的时钟。
(++) 使用 HAL_GPIO_Init()将这些引脚配置为交替模式。
(++) 如果使用中断模式,则应使用 HAL_NVPIO_Init() 启用和配置 MDFz_FLTx 或 ADFz
使用 HAL_NVIC_SetPriority() 和 HAL_NVIC_EnableIRQ() 启用和配置 MDFz_FLTx 或 ADFz 中断。
(++) 如果使用 DMA 模式,则初始化和配置 DMA。
(#) 配置常用参数(仅适用于第一个 MDF 或 ADF 实例初始化)、
通过调用
函数 HAL_MDF_Init()。
(#) 用户可以使用 HAL_MDF_DeInit() 函数取消初始化 MDF 或 ADF 实例。
2.1.2 *** 获取 ***
(#) 使用 HAL_MDF_AcqStart()配置滤波器参数并开始采集、
HAL_MDF_AcqStart_IT() 或 HAL_MDF_AcqStart_DMA()。
(#) 在轮询模式下 :
(++) 使用 HAL_MDF_PollForAcq() 检测采集结束。
使用 HAL_MDF_GetAcqValue 获取采集值。
(++) 仅对于 MDF 实例,使用 HAL_MDF_PollForSnapshotAcq() 来检测快照获取的结束。
快照获取结束。
使用 HAL_MDF_GetSnapshotAcqValue 获取快照获取值。
(++) 仅对于 ADF 实例,使用 HAL_MDF_PollForSndLvl()检测并获取
新声级值和环境噪声值。
(++) 仅针对 ADF 实例,使用 HAL_MDF_PollForSad() 检测声音活动。
(#) 在中断模式下 :
(++) HAL_MDF_AcqCpltCallback() 会在采集结束时被调用。
使用 HAL_MDF_GetAcqValue 获取采集值或使用
HAL_MDF_GetSnapshotAcqValue 获取快照采集值。
(++) 仅对于 ADF 实例,当有新的声级和环境噪声值时,将调用 HAL_MDF_SndLvlCallback()。
声级和环境噪声值可用时,将调用 HAL_MDF_SndLvlCallback()。
(++) 仅针对 ADF 实例,当发生声音活动检测时,将调用 HAL_MDF_SadCallback()。
声音活动检测发生时,将调用 HAL_MDF_SadCallback()。
(++) 如果发生溢出、过滤器超限或饱和,将调用 HAL_MDF_ErrorCallback()。
饱和时,将调用 HAL_MDF_ErrorCallback()。
使用 HAL_MDF_GetErrorCode() 获取相应的错误信息。
(#) 在 DMA 模式下 :
(++) HAL_MDF_AcqHalfCpltCallback() 和 HAL_MDF_AcqCpltCallback() 将分别在半采集和全采集时调用。
分别在半采集和采集完成时调用。
(++) 只有在 ADF 实例中,当有新的声级和环境噪声值时,才会调用 HAL_MDF_SndLvlCallback()。
声级和环境噪声值可用时,将调用 HAL_MDF_SndLvlCallback()。
(++) 只有在 ADF 实例中,当发生声音活动检测时,才会调用 HAL_MDF_SadCallback()。
声音活动检测发生时,将调用 HAL_MDF_SadCallback()。
(++) 如果发生溢出、滤波器超限、饱和或 DMA 错误,将调用 HAL_MDF_ErrorCallback()、
饱和或 DMA 错误发生时,将调用 HAL_MDF_ErrorCallback()。
使用 HAL_MDF_GetErrorCode() 获取相应的错误信息。
(#) 使用 HAL_MDF_GenerateTrgo() 在 TRGO 信号上生成脉冲。
(#) 在采集过程中,使用 HAL_MDF_SetDelay() 和 HAL_MDF_GetDelay() 分别设置和获取数据源的延迟。
设置和获取数据源的延迟。
(#) 在采集过程中,使用 HAL_MDF_SetGain() 和 HAL_MDF_GetGain() 分别设置和获取滤波器增益。
设置和获取滤波器增益。
(#) 在采集过程中,使用 HAL_MDF_SetOffset() 和 HAL_MDF_GetOffset() 分别设置和获取滤波器偏移误差补偿。
设置和获取滤波器偏移误差补偿。
(#) 在采集期间,仅对于 MDF 实例,使用 HAL_MDF_SetOffset() 和 HAL_MDF_GetOffset()
分别设置和获取滤波器偏移误差补偿。
(#) 使用 HAL_MDF_AcqStop()、HAL_MDF_AcqStop_IT() 或 HAL_MDF_AcqStop_DMA() 停止采集。
2.2 滤波器配置,主要是对于如下配置进行配置,其实就是MDF滤波配置,MdfFilterconfig
配置的参数包括,延时,偏移,放大系数,高通滤波,整形滤波等,还KWS语音激活的配置,也就是只有外部声音超过阈值才开始记录采样。
这么多复杂的功能,一键实现。
/** MdfFilterConfig0, MdfOldConfig0 and/or MdfScdConfig0 structures initialization */
MdfFilterConfig0.DataSource = MDF_DATA_SOURCE_BSMX;
MdfFilterConfig0.Delay = 0;
MdfFilterConfig0.CicMode = MDF_ONE_FILTER_SINC4;
MdfFilterConfig0.DecimationRatio = 32;
MdfFilterConfig0.Offset = 0;
MdfFilterConfig0.Gain = 14;
MdfFilterConfig0.ReshapeFilter.Activation = ENABLE;
MdfFilterConfig0.ReshapeFilter.DecimationRatio = MDF_RSF_DECIMATION_RATIO_4;
MdfFilterConfig0.HighPassFilter.Activation = ENABLE;
MdfFilterConfig0.HighPassFilter.CutOffFrequency = MDF_HPF_CUTOFF_0_000625FPCM;
MdfFilterConfig0.Integrator.Activation = DISABLE;
MdfFilterConfig0.SoundActivity.Activation = DISABLE;
MdfFilterConfig0.AcquisitionMode = MDF_MODE_ASYNC_CONT;
MdfFilterConfig0.FifoThreshold = MDF_FIFO_THRESHOLD_NOT_EMPTY;
MdfFilterConfig0.DiscardSamples = 0;
然后在xxxx_hal_mdf.h中对于环境噪声的控制有原始的配置,对于不同的噪声范围内形成明确的定义,对于不同的环境声级下,配置不同的信噪比数值
/** @defgroup MDF_SadSignalNoiseThreshold MDF sound activity detector data signal to noise threshold
* @{
*/
#define MDF_SAD_SIGNAL_NOISE_3_5DB 0x00000000U /*!< Signal to noise threshold is 3.5dB */
#define MDF_SAD_SIGNAL_NOISE_6DB MDF_SADCFGR_SNTHR_0 /*!< Signal to noise threshold is 6dB */
#define MDF_SAD_SIGNAL_NOISE_9_5DB MDF_SADCFGR_SNTHR_1 /*!< Signal to noise threshold is 9.5dB */
#define MDF_SAD_SIGNAL_NOISE_12DB (MDF_SADCFGR_SNTHR_0 | \
MDF_SADCFGR_SNTHR_1) /*!< Signal to noise threshold is 12dB */
#define MDF_SAD_SIGNAL_NOISE_15_6DB MDF_SADCFGR_SNTHR_2 /*!< Signal to noise threshold is 15.6dB */
#define MDF_SAD_SIGNAL_NOISE_18DB (MDF_SADCFGR_SNTHR_0 | \
MDF_SADCFGR_SNTHR_2) /*!< Signal to noise threshold is 18dB */
#define MDF_SAD_SIGNAL_NOISE_21_6DB (MDF_SADCFGR_SNTHR_1 | \
MDF_SADCFGR_SNTHR_2) /*!< Signal to noise threshold is 21.6dB */
#define MDF_SAD_SIGNAL_NOISE_24_1DB (MDF_SADCFGR_SNTHR_0 | \
MDF_SADCFGR_SNTHR_1 | \
MDF_SADCFGR_SNTHR_2) /*!< Signal to noise threshold is 24.1dB */
#define MDF_SAD_SIGNAL_NOISE_27_6DB MDF_SADCFGR_SNTHR_3 /*!< Signal to noise threshold is 27.6dB */
#define MDF_SAD_SIGNAL_NOISE_30_1DB (MDF_SADCFGR_SNTHR_0 | \
MDF_SADCFGR_SNTHR_3) /*!< Signal to noise threshold is 30.1dB */
这样就可以一键搞定。
3 实现的效果
这里的实现效果还是很好的,基本上通过源代码配置的声音可以比较清晰的重现,外部的敲击等噪音不是很大了。这里选择的代码还是上帖子提到的代码,对于音频滤波就是重新理解和配置参数。
4 小结
到这里的测速是基于代码分析,并不需要做很复杂的操作和测试。在这里单独拉出一个帖子是因为这个是当初的评测计划的一部分,所以独立出来详细说一下,在此解释一下。评测效果用视频显示不是很直观。下一贴想个办法图形化一下。
至此,主要的几个规定测试动作基本完成,功耗测量,音频视频录制播放,音频滤波。原计划中还有双麦克风评测,因为没有配套提供,而且也没有在T宝上找到专门采购的页面,所以这个评测就不好完成了。不过,还是抽时间加一个对于音频后处理的测试。在随后的帖子中分析一下。
5 补充视频
[localvideo]4903110daedbda82307a09136d95c622[/localvideo]
这个视频是把环境采集的音频用SAI输出到手机的音频采集口,使用录音机应用程序录制,这个每当发出比较大的敲击,就同步显示录音的音高,背景噪音的幅值也稳定输出,看书控制在比较小的范围。
-
回复了主题帖:
【STM32N6570-DK评测】#3 录制视频并显示
flytianya2010 发表于 2025-4-7 08:54
感谢楼主,学习了,可以提供一下源码吗?我也正在学习中,想复现一下您的这个功能。
st源码大多开源,在官网的范例程序中可以找到,读懂逻辑稍微修改一下就可以展示。
st源码包括自有的库,比较大,一般都超过了上传的限制了。
- 2025-04-03
-
发表了主题帖:
【STM32N6570-DK评测】#4 录制音频并播放
1 概述
STM32N6570-DK是一个功能强大的开发板,具有丰富的多媒体外设,在上一篇测试视频录制和播放后,再一样画瓢录制音频并播放。
2 录音功能和播放功能
2.1 这个有所不同的是,录制音频使用板载的PCM数字麦克风,播出使用SAI插口。
2.2 这次采用的是MP23DB01HP全向数字麦克风MP23DB01HP - MEMS audio sensor ,是列在ST的传感器产品里面的。这个麦克风是U13,和CN5扩展卡可以用扩展的双麦克风扩展板可以发挥相同的功能。当CN5的麦克风扩展板接入时,自动切换到CN5,同时只能使用一个,是通过自动感知引脚来区分的。
原计划还有评测双路麦克风的测试,不过,这次测试套件中没有这个STEVAL-MIC008A - Dual MP23DB01HP MEMS mic daughter board扩展板,只有一个扩展板底座,在网上也找不到,这个计划就需要调整一下,等下一篇再分析。
这个数字麦克风传感器性能比较逆天,是高灵敏度低功耗的,最低达到2uA的一个东东。双路麦克也和单路麦克一样使用相同的引脚数量,信号引脚Dout是共用的。
声音输出是I2C2 interface (100 kHz).读写地址0x34/0x35,通过SAI通道传输声音。
2.3 这个代码时钟频率设置在PCM采样频率为16KHz (2.048MHz/(32*4)),采样数据循环记录,使用loop (circular DMA)循环DMA存在PcmBuffer缓存,然后在SAI接口输出,通过解码芯片WM8904实现解码和播放。
3 代码解析
3.1 代码编译一下,顺利通过,然后下载到开发板中。
上一帖提到如何写入flash,具体这样:
找到编译后形成的Project.bin文件,执行以下语句
STM32_SigningTool_CLI.exe -bin Project.bin -nk -of 0x80000000 -t fsbl -o Project-trusted.bin -hv 2.3 -dump Project-trusted.bin
生成了Project-trusted.bin.这个二进制文件用cubeProgrammer写入到外部flash的地址 0x7000'0000,选择从flash启动则可。
前提是这些文件和工具都安装好,并配置好了环境变量。
2.2 初始化程序主要是配置标准外设以及时钟,启动DMA
MX_GPIO_Init();
MX_GPDMA1_Init();
MX_MDF1_Init();
/* USER CODE BEGIN 2 */
if (BSP_ERROR_NONE != BSP_LED_Init(LED_RED))
{
Error_Handler();
}
/* Initialize playback of recorded data */
Playback_Init();
/* Start record */
PcmHalfBufferCplt = 0;
PcmBufferCplt = 0;
dma_config.Address = (uint32_t)&PcmBuffer[0];
dma_config.DataLength = 4096U;
dma_config.MsbOnly = ENABLE;
if (HAL_MDF_AcqStart_DMA(&MdfHandle0, &MdfFilterConfig0, &dma_config) != HAL_OK)
{
Error_Handler();
}
2.3. 读取音频和播放
初始化麦克风就
static void MX_MDF1_Init(void)
{
/**
MdfHandle0 structure initialization and HAL_MDF_Init function call
*/
MdfHandle0.Instance = MDF1_Filter0;
MdfHandle0.Init.CommonParam.InterleavedFilters = 0;
MdfHandle0.Init.CommonParam.ProcClockDivider = 2;
MdfHandle0.Init.CommonParam.OutputClock.Activation = ENABLE;
MdfHandle0.Init.CommonParam.OutputClock.Pins = MDF_OUTPUT_CLOCK_0;
MdfHandle0.Init.CommonParam.OutputClock.Divider = 12;
MdfHandle0.Init.CommonParam.OutputClock.Trigger.Activation = DISABLE;
MdfHandle0.Init.SerialInterface.Activation = ENABLE;
MdfHandle0.Init.SerialInterface.Mode = MDF_SITF_NORMAL_SPI_MODE;
MdfHandle0.Init.SerialInterface.ClockSource = MDF_SITF_CCK0_SOURCE;
MdfHandle0.Init.SerialInterface.Threshold = 31;
MdfHandle0.Init.FilterBistream = MDF_BITSTREAM0_FALLING;
if (HAL_MDF_Init(&MdfHandle0) != HAL_OK)
{
Error_Handler();
}
/**
MdfFilterConfig0, MdfOldConfig0 and/or MdfScdConfig0 structures initialization
WARNING : only structures are filled, no specific init function call for filter
*/
MdfFilterConfig0.DataSource = MDF_DATA_SOURCE_BSMX;
MdfFilterConfig0.Delay = 0;
MdfFilterConfig0.CicMode = MDF_ONE_FILTER_SINC4;
MdfFilterConfig0.DecimationRatio = 32;
MdfFilterConfig0.Offset = 0;
MdfFilterConfig0.Gain = 14;
MdfFilterConfig0.ReshapeFilter.Activation = ENABLE;
MdfFilterConfig0.ReshapeFilter.DecimationRatio = MDF_RSF_DECIMATION_RATIO_4;
MdfFilterConfig0.HighPassFilter.Activation = ENABLE;
MdfFilterConfig0.HighPassFilter.CutOffFrequency = MDF_HPF_CUTOFF_0_000625FPCM;
MdfFilterConfig0.Integrator.Activation = DISABLE;
MdfFilterConfig0.SoundActivity.Activation = DISABLE;
MdfFilterConfig0.AcquisitionMode = MDF_MODE_ASYNC_CONT;
MdfFilterConfig0.FifoThreshold = MDF_FIFO_THRESHOLD_NOT_EMPTY;
MdfFilterConfig0.DiscardSamples = 0;
}
循环播放如下初始化函数实现
static void Playback_Init(void)
{
/* Probe the audio codec */
WM8904_Probe();
/* Initialize SAI peripheral */
MX_SAI1_Init();
/* Initialize audio codec */
WM8904_Init_t codec_init;
codec_init.InputDevice = WM8904_IN_NONE;
codec_init.OutputDevice = WM8904_OUT_HEADPHONE;
codec_init.Resolution = WM8904_RESOLUTION_16B;
codec_init.Frequency = WM8904_FREQUENCY_16K;
codec_init.Volume = 80U;
if (Audio_Drv->Init(Audio_CompObj, &codec_init) < 0)
{
Error_Handler();
}
if (Audio_Drv->Play(Audio_CompObj) != 0)
{
Error_Handler();
}
}
音频的读取用如下probe探测函数wm8904
static void WM8904_Probe(void)
{
WM8904_IO_t IOCtx;
uint32_t wm8904_id;
static WM8904_Object_t WM8904Obj;
/* Configure the audio driver */
IOCtx.Address = 0x34U;
IOCtx.Init = BSP_I2C2_Init;
IOCtx.DeInit = BSP_I2C2_DeInit;
IOCtx.ReadReg = BSP_I2C2_ReadReg;
IOCtx.WriteReg = BSP_I2C2_WriteReg;
IOCtx.GetTick = BSP_GetTick;
if (WM8904_RegisterBusIO(&WM8904Obj, &IOCtx) != WM8904_OK)
{
Error_Handler();
}
else if (WM8904_ReadID(&WM8904Obj, &wm8904_id) != WM8904_OK)
{
Error_Handler();
}
else if ((wm8904_id & WM8904_ID_MASK) != WM8904_ID)
{
Error_Handler();
}
else
{
Audio_Drv = (AUDIO_Drv_t *) &WM8904_Driver;
Audio_CompObj = &WM8904Obj;
}
}
音频 播放很简单,就是不断把DMA的数据传送到SAI
if (HAL_OK != HAL_SAI_Transmit_DMA(&hsai_BlockA1, (uint8_t *) &PcmBuffer[0], 2048U))
{
Error_Handler();
}
4 小结
这个播放的效果是用耳机就可以直接听到,外放音箱也可以,不过拍成视频效果不好,就只显示了一个过程的效果。
上述过程描述起来简单,执行也很快,不过,这个过程的复杂性不亚于视频录制和播放,都涉及到2路不同的外设协同工作。这个测试,使用了DMA的自动启动,所以更方便一些。
都是需要对PcmBuffer的缓存进行处理才能实现这样的功能。
-
回复了主题帖:
【STM32N6570-DK评测】#3 录制视频并显示
sipower 发表于 2025-4-2 15:15
你这个是在RAM内运行的还是在flash运行的?
都可以的。
开发过程的代码都是写入RAM的,
加上head后link一下生成新的bin文件,用cubeprogrammer写入FLASH就可以从flash运行,flash运行的本质还是要第一步从flash中拷贝代码区到RAM运行,直接在flash运行的访问速度太慢了。
- 2025-04-02
-
回复了主题帖:
【STM32N6570-DK评测】#3 录制视频并显示
jobszheng5 发表于 2025-4-2 09:53
图像来说,是不是30帧就足够了呀
这个就是模拟测试,通常最低是15fps,到了60fps就足以保证显示质量了。
-
回复了主题帖:
【STM32N6570-DK评测】#3 录制视频并显示
Jacktang 发表于 2025-4-2 07:43
图像时用缓存保存的,显示为60帧的过程还算清晰的
确实是,更大的视频通常需要去SPI flash等外部存储来存放才行。60帧缓存足够完成基本的视频处理了。
这个MCU内存还是挺够用的,再大就要上MPU了
- 2025-04-01
-
发表了主题帖:
【STM32N6570-DK评测】#3 录制视频并显示
1 概述
STM32N6570-DK具有丰富的多媒体捕捉和演示的功能,配套有摄像头,显示屏和控制按钮等。视频显示通过MIPI端口的摄像头捕捉,并且可以动态切割,变换并生成各种图片,或者叠加起来使用video格式连续演示。
这里使用巴斯光年做模特,在eeworld的背景板下展示一下。显示效果在显示屏上展示。
2 开发环境和安装
ST作为历史悠久的中国品牌,最早践行在中国服务中国的芯片厂家,作为众多n产品牌的cosplay原型,STcubeMX和STcubeIDE的安装和配置就不用多说了,不过耗时不少,配置也有很多需要更新的地方。
确实在配置和调试上花了不少时间,最终还是搞成了。
安装完以后先导入一个GPIO来闪一下灯,主要是看是否OK,这里修改一下闪灯的间隔,就可以从LED1的变化上判断是否成功
3 范例代码运行及解析
导入范例代码
这个代码先初始化LCD和imx335摄像头
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_DCMIPP_Init(void);
static void LCD_Init(uint32_t Width, uint32_t Height);
static void IMX335_Probe(uint32_t Resolution, uint32_t PixelFormat);
static ISP_StatusTypeDef GetSensorInfoHelper(uint32_t Instance, ISP_SensorInfoTypeDef *SensorInfo);
static ISP_StatusTypeDef SetSensorGainHelper(uint32_t Instance, int32_t Gain);
static ISP_StatusTypeDef GetSensorGainHelper(uint32_t Instance, int32_t *Gain);
static ISP_StatusTypeDef SetSensorExposureHelper(uint32_t Instance, int32_t Exposure);
static ISP_StatusTypeDef GetSensorExposureHelper(uint32_t Instance, int32_t *Exposure);
/* USER CODE END PFP */
... ...
MX_DCMIPP_Init();
/* Initialize the IMX335 Sensor ----------------------------- */
IMX335_Probe(IMX335_R2592_1944, IMX335_RAW_RGGB10);
然后就可以直接调用对应硬件的函数,读取60帧图片
/* Initialize the Image Signal Processing middleware */
if(ISP_Init(&hcamera_isp, &hdcmipp, 0, &appliHelpers, ISP_IQParamCacheInit[0]) != ISP_OK)
{
Error_Handler();
}
if (HAL_DCMIPP_CSI_PIPE_Start(&hdcmipp, DCMIPP_PIPE1, DCMIPP_VIRTUAL_CHANNEL0 , BUFFER_ADDRESS, DCMIPP_MODE_CONTINUOUS) != HAL_OK)
{
Error_Handler();
}
/* Start the Image Signal Processing */
if (ISP_Start(&hcamera_isp) != ISP_OK)
{
Error_Handler();
}
/* give the ISP 60 frames to set color balance */
while(NbMainFrames < 60)
{
BSP_LED_Toggle(LED_GREEN);
if (ISP_BackgroundProcess(&hcamera_isp) != ISP_OK)
{
BSP_LED_Toggle(LED_RED);
}
}
NbMainFrames = 0;
/* stop the acquisition */
HAL_DCMIPP_CSI_PIPE_Stop(&hdcmipp, DCMIPP_PIPE1, DCMIPP_VIRTUAL_CHANNEL0);
随后启动并显示在lcd屏幕上
LCD_Init(FRAME_WIDTH, FRAME_HEIGHT);
/* USER CODE END 2 */
if (HAL_DCMIPP_CSI_PIPE_Start(&hdcmipp, DCMIPP_PIPE1, DCMIPP_VIRTUAL_CHANNEL0 , BUFFER_ADDRESS, DCMIPP_MODE_SNAPSHOT) != HAL_OK)
{
Error_Handler();
}
... ...
if (HAL_DCMIPP_CSI_PIPE_Start(&hdcmipp, DCMIPP_PIPE1, DCMIPP_VIRTUAL_CHANNEL0 , BUFFER_ADDRESS, DCMIPP_MODE_SNAPSHOT) != HAL_OK)
{
Error_Handler();
}
/* Update LTDC Display window */
HAL_LTDC_SetWindowSize(&hltdc, FRAME_WIDTH/4 , FRAME_HEIGHT/4, LTDC_LAYER_1);
这样就可以完成读取图像并显示的功能,其中图像时用缓存保存的,显示为60帧的过程
4 演示效果
上述的显示效果如下,其中显示图像可以缩放,这里显示是在四分之一的角落显示的。
5 小结
通过上述的说明,可以比较简单地完成图像录制和显示的过程,完成了评测需要完成的第二个任务。如果需要更改显示缩放的范围和屏幕的显示大小,只需要对
HAL_LTDC_SetWindowSize(&hltdc, FRAME_WIDTH/4 , FRAME_HEIGHT/4, LTDC_LAYER_1);
这一句的显示更新语句进行修改就可以了。
- 2025-03-28
-
回复了主题帖:
【STM32N6570-DK评测】#1 开箱
damiaa 发表于 2025-3-27 14:43
总有一天也得搞一块玩玩。
看着效果,还是挺眩的。速度看起来也不错
- 2025-03-26
-
回复了主题帖:
【STM32N6570-DK评测】#2 不同负载下的功耗测试
sipower 发表于 2025-3-25 14:21
有没有办法刨除屏幕的功耗,单看板子的耗电量呢?
开发板上有专门的电流测量跳线,是串接入对应芯片供电回路的。
这样,需要去除对应的板载零欧姆电阻,用跳线替代。
另外,分开不同的程序,访问不同的外设,就可以测量无屏功耗了。不过,屏幕也是这个板子的一部分,测量开发板电源这个没有问题。至于芯片的功耗,肯定是很小的,在低功耗状态 ,应该是低于1mA
- 2025-03-24
-
发表了主题帖:
【STM32N6570-DK评测】#2 不同负载下的功耗测试
1 概述
本开发板提供了非常完整的出厂范例,覆盖了AI测试,音视频,文字显示等不同的状态。适宜进行不同负载下的功耗测试主要是围绕范例代码实现不同功能下的功耗和对比。
2 功耗测试方法和工具
本开发板具有3种供电模式,其中STlink供电模式同时还包括了STLINK的供电功耗,跳线到USB1供电就可以只包括核心功能的功耗测试。
测试使用微型USB电压电流表,可以检测电压和电流,适合进行本次的测试。
3 STLINK的供电功耗
连接供电在USB1,这样stliink就不对核心部分供电了。直接插在stlink检测,供电电流0.06A。这个是基础供电,也可以作为核心芯片的供电性能进行对比。
4 结合图形显示驱动的电流测量
4.1 出厂范例是一个基于各种图形的显示和控制演示,包括图片,文本,视频等显示和转换,主页面如下显示。这时的功耗从reset开始,电流为0.2A开始,最后稳定在0.40A,约2.01瓦左右。这个是例程的基础的功耗。
4.2 文字显示。
选择进入文本模式的演示,这时显示功耗略有增加,但增加很小,约0.01W的增加。但是在文本切换界面时,功耗动态增加,可以达到2.067W
4.3 图片显示
图片显示的功耗略大于文本显示,这里是svg格式的图形显示,功耗约为2.02W。
4.4 视频显示
视频显示,功耗如预期有所增加,但是增加也不多,可以到2.131W
4.5 应用展示
范例提供了两个演示,一个是电动车开锁,另一个是指南针。
其中电动车开锁明显功耗最低,达到1.95W,比较出乎意料。不过,这个应该是图形显示刷新少以文本为主的结果,控制逻辑部分功耗不大。
这个是指南针的演示,因为使用了全彩色的显示,功耗维持基本模式达到2.04W
4.6 图形加速显示
图形加速模式,是这次测试功耗最高的部分,因为启动了neoChrome加速器,所以使用了更强大的计算,显示出功耗达到2.22W
5 小结
通过上面的功耗测试,可以发现,对于不同的图形处理,功耗发生了显著的变化,其中在图形处理和变化中,获得最大的功耗。那么基础功耗始终保持在2W左右,其实也可以理解。就是LCD驱动以及背光驱动是稳定的功耗大户,肯定比芯片的功耗大。不过扣除这些稳定的LCD功耗,可以看出,这个芯片的功耗还是很低的,即使是在图形加速情况下,也只有0.2W的增量,看起来不小,但是对比英伟达动辄几百W的烧钱手法。ST的边缘计算芯片,提供了一个非常好的边缘计算替代方案,完全可以实现理想的图形图像展示,以及相对复杂一些的变换。
-
回复了主题帖:
【STM32N6570-DK评测】#1 开箱
秦天qintian0303 发表于 2025-3-22 10:19
这DK板子看着相当霸气啊,配件也很丰富
确实是足尺寸的,够有料
- 2025-03-21
-
发表了主题帖:
【STM32N6570-DK评测】#1 开箱
1 概述
感谢入选走近 AI 重磅新品 STM32N6,解锁在 MCU 部署高性能、节能型边缘 AI 的活动,评测STM32N6570-DK,这款开发板的资料在STM32N6570-DK - Discovery kit with STM32N657X0 MCU,
打开包装,采用了环保包装,分别是主板,传感器扩展板和摄像头扩展板
2 开箱
STM32N6570-DK Discovery 套件是基于 Arm® Cortex®-M55 核心的 STM32N657X0H3Q 微控制器的完整演示和开发平台。这次的开发板包括了一个用于click-on的传感器模块扩展板,以及一个摄像头模块。正面是标准的正规的Discovery 开发板,STM32N6570-DK Discovery 套件包括全方位的硬件功能,帮助用户评估许多外围设备,如 USB Type-C®、Octo-SPI 闪存和 Hexadeca-SPI PSRAM 设备、以太网、相机模块、LCD、microSD™、音频编解码器、数字麦克风、ADC、柔性扩展连接器和用户按钮。
STM32N6570-DK Discovery 套件集成了 STM32 MCU 的 STLINK-V3EC 嵌入式电路内调试器和编程器,以及 USB 虚拟 COM 端口桥接器和全面的 MCU 软件包。
反面可以清楚的看到核心芯片STM32N657X0H3Q以及主要的部件。
STM32N657X0H3Q 微控制器具有一个 USB 2.0高速/全速设备/主机/OTG 控制器,一个 USB 2.0高速/全速设备/主机/OTG 控制器,带 UCPD(USB Type-C®供电),一个带 TSN(时间敏感网络)的以太网,四个I2C,两个I3C,六个SPI(其中四个I2S功能),两个SAI,四个DMIC支持,五个 USART,五个 UART(ISO78916接口,LIN,IrDA,高达12.5 Mbit/s),一个 LPUART,两个 SDMMC(MMC 版本4.0,CE-ATA 版本1.0和 SD 版本1.0.1),三个具有 TTCAN 功能的 CAN FD,JTAG 和 SWD 调试支持,以及嵌入式 Trace Macrocell™(ETM)。
3 开发板参数和主要应用场景
这个开发板实现的功能可以从下面的模块图中清晰描述,这些都是可以快速实现设计的主要功能模块
利用 STM32N6,在工业和消费类应用中实现全新性能水平
-STM32N6 基于运行频率达800 MHz的 Arm® Cortex®-M55处理器,是一款引入 Arm Helium 向量处理技术的 CPU,为标准 CPU 增添 DSP 处理能力。
-STM32N6 是首款内嵌意法半导体自主研发的神经处理单元 (NPU)——ST Neural-ART accelerator™ 的 STM32 MCU,专为节能型边缘 AI 应用而设计。其时钟频率高达1 GHz,计算性能可达600 GOPS,可为计算机视觉和音频应用提供实时神经网络推理能力。
-配备 MIPI CSI-2接口和图像信号处理 (ISP) 的专用计算机视觉处理管线,确保兼容多种类型的摄像头。STM32N6 还具有H264硬件编码器和 NeoChrom™ 图形加速器,适用于功能丰富的产品开发。
-它提供4.2 MB的连续嵌入式 RAM,是神经网络或图形应用的理想选择,并辅以高速外部存储器接口(hexa-SPI、OCTOSPI、FMC)。
-STM32N6 具备先进的安全特性,目标通过 SESIP 3级和 PSA 3级认证,符合最新安全标准。
这些参数都是对以前的STM32H7系列等芯片的升级,主要是增加了N-也就是Neural的功能,神经网络及AI加速器功能,在外设的扩展性能和内存扩展容量,也是一个很快的进步。那么,主要就是使用嵌入式的方式实现人工智能等应用。相比采用Linux衍生开发的芯片,性能强,但是边缘计算的特点不显著,而且价格比较高,这个是一个比较均衡的产品。
4 小结
这个开发板是需要完成典型的任务,如功耗,视频和音频处理等,尽可能增加AI的相关测试。
- 2025-02-24
-
回复了主题帖:
>>征集 | 晒电机控制痛点与难题,一起寻求最优解!
ADI的TMC系列电机驱动点亮了新的科技树,在大家卷生卷死的电机驱动赛道上单独开了一个玩法,就是用高性能的智能控制完成全部任务,换言之,不仅干了电机控制和电压驱动硬件集成的活,把控制和驱动都集成到一个芯片,还要把控制逻辑也集成到芯片中,软件硬件高度集成,软硬通吃。
此前评测过TMC76xx芯片的开发板,主要是控制双极伺服电机用的,用起来相当复杂,但是效果相当的好,在伺服电机低转矩启动和停止时都可以做得非常丝滑。复杂的设计,提供了TMC-IDE来智能测试和参数下载。
那么这次围绕 TMC9660 展开的是更升一级的芯片,驱动的电机品种更多,性能更精炼。这是一款高度集成的单芯片,集栅极驱动器、电机控制器与降压转换器于一体,广泛应用于机器人、工业制造、电动车辆等领域。TMC9660 支持多种电机类型,工作电压范围为 7.7V 至 70V ,具备诸多特性,如智能栅极驱动、硬件 FOC 控制、多种反馈接口、丰富的电源管理功能等。其内部结构包含多个功能模块,各模块分工协作,实现对电机的精准控制与系统的稳定运行。通过 SPI 或 UART 接口与外部处理器通信,有两种应用模式,还提供多种节能模式。
TMC9660 芯片内部结构复杂且高度集成,各模块协同工作以实现电机控制和系统管理功能,主要包含以下几个关键部分,在此前的设计中,这每一个部分可能都需要单独的芯片来控制,但是,这个东东直接都聚合在一起了:
微控制器单元(MCU):内置 32 位 RISC-V 微处理器,运行频率 40MHz,集成 48KB SRAM、OTP 和 ROM(含引导加载程序、直接寄存器访问和参数固件) 。拥有多个定时器,如系统定时器、基本定时器、高级定时器和看门狗定时器,用于 PWM 生成、位置计数、采样时间生成等。还集成 SPI、UART、I²C 通信外设,方便与外部设备交互。
电机控制核心(MCC):基于硬件实现,以场定向控制(FOC)为基础,支持多种电机类型。集成速度和位置 PI 控制器及 8 点位置斜坡发生器,通过 ADC 引擎测量电机电流,利用编码器和霍尔传感器反馈引擎获取转子位置。能实现高效的电机控制,支持平滑运行、零速满扭矩和快速动态响应。
电源管理单元(PMU):可通过电机电源电压生成内部所需电压。集成 DC/DC 降压转换器、电荷泵、两个可配置 LDO 和两个 1.8V LDO。具备欠压锁定(UVLO)、过流保护等功能,确保芯片在不同电源条件下稳定运行,还能对外部电源和内部生成电压进行监测和管理。
栅极驱动单元(GDU):专为电机控制设计,可驱动四个外部 NMOS+NMOS 半桥。具备用户可配置斜率控制、智能时序控制、过流和栅极短路保护等功能。采用自举拓扑结构,通过内部电荷泵提供 11.6V 栅极驱动电压,支持 100% 占空比运行,可有效驱动外部 FET,提高系统可靠性和效率。
测量单元(MU):用于测量和转换模拟信号,包含 4 个高带宽、差分双向电流检测放大器(CSA)和 4 个 13 位 ADC。CSA 具有低偏移、高带宽、可编程增益和可配置滤波器等特性,可测量电机相电流、IC 温度、电源电压及外部模拟信号,为电机控制提供准确的测量数据。
通信接口:支持 SPI 和 UART 通信接口,用于与外部处理器通信。SPI 接口有两个用于控制外部 SPI 外设,一个可连接 TMC9660 作为外设,支持多种 SPI 模式和高达 10MHz 的时钟频率;UART 接口支持全双工数据交换,提供多种波特率选择,支持自动波特率检测,还可通过 UART_TXEN 信号控制外部收发器实现 RS485 通信。
引导加载程序(Bootloader):用于系统启动和配置低级别设置,支持内部内存自检、系统配置(如时钟源、GPIO 功能、电机控制模式等)存储到 OTP 内存、外部内存访问等功能。通过 UART、RS485 或 SPI 通信,采用请求 / 响应数据报格式,确保系统启动和配置的灵活性和可靠性。
上述模块有几个亮点,
首先就是基于RISC-V的MCU,这次把开源进行到底,不再给arm交税了。相对较低的主频40MHz其实已经可以完成这些控制功能了,成本控制上首先加一:
其次电源管理单元,具有丰富的功能,高度弹性适应芯片内部多种功能模块的电压轨要求,还有节能降耗和智能控制的功能,节能成本控制再加一;
然后是山脊驱动单元,驱动4个NMOS+NMOS半桥,其实就是4个全桥,可以自由组合,只用三个全桥,就用来对无刷电机进行三相控制,只用两个全桥,就可以直接控制一个直流电机的正反转和调节,步进电机需要4个端口,应该是用足了4个全桥,这样的设计是用集成单元的冗余来实现多种应用的适应配合;
最后是完整的高度智能化,上述的智能控制,通过电机控制单元的内置等,都对开发者隔离了,只需要通过SPI,I2C等通讯端口按照规则输出控制命令,就可以直接控制,不需要理解更深的电机控制原理,纯纯的懒人助理。
目前看来,AI还没有淘汰我们,TMC系列已经抢先培养了懒人,来完成高级的任务了。
- 2025-02-18
-
发表了主题帖:
宝马多媒体模块的拆解二
宝马多媒体模块的拆解一
1 简介
整个模块完全拆解了,首先是核心主控板
这个是正面的拆解图,其中右侧是一个被屏蔽罩封闭的小扩展板。连结的非常牢靠,拆不下来,要先吸锡,再破坏才OK.
这个是主板的反面,拆了屏蔽层之后的
这个是没拆之前的
然后是随后的车载音频控制小板,对照主板的大小
子板的正面
子板的反面
连接主板的侧面
暴力破拆
拆开后的正面
拆开后的反面
2 古董级核心微控制器MCU
展现真容,核心主控的MCU是ST意法ST10F168
以及NEC的D43256
毫不意外,这两款芯片都应该是停产了
ST10F168是16位256KB内存的25MHzMCU,在KEIL的驱动网站上仍然可以找到资料。ST ST10F168 Data Sheet (keil.com)
配套的是NEC的 D43256BGU DatasheetCMOS RAM最为扩展外存。
MCU的原理图如下,应该是自研的指令集,还没有用到ARM指令集的
体验一下硬核的ST科技,自研的ASM汇编指令集
现在看着就头大了,能把这个模块弄出声音了,估计宝马的软件工程师掉不少头发。
背面的是SAA7706H Car radio Digital Signal Processor (DSP) (nxp.com.cn),来自NXP的车载电台数字处理芯片SAA7706
逻辑图如下,使用了单声道,多声道,外来音源的混合数字处理模式,输出的是数字音频。或许,这就已经是当时的高科技了
不过看着数据参数表,还是科技含量满满的。
这个F0S8104来自Cirrus Logic当年的声卡专家,对应数模转换和音频处理。
3 车载音频和声音控制处理
上面已经拆解开了小板,其中核心元件就是飞利浦的TEA6848H New In Car Entertainment car radio tuner IC with Precision Adjacent Channel Suppression 。这个是车载音频娱乐调谐芯片,一直到2017年还有最后一次更新还保留在NXP的网站上。
TEA6848H是具有汽车收音机调谐器的单芯片,适用于AM、FM和气象波段(WB) ,可通过I²C总线进行微控制器调谐。其提供以下功能:
- AM双转换接收器,适用于LW、MW和SW(31 m、41 m和49 m波段),其中IF1 = 10.7 MHz,IF2 = 450 kHz
-具有集成镜频抑制的FM双转换接收器,适用于IF1和IF2,可选择美国FM、美国气象、欧洲FM、东欧FM和日本FM波段;450 kHz FM IF2具有完全集成的动态选择性;带动态阈值扩展的FM解调器;通过I²C总线对准IF2选择性的中心频率。
那么就是一个多频段选择和调整芯片。具有精密相邻信道抑制功能的新型车载娱乐汽车无线电调谐器IC (NICE-PACS) | NXP 半导体
4 总结
综合上一帖的拆解,这个多媒体模块在现在看来有些名不副实,因为主要的功能就是车载电台和外来音源的处理。应该在ST的MCU还有比较复杂的面板控制功能,因为还支持CAN协议,所以还有和汽车主控交互的功能。不过,如果没有IDE,只用手搓,那个汇编代码的编制,应该是一个硬功夫。
这个模块还有不少放大器,功放等元件,不过过于久远,应该不少都找不到对应的介绍了。如LT1376已经定位到了ADI的页面LT1376数据手册和产品信息 | Analog Devices,不过显然不是ADI的。可以找到的是LT1249 Datasheet和ST2303 datasheet STANSON | P Channel Enchancement Mode MOSFET等元件。
这次拆解,还是大出所料。主要是车载智能化的进步实在太快了,车载智能仓提供的丰富人机交互已经具有未来的科幻感了。这次拆解非常费劲,但是拆开后发现,是一次科技考古活动。
从设计看,功能冗余再冗余,安全屏蔽再屏蔽,也不能说不对,但其实更好的优化之下,更高速率的信号传输也没有必要这么如临大敌的搞这么复杂的硬件设计。
用现在的眼光,活血可以解释为是用高品质作为了懒惰的挡箭牌。
- 2025-02-17
-
发表了主题帖:
宝马多媒体模块的拆解一
本帖最后由 北方 于 2025-2-17 16:43 编辑
1 概述
有幸入选EEWorld邀你来拆解(18期):揭秘随身WiFi、宝马原装索尼打印模块活动,获得宝马多媒体模块的拆解机会
不过,等收到这个模块的时候却发现有些搞不明白。
这个模块是原装宝马模块无疑,鲜明的BMW标识而不是通常的代工厂标识。不过,根据最新的车机一体化,都是一个比较大的模块包括音箱,功放,控制按钮等。那么这个样子,颗是多媒体模块,应该是比较古董级的。后面的拆解过程就印证了这个印象。因为我几乎就拆不了。还需要另外找装备。
所以,这一帖只写已经拆下了的部分。
2 首拆
先把两个模块分开,这个是用一个定制排线插接起来的,所以很容易就分离开了。看起来上面的塑壳难拆,因为用了比较特殊的梅花螺丝,原来的几个都不行,最小的20号,所以还订了起子,需要是15号的才行。其实拆开后,这个是最好弄的。而下面的铝壳非常容易分开,但是随后就怎么也搞不动了,因为,只要是芯片就上屏蔽罩,而且各种连接方式,卡扣,焊接等等。到现在才想出拆开的方法,有些部分只好用破坏性的暴力拆解。
这个是塑壳模块的拆解图,PCB板材扎实,分立元件多,明显覆铜线面积大,尽可能对称布置,元件规整,显然的高质量。不过,这个是干啥的,还真没猜出来。正面的铸铝支撑架,还有明显的散热功能,也用螺丝连接在PCB板上。
反面,就没有什么元器件了。
3 功能解析
3.1 第一部分是左下角的TEA6101器件为核心的部分
3.2 这是围绕LM2904的部分
查了一下,这个是一个四路天线混合器。这个是来自飞利浦公司的。可是飞利浦电子应该早就被合并了吧,模拟部分貌似是被NXP合并了,这个产品也就是存在于记忆中了。不过,能在网上找到参数表,应该是一个比较能打的产品。
这个芯片是给车载调频FM信号提供在4个天线中寻找最优信号的选择器。在高速运动的汽车上,保持FM信号的稳定应该还是有点技术获得,我们经常在开车的过程广播信号忽强忽弱,就是快速穿越不同区域,信号显著变化的原因。采用这个芯片,应该是让FM广播在多个天线中选择信号最优的,保持用户听觉体验的稳定。如果,不是拆到这个芯片,也不容易理解BMW为什么在用户体验上有那么高的溢价,就是坐在车里,用户体验很好,但是就是不知道是哪里觉得舒服。
其设计原理图如下
3.3 这是另一个LM2904对应的部分。两部分布置在不同的区域,故意隔了老远,但走线对称,比较像配置的双声道信号线。
这个LM2904是来自德州仪器的查用双通道运算放大器,最高电压是36V,在车载电池12V的情况下,给出了足够的安全裕度。带宽1.2MHz的时候能获得最稳定的放大倍数。
这个字里行间,就是为了一个稳定,这个正好适应于调频信号MHz信号的范围。
4 小结
这个部分的小拆解有两个体会。
现在的技术进步,电子集成化突飞猛进。保持高品质的调频FM信号,需要从天线到运算放大器等多个环节都采取措施,而现在有专门的调频芯片一个搞定,还包括选频跳频记忆等多种控制功能,而且性能包好,成本包低。
另一个,车载电子的被动元件,始终稳稳的保持车载电子设计的重要性地位。在信号回路的阻抗匹配,信号回路的各种滤波,陷波和过压过流保护,高质量的电阻电容等被动元件,仍然是不可或缺的环节。这个广播信号放大器模块的设计,就是充分考虑了信号的稳定,降低敢让,降低EMC辐射的多种考虑,而且量大份足,管够的样子,非常符合德国汽车工业那种传统的印象。
从功能实现上,看起来不复杂,但是还是可以学到很多设计概念上的理念。
- 2025-01-22
-
回复了主题帖:
【颁奖】 【回顾2024,展望2025】新年抢楼活动来啦!
个人收件信息已确认。
- 2025-01-14
-
回复了主题帖:
【回顾2024,展望2025】新年抢楼活动来啦!
最新关注的是量子技术。
量子技术虽然看起来还很抽象,不过一旦实用化,就可以迅速破解区块链的加密机制,对比特币等空气币给以致命一击。
所以,搬个板凳看戏。