- 2024-11-14
-
回复了主题帖:
【STM32H7S78-DK】(11)语音控制之旅
ly87802541 发表于 2024-11-13 12:31
大佬给力!竟然输出10+篇。
这么强大的板子,测评100+也不过分:loveliness:
- 2024-11-13
-
回复了主题帖:
【英飞凌PSOC™ 4100S Max】①开箱及开发环境搭建
nmg 发表于 2024-11-13 10:06
感谢分享
:loveliness:好东西一起分享
- 2024-11-12
-
发表了主题帖:
【英飞凌PSOC™ 4100S Max】①开箱及开发环境搭建
本帖最后由 cc1989summer 于 2024-11-12 22:04 编辑
非常感谢EEWORLD以及DigiKey 得捷提供我这次试用机会。
早就听闻英飞凌在汽车控制领域的大名,这是我第一次使用英飞凌MCU,非常期待。
提前大致了解了下,英飞凌的MCU产品线主要有4类。
1. TC系列,主要是汽车控制,是英飞凌的王牌产品。基于TriCore™ 的产品在汽车中的应用非常广泛,包括内燃机控制、纯电动和混合动力汽车、变速器控制单元、底盘域、制动系统、电动转向系统、安全气囊、联网和高级驾驶辅助系统,并推动着自动化,电动化以及网联化的发展。
2. PSOC系列(收购cypress),涵盖较广,汽车控制、工业控制、消费电子、物联网等等都有涉及。
3. T2G系列,采用高性能 32 位 Arm® Cortex-M4F® 和 M7F CPU,工作频率最高可至 350 MHz,适用于互联汽车应用。
4. XMC系列,基于ARM® Cortex®-M内核。这个产品系列专门针对功率转换、工厂自动化、楼宇自控、交通和家用电器等领域的应用而打造。
以下为产品线图示:
回到开发板本身,收到后打开感觉十分惊艳,包装精美,看起来不像电子开发板,倒像个精致的礼物。
开发板做工也十分精美,最引人注目的是巨大的触摸板,这也是英飞凌的看家本领,第五代CapSense。
第五代CAPSENSE技术的性能是前几代的十倍,功耗仅是前几代的十分之一,不仅支持工程师开发更直观的用户界面,降低了整体功耗,而且满足便携式电池供电的物联网设备的低功耗需求。全新CAPSENSE是智能门锁、智能开关、恒温器、智能音箱、电动工具、工业触摸屏等各种家用电器、工业应用以及其他物联网设备的理想选择。新技术也很适合有较大触摸屏的电磁炉、洗衣机和烘干机、冰箱、烤箱等工业和家用电器产品。
配置温习下:
32 位 MCU 子系统
带有 DMA 控制器的 48 MHz Arm® Cortex®-M0+ CPU
384 KB 闪存和 32 KB SRAM
带 PLL 的外部 MHz 振荡器 (ECO) 和 32 KHz 手表晶体振荡器 (WCO)
加密块包括 AES、TRNG、CRA、PRNG 和 SHA
可编程模拟块
1 个 12 位、1 Msps SAR ADC
两个运算放大器可配置为可编程增益放大器 (PGA)、比较器 (CMP) 等。
两个低功耗比较器 (CMP)
两个 MSC(多传感转换器)模块集成了第五代 CAPSENSE 和电感传感
可编程数字模块
两个 16 位定时器/计数器/脉宽调制器 (TCPWM) 模块
两个串行通信模块 (SCB),可配置为 I2C、SPI 或 UART
段码式 LCD
I2S 音频输出
一个 CAN-FD(具有灵活数据速率的控制器局域网络)控制器
通电后,有个触摸演示程序。
[localvideo]7799f6b9298a0ff6a61f1d26d395b9ae[/localvideo]
接下来是开发环境搭建。
麻烦事来了。
目前最新版开发工具是ModusToolbox 3.3
下载网址,实际也包含ModusToolbox 3.0:
https://softwaretools.infineon.com/tools/com.ifx.tb.tool.modustoolbox
下载(下载速度10+KB/s)安装后,新建工程,发现无法获取芯片列表,该列表需要从github获取,然而由于无法连上github,实际无法使用。
后来发现这是个通病,英飞凌的本地化做的不够好,没有在中国设置服务器。
EEWORLD已经有坛友发过这个问题,
https://bbs.eeworld.com.cn/thread-1237088-1-1.html
https://bbs.eeworld.com.cn/thread-1237247-1-1.html
解决方案是安装ModusToolbox 3.0 以及离线软件包。
ModusToolbox 3.0
https://softwaretools.infineon.com/tools/com.ifx.tb.tool.modustoolbox
ModusToolbox™ Offline Libraries离线软件包
https://softwaretools.infineon.com/tools/com.ifx.tb.tool.modustoolboxofflinecontentpackage
下载下来后(下载速度10+KB/s,早上6点可达到500KB/s),
先安装ModusToolbox 3.0,设置好环境变量CY_TOOLS_PATHS
新建项目,仍然得到错误信息,此时,选择offline选项,
注意看下面的报警提示:
没有找到离线包。
那么我们就在提示的目录新建 .modustoolbox目录,然后将下载下来的离线包(整体是个offline目录)存到此目录。
然后重新打开软件新建工程终于可以了!!!!!!
选择官方例程:GPIO pins
然后进行编译及下载。
注意Debug设置,选择 Program(KitProg3)
以下是下载信息:
Open On-Chip Debugger 0.11.0+dev-4.4.0.2134 (2022-09-08-13:07)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
kitprog3 set_latest_version: C:/Users/Administrator/ModusToolbox/tools_3.0/fw-loader 2.40.1241
Info : auto-selecting first available session transport "swd". To override use 'transport select <transport>'.
adapter speed: 2000 kHz
** Auto-acquire enabled, use "set PSOC4_USE_ACQUIRE 0" to disable
cortex_m reset_config sysresetreq
Info : Using CMSIS-DAPv2 interface with VID:PID=0x04b4:0xf155, serial=14060E6D01042400
Info : CMSIS-DAP: SWD supported
Info : CMSIS-DAP: Atomic commands supported
Info : CMSIS-DAP: FW Version = 2.0.0
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 0 TDO = 0 nTRST = 0 nRESET = 1
Info : CMSIS-DAP: Interface ready
Info : KitProg3: FW version: 2.30.1155
Info : KitProg3: Pipelined transfers enabled
Info : KitProg3: Asynchronous USB transfers enabled
Info : VTarget = 4.885 V
Info : kitprog3: acquiring the device (mode: reset)...
Info : clock speed 2000 kHz
Info : SWD DPIDR 0x0bc11477
Info : [psoc4.cpu] Cortex-M0+ r0p1 processor detected
Info : [psoc4.cpu] target has 4 breakpoints, 2 watchpoints
Info : [psoc4.cpu] external reset detected
*****************************************
** Silicon: 0x2E2D, Family: 0xBE, Rev.: 0x11 (A0)
** Detected Family: PSoC 4100S Max
** Detected Device: CY8C4149AZI-S598
** Detected Main Flash size, kb: 384
** Chip Protection: OPEN
*****************************************
Info : gdb port disabled
Info : starting gdb server for psoc4.cpu on 3333
Info : Listening on port 3333 for gdb connections
Info : SWD DPIDR 0x0bc11477
Info : kitprog3: acquiring the device (mode: reset)...
psoc4.cpu halted due to debug-request, current mode: Thread
xPSR: 0xa1000000 pc: 0x10000040 msp: 0x20007fe8
** Device acquired successfully
** Programming Started **
auto erase enabled
Info : Padding image section 0 at 0x0000146c with 148 bytes (bank write end alignment)
Warn : Only mass erase available, erase skipped! (psoc4 mass_erase)
[ 4%] [# ] [ Programming ]
[ 9%] [## ] [ Programming ]
[ 14%] [#### ] [ Programming ]
[ 19%] [###### ] [ Programming ]
[ 23%] [####### ] [ Programming ]
[ 28%] [######## ] [ Programming ]
[ 33%] [########## ] [ Programming ]
[ 38%] [############ ] [ Programming ]
[ 42%] [############# ] [ Programming ]
[ 47%] [############### ] [ Programming ]
[ 52%] [################ ] [ Programming ]
[ 57%] [################## ] [ Programming ]
[ 61%] [################### ] [ Programming ]
[ 66%] [##################### ] [ Programming ]
[ 71%] [###################### ] [ Programming ]
[ 76%] [######################## ] [ Programming ]
[ 80%] [######################### ] [ Programming ]
[ 85%] [########################### ] [ Programming ]
[ 90%] [############################ ] [ Programming ]
[ 95%] [############################## ] [ Programming ]
[100%] [################################] [ Programming ]
wrote 5376 bytes from file C:/Users/Administrator/InfineonWork/GPIO_Pins/build/APP_CY8CKIT-041S-MAX/Debug/mtb-example-psoc4-gpio.hex in 0.291444s (18.014 KiB/s)
** Programming Finished **
** Program operation completed successfully **
srst_only separate srst_gates_jtag srst_open_drain connect_deassert_srst
Info : SWD DPIDR 0x0bc11477
Polling target psoc4.cpu failed, trying to reexamine
Info : SWD DPIDR 0x0bc11477
Info : [psoc4.cpu] Cortex-M0+ r0p1 processor detected
Info : [psoc4.cpu] target has 4 breakpoints, 2 watchpoints
shutdown command invoked
Info : psoc4.dap: powering down debug domain...
Warn :
*******************************************************************************************
* KitProg firmware is out of date, please update to the latest version (2.40.1241)
* using fw-loader tool which can be found in the following folder
* C:/Users/Administrator/ModusToolbox/tools_3.0/fw-loader
*******************************************************************************************
运行效果如下:
[localvideo]74999f0ea117114a68fbab4650a38d04[/localvideo]
本次的开箱分享就到这里了~
- 2024-11-09
-
发表了主题帖:
【STM32H7S78-DK】(11)语音控制之旅
本帖最后由 cc1989summer 于 2024-11-9 22:39 编辑
语音识别、人工智能是目前的大热门。
咱们的STM32H7S78-DK是自带有数字麦克风的,也就是U1:MP23DB01
然而要想实现STM32语音识别,涉及到人工智能CNN,我目前还没摸索会。
网上有相关的内容参考:
https://github.com/gk969/stm32-speech-recognition
这里就基于离线语音识别模块:ASR-PRO
模块介绍:本模块是针对低成本离线语音应用方案开发的一款通用、便携、低功耗高性能的语音识 别模组,采用最新的 ASRPRO 芯片,内置神经网络处理器,能支持 DNN\TDNN\RNN 等神 经网络及卷积运算,支持语音识别、声纹识别、语音增强、语音检测等功能,具备强劲的回 声消除和环境噪声抑制能力,语音识别效果优于其它语音芯片。该芯片方案还支持汉语、英 语、日语等多种全球语言,可广泛应用于家电、照明、玩具、可穿戴设备、工业、汽车等产 品领域,搭配天问 Block 图形化编程软件,快速实现语音交互及控制和各类智能语音方案应 用。
大概模式是这样:
使用模块配套的软件:可以自定义语音模型,并下载到芯片中,实现离线语音识别:
下图是我预先定义好的唤醒语句,以及控制语句,生成模型并下载后,就可以开启STM32语音控制之旅了。
STM32H7S78-DK需要设置的主要是串口(UART7,PE8/PE7)以及GPIO。
关于串口(UART7,PE8/PE7),需要注意的是,开发板没有引出,整块开发板只有虚拟串口(UART4)可用。
需要对电路加以改动,详见我的前述帖子:
https://bbs.eeworld.com.cn/thread-1295392-1-1.html
记得一定要开启串口中断。
以下是main.c函数,
记得此语句开启串口接收中断:
HAL_UART_Receive_IT(&huart7, UART_BUF,sizeof(UART_BUF));
int main(void)
{
MPU_Config();
/* USER CODE BEGIN 1 */
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
/* Enable D-Cache---------------------------------------------------------*/
SCB_EnableDCache();
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Update SystemCoreClock variable according to RCC registers values. */
SystemCoreClockUpdate();
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_UART7_Init();
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart7, UART_BUF,sizeof(UART_BUF));
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
在串口中断语句中,加入控制语句:
此句是把语音识别模块发给MCU的指令,由MCU发给电脑端,做串口监听。
HAL_UART_Transmit(&huart7, UART_BUF,sizeof(UART_BUF),1000);
此句是处理完串口接收中断,再次进入串口中断。
HAL_UART_Receive_IT(&huart7, UART_BUF,sizeof(UART_BUF));
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
HAL_UART_Transmit(&huart7, UART_BUF,sizeof(UART_BUF),1000);
if(UART_BUF[0] == 0x01)
{HAL_GPIO_WritePin(LD1_GPIO_PORT, LD1_Pin,SET);}
if(UART_BUF[0] == 0x02)
{HAL_GPIO_WritePin(LD2_GPIO_PORT, LD2_Pin,SET);}
if(UART_BUF[0] == 0x03)
{HAL_GPIO_WritePin(LD3_GPIO_PORT, LD3_Pin,RESET);}
if(UART_BUF[0] == 0x04)
{HAL_GPIO_WritePin(LD4_GPIO_PORT, LD4_Pin,RESET);}
if(UART_BUF[0] == 0x05)
{HAL_GPIO_WritePin(LD1_GPIO_PORT, LD1_Pin,RESET);}
if(UART_BUF[0] == 0x06)
{HAL_GPIO_WritePin(LD2_GPIO_PORT, LD2_Pin,RESET);}
if(UART_BUF[0] == 0x07)
{HAL_GPIO_WritePin(LD3_GPIO_PORT, LD3_Pin,SET);}
if(UART_BUF[0] == 0x08)
{HAL_GPIO_WritePin(LD4_GPIO_PORT, LD4_Pin,SET);}
if(UART_BUF[0] == 0x09)
{
HAL_GPIO_WritePin(LD1_GPIO_PORT, LD1_Pin,SET);
HAL_GPIO_WritePin(LD2_GPIO_PORT, LD2_Pin,SET);
HAL_GPIO_WritePin(LD3_GPIO_PORT, LD3_Pin,RESET);
HAL_GPIO_WritePin(LD4_GPIO_PORT, LD4_Pin,RESET);
}
if(UART_BUF[0] == 0x10)
{
HAL_GPIO_WritePin(LD1_GPIO_PORT, LD1_Pin,RESET);
HAL_GPIO_WritePin(LD2_GPIO_PORT, LD2_Pin,RESET);
HAL_GPIO_WritePin(LD3_GPIO_PORT, LD3_Pin,SET);
HAL_GPIO_WritePin(LD4_GPIO_PORT, LD4_Pin,SET);
}
HAL_UART_Receive_IT(&huart7, UART_BUF,sizeof(UART_BUF));
}
运行效果:
[localvideo]9b28ca4de63950b6a27f30dee0c6f2b9[/localvideo]
再增加点花样,对于显示屏的颜色给与控制。增加以下指令:
程序代码,参考BSP中的LCD显示:
int main(void)
{
/* MPU Configuration--------------------------------------------------------*/
MPU_Config();
/* Enable the CPU Cache */
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
/* Enable D-Cache---------------------------------------------------------*/
// SCB_EnableDCache();
/* STM32H7RSxx HAL library initialization:
- Systick timer is configured by default as source of time base, but user
can eventually implement his proper time base source (a general purpose
timer for example or other time source), keeping in mind that Time base
duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
handled in milliseconds basis.
- Set NVIC Group Priority to 4
- Low Level Initialization
*/
HAL_Init();
/* Configure the system clock to 400 MHz */
SystemClock_Config();
/* Initialize leds */
BSP_LED_Init(LED_GREEN);
BSP_LED_Init(LED_RED);
/* Configure the User push-button in EXTI Mode */
BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);
MX_UART7_Init();
HAL_UART_Transmit(&huart7, UART_BUF9, sizeof(UART_BUF9),100);
HAL_UART_Receive_IT(&huart7, UART_BUF,sizeof(UART_BUF));
/* Init LCD */
BSP_LCD_Init(0, LCD_ORIENTATION_LANDSCAPE);
BSP_LCD_GetBrightness(0, &Brightness);
BSP_LCD_SetBrightness(0, 40);
BSP_LCD_GetBrightness(0, &Brightness);
UTIL_LCD_SetFuncDriver(&LCD_Driver);
//BSP_LCD_Reload(0, BSP_LCD_RELOAD_VERTICAL_BLANKING);
//Display_DemoDescription();
UTIL_LCD_FillRect(0, 0, 800, 480, UTIL_LCD_COLOR_GREEN);
//AudioPlay_demo();
//BSP_examples[4].DemoFunc();
while (1)
{
}
}
串口中断部分,解析语音指令显示代码:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
HAL_UART_Transmit(&huart7, UART_BUF,sizeof(UART_BUF),1000);
if(UART_BUF[0] == 0x11)
{
/* Display LCD messages */
UTIL_LCD_FillRect(0, 0, 800, 480, UTIL_LCD_COLOR_RED);
UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_WHITE);
UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_MAGENTA);
UTIL_LCD_SetFont(&Font24);
UTIL_LCD_DisplayStringAt(0, 200, (uint8_t *)"AUDIO PLAYER by cc1989summer", CENTER_MODE);
}
if(UART_BUF[0] == 0x12)
{
/* Display LCD messages */
UTIL_LCD_FillRect(0, 0, 800, 480, UTIL_LCD_COLOR_GREEN);
UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_WHITE);
UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_BLUE);
UTIL_LCD_SetFont(&Font24);
UTIL_LCD_DisplayStringAt(0, 200, (uint8_t *)"AUDIO PLAYER by cc1989summer", CENTER_MODE);
}
if(UART_BUF[0] == 0x13)
{
/* Display LCD messages */
UTIL_LCD_FillRect(0, 0, 800, 480, UTIL_LCD_COLOR_BLUE);
UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_WHITE);
UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_BLUE);
UTIL_LCD_SetFont(&Font24);
UTIL_LCD_DisplayStringAt(0, 200, (uint8_t *)"AUDIO PLAYER by cc1989summer", CENTER_MODE);
}
if(UART_BUF[0] == 0x14)
{
/* Display LCD messages */
UTIL_LCD_FillRect(0, 0, 800, 480, UTIL_LCD_COLOR_WHITE);
UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_WHITE);
UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_BLUE);
UTIL_LCD_SetFont(&Font24);
UTIL_LCD_DisplayStringAt(0, 200, (uint8_t *)"AUDIO PLAYER by cc1989summer", CENTER_MODE);
}
if(UART_BUF[0] == 0x15)
{
/* Display LCD messages */
UTIL_LCD_FillRect(0, 0, 800, 480, UTIL_LCD_COLOR_MAGENTA);
UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_WHITE);
UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_BLUE);
UTIL_LCD_SetFont(&Font24);
UTIL_LCD_DisplayStringAt(0, 200, (uint8_t *)"AUDIO PLAYER by cc1989summer", CENTER_MODE);
}
if(UART_BUF[0] == 0x16)
{
/* Display LCD messages */
UTIL_LCD_FillRect(0, 0, 800, 480, UTIL_LCD_COLOR_BLACK);
UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_WHITE);
UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_BLUE);
UTIL_LCD_SetFont(&Font24);
UTIL_LCD_DisplayStringAt(0, 200, (uint8_t *)"AUDIO PLAYER by cc1989summer", CENTER_MODE);
}
if(UART_BUF[0] == 0x17)
{
/* Display LCD messages */
UTIL_LCD_FillRect(0, 0, 800, 480, UTIL_LCD_COLOR_ORANGE);
UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_WHITE);
UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_BLUE);
UTIL_LCD_SetFont(&Font24);
UTIL_LCD_DisplayStringAt(0, 200, (uint8_t *)"AUDIO PLAYER by cc1989summer", CENTER_MODE);
}
HAL_UART_Receive_IT(&huart7, UART_BUF,sizeof(UART_BUF));
}
运行效果;
[localvideo]3a9dfed40ae59b39aee5a76c067e0372[/localvideo]
最后,结合此前的练习:
【STM32H7S78-DK】⑦连接WIFI获取时间(基于ESP8266)
https://bbs.eeworld.com.cn/thread-1295392-1-1.html
加入语音唤醒WIFI时间指令,思路跟上述一样。
在对应的串口中断中加入获取时间的指令。
[localvideo]74addb62a5040d2e86964dc05598b3b1[/localvideo]
至此,全部的【STM32H7S78-DK】体验及分享就到这里了。
总计11篇贴文,付出很多时间精力,也收获很多知识和经验,不仅对对STSTM32H7S78开发掌握更深,对ST的各类软件操作也更加熟练。
当然,由于时间关系,很多高端、丰富的功能还没时间体验,转眼就到交作业的截止时间了。
包括 MXCHIP的SPI WIFI模块、数字麦克风、摄像头(坛友有首发)、以太网、DMA、TouchGFX、Free-RTOS、NanoEdge™ AI Studio等等。
有些浅尝辄止,有些还未开始体验,待后续有时间,一定深入学习,进一步发掘和体验STM32H7S78-DK的宝藏功能。
我目前接下来的目标是:做一个基于互联网的网络收音机,结合TouchGFX的丰富界面,功能一定很酷炫。
还有就是视频播放器、将存在SD卡上的视频,比如mp4格式,解码并播放出来。
再有就是目前流行的人工智能,比如基于TouchGFX的手写识别,直接在触摸屏上一边手写,一边自动识别。
想法很多,接下来逐步实践吧,所谓学无止境就是这样吧。
最后,非常感谢EEWORLD和ST给我的这次机会,我很珍惜也很努力,希望EEWORLD越办越好,给我们电子从业人员和电子爱好者提供更多的学习成长机会,也祝愿ST越来越强大!
- 2024-11-02
-
回复了主题帖:
# STM32H7S78-DK 开发套件三周目评测:简单声音采集保存之使用 SD 卡读写的实现与分析
哥们,你这帖子在那干讲,没开发板跑的实物图啊。{:1_131:}
- 2024-10-30
-
回复了主题帖:
《STM32H7S78-DK 开发套件二周目评测:简单声音采集之驱动MAX4466高精度声音传感器》
ccccccc@ 发表于 2024-10-30 15:50
我开始也是看他有数字麦克风,才想测评弄这个,但是我只找到一个麦克风接口,有点疑惑。所以就干脆直接买 ...
哥们,翻到开发板背面,靠近USB1上面,有个芯片U1:MP23DB01,就是数字麦克风
- 2024-10-29
-
回复了主题帖:
【STM32H7S78-DK】⑩播放流行音乐,大家一起摇摆!
freebsder 发表于 2024-10-29 18:55
做个网络的,在线播放
有这个想法呢,还得继续摸索,搞定wifi……:victory:
-
回复了主题帖:
【STM32H7S78-DK】⑩播放流行音乐,大家一起摇摆!
lugl4313820 发表于 2024-10-29 17:11
强呀,我一直找WM8904的例程,没搞定,这次找到了,感谢大神的分享!
官方的BSP是要好好利用上,底层的东西就没必要重复造轮子了。{:1_138:}
-
回复了主题帖:
【STM32H7S78-DK】⑩播放流行音乐,大家一起摇摆!
秦天qintian0303 发表于 2024-10-29 09:09
可以弄个打击乐的乐器
这个可以有:victory:
-
回复了主题帖:
【STM32H7S78-DK】⑨TouchGFX项目实践:电子相册
inkinessray 发表于 2024-10-29 15:22
厉害!
多谢支持!大家互相学习:loveliness:
-
回复了主题帖:
《STM32H7S78-DK 开发套件二周目评测:简单声音采集之驱动MAX4466高精度声音传感器》
楼主,STM32H7S78-DK本身就带数字麦克风,理论上可以通过该麦克风实现音量检测……:victory:
- 2024-10-28
-
发表了主题帖:
【STM32H7S78-DK】⑩播放流行音乐,大家一起摇摆!
STM32H7S78-DK 开发板是具备无敌多媒体功能的超级开发板。
为什么这么讲呢,他具备数字麦克风、I2S音频编解码、SD卡及Flash存储、5英寸高清晰TFT LCD、WIFI扩展卡。
这些功能集合到一块,可以发挥无穷想象,既可以做一个数码相册、也可以做一个网络收音机、或者是像小爱同学一样的智能音箱,总之玩法多样,潜力无穷。
本篇我们来体验最基本的音频播放功能,即播放存储在Flash上的流行音乐。
大致逻辑是这样的:
但问题是,整个流程涉及Flash读取、音频文件解析(Wav)、I2S(DMA方式)、WM8904驱动……
短时间内如何掌握这么多复杂高深的内容,从而完成我们一个简单的任务:播放流行音乐
经过一段时间的摸索,办法来了:利用官方的BSP(board support package,板级支持包)
这里面有我们需要的一切函数,我们想要实现什么功能,直接设置好参数调用就好了,无需彻底搞懂复杂的过程,一切以目标驱动模式完成。
好了,话不多说,开始我们的流行音乐之旅吧。
1. 在CubeIDE中导入官方例程BSP。
2. 熟读README.md,详细介绍了这个BSP都有啥演示程序,以及如何使用。
3. 最关键的环节:烧录音乐文件(bin)到Flash存储中。
### <b>How to use it ?</b>
- Use STM32CubeProgrammer, available on www.st.com or any other in system programming
tool to load "BSP/Binary/audio_sample_tdm.bin" file to the external QSPI flash
at the address 0x700A0000.
- Open the STM32CubeProgrammer tool
- Select the octoSPI external flash loader "MX66UW1G45G_STM32H7S78-DK"
- From Erasing & Programming menu, browse and open the output binary file relative to this example
- Load the file into the external QSPI flash using "Start Programming" at the address APPLICATION_ADDRESS (0x700A0000)
他这里提供了一段实例音乐audio_sample_tdm.bin(大小512KB),我们将他替换为我们想要播放的流行音乐。
你肯定纳闷,上哪去搞bin格式的音频。
首先下载一首mp3,其次去在线mp3转wav格式网站,这种很多。
比如:
https://www.aconvert.com/cn/audio/mp3-to-wav/
比特率和采样率参考:
得到WAV格式后,直接将.wav后缀改为.bin(简单粗暴有木有,其实wav就是最原始的i2s数字音频文件)
WAV为微软公司(Microsoft)开发的一种声音文件格式,它符合RIFF(Resource Interchange File Format)文件规范,用于保存Windows平台的音频信息资源,被Windows平台及其应用程序所广泛支持,该格式也支持MSADPCM,CCITT A LAW等多种压缩运算法,支持多种音频数字,取样频率和声道。标准格式化的WAV文件采样频率为44100Hz,采样比特为16bit,因此标准的(这里说标准,只是一种广泛采用的波形音频方案)WAV文件和CD音频格式一样,也是44.1KHz的取样频率,16位量化数字,在声音文件质量和CD音频相差无几。
将我们的流行音乐miaozhen.bin(大约10.9MB)通过STM32CubeProgrammer烧录到开发板的Flash中。
第一步,连接开发板,选择Flash驱动:MX66UW1G45G_STM32H7S78-DK。
第二部:选择我们的bin格式音频,输入起始地址(0x700A0000),开始烧录。
4. 对官方支持包BSP大做手术,实现我们的功能:播放流行音乐
main.c中可以看到,BSP总共6个功能,由用户按钮选择,我们简单干脆,只要audio play功能。
所以把该程序块直接屏蔽,仅改为:AudioPlay_demo();
来到main.h中,查看对音频文件的定义:
/* The Audio file is flashed with STM32CubeProgrammer @ flash address = AUDIO_SRC_FILE_ADDRESS */
#define AUDIO_SRC_FILE_ADDRESS 0x700A0000 /* Audio file address in flash */
#define AUDIO_FILE_SIZE 0xafc880
AUDIO_SRC_FILE_ADDRESS好理解,就是刚才我们写入Flash的地址:0x700A0000。
AUDIO_FILE_SIZE就是该段音频的文件大小:
用文件管理器可看到,该bin文件为11,520,128 bit,换算为16进制为:0xAFC880,也就是上面的AUDIO_FILE_SIZE
这里一定要对上,否则在循环播放的过程中会错乱。
最后来到播放音乐的核心 audio_play.c文件中:
我们可以仔细阅读各部分的功能,多余的也不要了。
最核心的while循环中,仅保留
AUDIO_Process();
#include "main.h"
#include <stdio.h>
/** @addtogroup STM32H7RSxx_HAL_Examples
* @{
*/
/** @addtogroup BSP
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/*Since SysTick is set to 1ms (unless to set it quicker) */
/* to run up to 48khz, a buffer around 1000 (or more) is requested*/
/* to run up to 96khz, a buffer around 2000 (or more) is requested*/
#define AUDIO_DEFAULT_VOLUME 90
/* Audio file size and start address are defined here since the audio file is
stored in Flash memory as a constant table of 16-bit data */
#define AUDIO_START_OFFSET_ADDRESS 0 /* Offset relative to audio file header size */
#define AUDIO_BUFFER_SIZE 2048
/* Audio file size and start address are defined here since the audio file is
stored in Flash memory as a constant table of 16-bit data */
#define AUDIO_START_OFFSET_ADDRESS 0 /* Offset relative to audio file header size */
/* Private typedef -----------------------------------------------------------*/
typedef enum {
BUFFER_OFFSET_NONE = 0,
BUFFER_OFFSET_HALF,
BUFFER_OFFSET_FULL,
}BUFFER_StateTypeDef;
typedef struct {
uint8_t buff[AUDIO_BUFFER_SIZE];
uint32_t fptr;
BUFFER_StateTypeDef state;
uint32_t AudioFileSize;
uint32_t *SrcAddress;
}AUDIO_BufferTypeDef;
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
ALIGN_32BYTES (static AUDIO_BufferTypeDef buffer_ctl);
__IO uint32_t audio_state;
__IO uint32_t uwVolume = 20;
__IO uint32_t uwPauseEnabledStatus = 0;
uint32_t AudioFreq[8] = {96000, 48000, 44100, 32000, 22050, 16000, 11025, 8000};
BSP_AUDIO_Init_t AudioPlayInit;
/* Private function prototypes -----------------------------------------------*/
static void Audio_SetHint(uint32_t Index);
static uint32_t GetData(void *pdata, uint32_t offset, uint8_t *pbuf, uint32_t NbrOfData);
AUDIO_ErrorTypeDef AUDIO_Start(uint32_t *psrc_address, uint32_t file_size);
extern TS_Init_t hTS;
/* Private functions ---------------------------------------------------------*/
/**
* [url=home.php?mod=space&uid=159083]@brief[/url] Audio Play demo
* @param None
* @retval None
*/
void AudioPlay_demo(void)
{
uint32_t *AudioFreq_ptr;
uint32_t y_size,x_size;
uint32_t CurrentTickDetect =0;
uint32_t LastTSTick = 0;
uint32_t TS_Available = 1;
uint16_t x1, y1;
TS_State_t TS_State;
uint8_t VolStr[256] = {0};
uint8_t FreqStr[256] = {0};
int32_t ts_status = BSP_ERROR_NONE;
int32_t nor_status = BSP_ERROR_NONE;
Point Points2[] = {{226, 196}, {265, 223}, {226, 248}};
BSP_XSPI_NOR_Init_t NorInit;
BSP_LCD_GetXSize(0, &x_size);
BSP_LCD_GetYSize(0, &y_size);
AudioFreq_ptr = &AudioFreq[1]; /*48K*/
UserButtonPressed = 0;
uwPauseEnabledStatus = 1; /* 0 when audio is running, 1 when Pause is on */
uwVolume = 90;
Audio_SetHint(0);
UTIL_LCD_SetFont(&Font20);
UserButtonPressed = 0;
/* External Nor Flash initialization to get audio file from */
NorInit.InterfaceMode = MX66UW1G45G_OPI_MODE;
NorInit.TransferRate = MX66UW1G45G_DTR_TRANSFER;
if (BSP_XSPI_NOR_Init(0, &NorInit) != BSP_ERROR_NONE)
{
nor_status = BSP_ERROR_NO_INIT;
}
else if (BSP_XSPI_NOR_EnableMemoryMappedMode(0) != BSP_ERROR_NONE)
{
nor_status = BSP_ERROR_PERIPH_FAILURE;
}
if (nor_status != BSP_ERROR_NONE)
{
UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_WHITE);
UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_RED);
UTIL_LCD_DisplayStringAt(0, y_size - 95, (uint8_t *)"ERROR", CENTER_MODE);
UTIL_LCD_DisplayStringAt(0, y_size - 80, (uint8_t *)"NOR flash XSPI cannot be initialized", CENTER_MODE);
}
hTS.Width = x_size;
hTS.Height = y_size;
hTS.Orientation = TS_SWAP_NONE;
hTS.Accuracy = 10;
/* Touchscreen initialization */
ts_status = BSP_TS_Init(0, &hTS);
if (ts_status != BSP_ERROR_NONE)
{
UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_WHITE);
UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_RED);
UTIL_LCD_DisplayStringAt(0, y_size - 95, (uint8_t *)"ERROR", CENTER_MODE);
UTIL_LCD_DisplayStringAt(0, y_size - 80, (uint8_t *)"Touch Screen cannot be initialized", CENTER_MODE);
}
AudioPlayInit.Device = AUDIO_OUT_HEADPHONE;
AudioPlayInit.ChannelsNbr = 2;
AudioPlayInit.SampleRate = *AudioFreq_ptr;
AudioPlayInit.BitsPerSample = AUDIO_RESOLUTION_16B;
AudioPlayInit.Volume = uwVolume;
if(BSP_AUDIO_OUT_Init(0, &AudioPlayInit) != 0)
{
UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_WHITE);
UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_RED);
UTIL_LCD_DisplayStringAt(0, y_size - 95, (uint8_t *)" AUDIO CODEC FAIL ", CENTER_MODE);
UTIL_LCD_DisplayStringAt(0, y_size - 80, (uint8_t *)" Try to reset board ", CENTER_MODE);
}
/*
Start playing the file from a circular buffer, once the DMA is enabled, it is
always in running state. Application has to fill the buffer with the audio data
using Transfer complete and/or half transfer complete interrupts callbacks
(BSP_AUDIO_OUT_TransferComplete_CallBack() or BSP_AUDIO_OUT_HalfTransfer_CallBack()...
*/
AUDIO_Start((uint32_t *)AUDIO_SRC_FILE_ADDRESS + PLAY_HEADER, (uint32_t)AUDIO_FILE_SIZE);
while (1)
{
AUDIO_Process();
}
}
AUDIO_Start((uint32_t *)AUDIO_SRC_FILE_ADDRESS + PLAY_HEADER, (uint32_t)AUDIO_FILE_SIZE);
就是音频播放的开始。
uint8_t AUDIO_Process(void)就是从Flash存储中读取音乐文件。
AUDIO_Process();就是音乐循环反复播放音乐文件,这里用到了双缓冲DMA。
/**
* @brief Gets Data from storage unit.
* @param None
* @retval None
*/
static uint32_t GetData(void *pdata, uint32_t offset, uint8_t *pbuf, uint32_t NbrOfData)
{
uint8_t *lptr = pdata;
uint32_t ReadDataNbr;
ReadDataNbr = 0;
while(((offset + ReadDataNbr) < buffer_ctl.AudioFileSize) && (ReadDataNbr < NbrOfData))
{
pbuf[ReadDataNbr]= lptr [offset + ReadDataNbr];
ReadDataNbr++;
}
return ReadDataNbr;
}
/**
* @brief Manages Audio process.
* @param None
* @retval Audio error
*/
uint8_t AUDIO_Process(void)
{
uint32_t bytesread;
AUDIO_ErrorTypeDef error_state = AUDIO_ERROR_NONE;
switch(audio_state)
{
case AUDIO_OUT_STATE_PLAYING:
if(buffer_ctl.fptr >= buffer_ctl.AudioFileSize)
{
/* Play audio sample again ... */
buffer_ctl.fptr = 0;
error_state = AUDIO_ERROR_EOF;
}
/* 1st half buffer played; so fill it and continue playing from bottom*/
if(buffer_ctl.state == BUFFER_OFFSET_HALF)
{
bytesread = GetData((void *)buffer_ctl.SrcAddress,
buffer_ctl.fptr,
&buffer_ctl.buff[0],
AUDIO_BUFFER_SIZE /2);
if( bytesread >0)
{
buffer_ctl.state = BUFFER_OFFSET_NONE;
buffer_ctl.fptr += bytesread;
}
}
/* 2nd half buffer played; so fill it and continue playing from top */
if(buffer_ctl.state == BUFFER_OFFSET_FULL)
{
bytesread = GetData((void *)buffer_ctl.SrcAddress,
buffer_ctl.fptr,
&buffer_ctl.buff[AUDIO_BUFFER_SIZE /2],
AUDIO_BUFFER_SIZE /2);
if( bytesread > 0)
{
buffer_ctl.state = BUFFER_OFFSET_NONE;
buffer_ctl.fptr += bytesread;
}
}
break;
default:
error_state = AUDIO_ERROR_NOTREADY;
break;
}
return (uint8_t) error_state;
}
最后我们插上3.5mm耳机,烧录程序,就能听到流行音乐《秒针》响起,一起尽情摇摆吧!
[localvideo]f7e15894b95fcff90c7ed44dfeeb40f7[/localvideo]
-
回复了主题帖:
【STM32H7S78-DK】⑨TouchGFX项目实践:电子相册
lugl4313820 发表于 2024-10-28 19:29
能读SD卡或者从网络下载的图片吗?
肯定可以的,SD卡上Fatfs系统,再用STM32自带的JPG硬件解码工具解码后显示到TFT,网络下载图片同理。
只是这是比较复杂的系统,目前还没学习到那一步。:victory:
-
回复了主题帖:
《人工智能实践教程——从Python入门到机器学习》阅读分享二:面向对象及高级编程
风尘流沙 发表于 2024-10-28 10:22
谢谢楼主的分享,我去找书看一下。
一起学习进步{:1_144:}
-
回复了主题帖:
测评入围名单: 英飞凌PSOC™ 4100S Max Pioneer套件
计划确认,可以按时完成测评。感谢英飞凌和EE。
-
回复了主题帖:
【STM32H7S78-DK】⑨TouchGFX项目实践:电子相册
freebsder 发表于 2024-10-28 14:57
色调好像不是和原始图像匹配,有点深的样子。
这跟现在的手机拍照自动优化有很大关系,比如你拍蓝天,拍出来的比人眼看到的还要蓝。
你拍黑夜,拍出来的比真实看到的还要亮。
-
回复了主题帖:
【STM32H7S78-DK】⑨TouchGFX项目实践:电子相册
慕容雪花 发表于 2024-10-28 09:55
这分辨率,niu B!!!!
800*480 在5寸的面积上显示,效果确实很可以的。:loveliness:
- 2024-10-27
-
发表了主题帖:
【STM32H7S78-DK】⑨TouchGFX项目实践:电子相册
TouchGFX
在前面的帖子中,我们已经体验到TouchGFX与STM32绝配的功能及精美的显示效果。
本例我们将制作一款电子相册。
首先,欣赏几张美景,来自Bing Wallpaper,下载下来后,我们将分辨率调成800*480,图片格式调为PNG,单张图片1MB左右。
在TouchGFX Designer中新建4个SCREEN:
每个SCREEN插入一个图片:
为了实现电子相册的功能,我们还要加上图片自动切换的动作:
也就是在屏幕1~屏幕4分别加上动作:
屏幕1 500tick ——>切换到 屏幕2 500tick——>切换到 屏幕3 500tick——>切换到 屏幕4 500tick——>切换到 屏幕1 500tick——>……
实测在默认时钟下,500tick大约为8s,每个tick大约16ms。
然后生成工程,由于图片较大,该项目代码是要下载到外部Flash的,一定要进行外部Flash设定:
详见帖子:
https://bbs.eeworld.com.cn/thread-1295198-1-1.html
(其中最为关键的Boot_XIP.hex可以在该贴中下载到)
可以看到: text 足足3.3MB
代码段(text)、数据段(data)这两者相加共同构成可执行文件的大小
先编译下载Appli屏幕无反应,然后再编译下载Boot,就能正常显示了。
[localvideo]6a8b412ff8c2e9e4d3203c9078cfab19[/localvideo]
本次的分享就到这里,谢谢关注!
- 2024-10-14
-
回复了主题帖:
《动手学深度学习PyTorch版》阅读分享四 手写识别小试牛刀(基于CNN)
hellokitty_bean 发表于 2024-10-14 09:19
感谢分享呀。。。。。。。。。。。。。。。。。。。。。。
嘿嘿,大家共同进步。{:1_138:}
-
回复了主题帖:
【STM32H7S78-DK】⑧TouchGFX项目实践:触摸按钮翻转LED
wangerxian 发表于 2024-10-14 09:21
从屏幕到硬件的控制,后面就可以控制其他外设了。
对的,IO口的操作是最基础的程序,搞定这个就入门了,后面可以产花样上难度。:loveliness: