当前位置: 首页 > news >正文

【转载】STM32使用PWM驱动无源蜂鸣器实现8bit音乐播放

“力大砖飞”式播放音乐法,无需拿着乐谱转换音符,只需要一个音乐文件+你最亲爱的STM32开发板和他的无源蜂鸣器朋友,就能得到上世纪“最伟大的产物”----8bit音乐。不过,要保证你的STM32开发板内部的flash足够大呦~

 

基础知识

注意!!!参考文章点这里

  • 采样速率:指1s中采样多少个数据点,比如1s种采集16000个点,那么采样率就是16KHz。采样速率越高,越能抓到频率较高的声音,比如CD的采样率就是44.1KHz,确保人耳能听到的声音都会被抓到

  • 采样位数:指音频幅度最大值与最小值分为了多少阶,比如满幅度是3.3V,如果是8Bit位数,那么每一阶就是3.3V/256 = 12.89mv,采样位数越高,声音细节越好。所以采样速率和位数越高,声音还原越逼真,但存储的数据量也越大,一首三四分钟的歌曲,如果不采用编码按原始波形数据存储,数据量有好几十兆大小,这涉及到音频编码的问题

  • 如何播放

    1. 把采样(ADC)的数据按原样输出(DAC)

    2. 有些芯片本身不带有DAC,所以只能用PWM代替DAC,这里只需要把DAC的幅度值转换成PWM的占空比即可,例如16KHz 8Bit的声音转换成16Khz 256阶占空比的PWM。但有一个问题,如果用16KHz的PWM播放语音,声音是可以播放,但有一个16Khz的谐波存在,这个声音会被人耳听到,所以需要更高频率的PWM,数据还是按照16Khz更新

    3. 这里使用32KHz的PWM,用16KHz 无符号8Bit PCM格式的音频数据,8Bit的数据对应1个Byte,16KHz采样,1秒种占用存储空间就是16K Byte,换算可存储的时间为:Flash存储空间(单位转换成KB) / 16K。例如,2M Byte的Flash存储空间,理论上可以存储2048K/16K = 128秒的音频。

    4. 32K的TIM1播放,16K的TIM2中断更新

      在这里插入图片描述

音频处理

使用Audacity软件处理音频

在这里插入图片描述

打开要转换的音频文件

在这里插入图片描述

导出音频

在这里插入图片描述

配置导出设置

  • 单声道
  • 16000Hz采样
  • RAW格式
  • Unsigned 8-bit PCM 一定是无符号的这个

在这里插入图片描述

使用winhex软件获取数组

在这里插入图片描述

打开刚刚转换好的RAW文件

在这里插入图片描述

在数字区域“Ctrl+A”全选,依次点击:“编辑”—“复制选块”—“C源码”

在这里插入图片描述

新建一个H文件,“Ctrl+V”,粘贴到H文件中

在这里插入图片描述

添加预处理部分,注意要将数组名里的空格替换成下划线

在这里插入图片描述

在这里插入图片描述

STM32部分

beep_con.c

/*** @file        beep_con.c* @author      * @Version     V1.0* @date        * @brief       */
/* Includes ------------------------------------------------------------------*/
#include "beep_con.h"
/*刚刚处理的H文件*/
#include "cangcang8bit.h"
/* Private macro -------------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint32_t AudioDataAddr = 0;
uint32_t AudioDataLen = 0;Beep_sta con_sta = STOP;
/* Exported variables --------------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
void Beep_Init(void)
{AudioDataLen = ARRAY_LENGTH(AnsiChar_data);//在定时器开启前初始化获得数据长度
}void Beep_Con(Beep_sta sta)
{con_sta = sta;
}void HAL_TIM2_Callback(void)
{if(con_sta != STOP){if(con_sta == RES)AudioDataAddr = 0;//重置但不开始if(AudioDataAddr++ >= AudioDataLen){AudioDataAddr = 0;}
//		__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1,AnsiChar_data[AudioDataAddr]);//采用32K载波,ARR为256-1__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, (AnsiChar_data[AudioDataAddr] * 1800) >> 8);//采用40K载波,ARR为1800-1,需要从256映射到1800}
}

beep_con.h

#ifndef BEEP_CON_H
#define BEEP_CON_H
/* Includes ------------------------------------------------------------------*/
#include "tim.h"
/* Exported types ------------------------------------------------------------*/
typedef enum
{STOP=0,RUN=1,RES=2,
}Beep_sta;extern void Beep_Init(void);extern void Beep_Con(Beep_sta sta);extern void HAL_TIM2_Callback(void);#endif

main.c

/* USER CODE BEGIN 2 */Beep_Init();HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);    /*开启CH1的PWM输出*/HAL_TIM_Base_Start_IT(&htim2);
/* USER CODE END 2 */

stm32f1xx_it.c

void TIM2_IRQHandler(void)
{/* USER CODE BEGIN TIM2_IRQn 0 *//* USER CODE END TIM2_IRQn 0 */HAL_TIM_IRQHandler(&htim2);/* USER CODE BEGIN TIM2_IRQn 1 */HAL_TIM2_Callback();//16K中断调用/* USER CODE END TIM2_IRQn 1 */
}
http://www.jsqmd.com/news/1362507/

相关文章:

  • ​ ⛳️赠与读者[特殊字符]第一部分——内容介绍考虑多渗透率电动汽车接入的配电网承载能力评估研究摘要大规模电动汽车无序充电会加剧配电网电压越限、线路与变压器过载、负荷峰谷差扩大等运
  • 2026年芝麻白603路沿石直销厂商实力 - 热点品牌推荐
  • 前几天家庭聚会,我二叔喝了点酒
  • 【Bug已解决】`DiffusionPipeline.download()` breaks with huggingface_hub>=1.22.0 in offline mode (Incomple
  • 2026年实力之选:通州区伴侣宠物医院——南通宠物医疗领域的专业品牌机构 - 卓企推荐
  • Neural Amp Modeler:如何用3个步骤解决数字吉他音色的真实性问题
  • 深度解析php在网站后台建设中的优势 张晋芳揭秘高效开发核心逻辑
  • Libre Barcode字体:5分钟学会生成专业条码的终极免费方案
  • 【电商项目】商品规格模块实现过程中的一些思考与报错修正
  • CaptchaHarvester浏览器自动化原理:Chromium代理配置与多域名拦截技术
  • 如何用JXBanner打造吸睛App轮播?从安装到高级配置完整指南
  • G-Helper终极指南:华硕笔记本性能调优的完整解决方案
  • FinalBurn Neo:如何在多平台上重温经典街机游戏的终极指南
  • 丑数家族大揭秘:从堆解法到多指针DP手撕两道经典算法题
  • 深度剖析猫抓Cat-Catch:浏览器扩展架构演进与模块化设计的技术决策
  • Zotero MCP终极指南:如何让AI助手成为你的智能研究伙伴
  • mlx-community/DeepSeek-V4-Pro-Qwen3.5-9B-4bit:终极4bit量化多模态模型震撼登场!一文看懂核心优势
  • Less安全特性完全指南:如何在受限环境中安全使用文本查看器
  • 多模态边缘AI的工程突围:从TinyML到异构加速的计算范式革命
  • 钉钉、飞书、企业微信之后,企业如何规划私有化替代? - BeeWorks
  • GraphQL-CSS API全解析:useGqlCSS、GqlCSS组件与getStyles实用指南
  • 从79%用户行为集中度,解析流量高峰下的产品设计与数据洞察
  • AI 数字人合规安全完全手册(2026年8月最新版)
  • 面对Astra等新AI模型,开发者如何构建技术评估与工程化实践框架
  • Dashibase性能优化指南:缓存策略与数据库查询效率提升技巧
  • 5步掌握开源无人机影像三维建模:OpenDroneMap全流程指南
  • 从零开始掌握Ryujinx:高性能Switch模拟器完整使用指南
  • Webpack 构建优化与工程规范治理:代码评审该盯住哪些细节
  • 边缘AI部署实战:从模型量化到硬件加速(electronica 2026趋势启示)
  • SwarmForge安全加固:保护AI代理免受恶意输入的影响