基于STM32的录音与播音

基于STM32的录音与播音

设计方案

本设计通过STM32的内置ADC加一个麦克风和放大电路(可以在网上买模块)实现音频的采集,然后存放在SD卡中(这里可以参考我之前的博客FATFS文件系统),然后再读取SD卡里存放的数据通过单片机的内置DAC接一个放大电路和一个喇叭(可以在网上买模块)进行音频播放(参考我前面的博客)。再进行ADC采集和DAC输出时是借助定时器中断,设置定时器的频率就可以设置ADC和DAC的频率了。

通过STM32CUBEMX配置工程

1、配置SDIO和FATFS

参考我前面的博客。https://blog.csdn.net/qq_53000374/article/details/126390968

2、配置DAC和定时器

参考我前面的博客。https://blog.csdn.net/qq_53000374/article/details/126272701

3、配置ADC和定时器

这里只需要配置ADC,定时器和DAC共用一个。
在这里插入图片描述
其他的不用管。

添加代码


//main前面
#include "string.h"
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#define KEY0	HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)
#define KEY1	HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)#define	val_count_max		5000  //最大采样个数
uint16_t val_count=0;    //实际采样个数uint16_t val_data[val_count_max]={0};   
uint16_t val_data_buff[val_count_max]={0};#define DAC_Count 4096
uint8_t DAC_Data[5000]={0};uint16_t DAC_F=2;  
volatile  uint16_t Time_Count=0;char* ch_tab="12345";char read_buff[100]={0};FATFS fs;  //文件系统工作区指针
FIL fp;   //文件对象结构指针
FRESULT f_res;  //函数放回结果
uint16_t fnum;               /* 文件成功读写数量 */uint16_t fp_num;   //文件大小
UINT fp_rw_num;  //实际文件读写字节数uint8_t fp_wriet_flag=0;  //SD卡写标志
uint8_t sound_record_flag=0;   //录音标志uint8_t fp_read_flag=0;  //SD卡读标志
uint8_t play_record_flag=0;   //播音标志uint8_t key0_down_flag=0;  //按键按下一次标志,
uint8_t key1_down_flag=0;  //按键按下一次标志,uint16_t fp_memory=0;char Read_Data[DAC_Count]={0};
/* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */void KEY_Scanf()
{if(KEY0 == 0)  //录音开始和停止{HAL_Delay(10);if(KEY0==0){while(!KEY0);key0_down_flag=0;sound_record_flag = !sound_record_flag;  //0:停止  1:开始}}if(KEY1 == 0){HAL_Delay(10);if(KEY1==0){while(!KEY1);key1_down_flag=0;play_record_flag = !play_record_flag;}}
}void KEY_Handle(void)  
{if((sound_record_flag != 0) && (key0_down_flag==0))  //开始录音{key0_down_flag=1;val_count=0;HAL_TIM_Base_Start_IT(&htim3);HAL_ADC_Start(&hadc1);}else if((sound_record_flag == 0) && (key0_down_flag==0))  //停止录音{key0_down_flag=1;HAL_TIM_Base_Stop_IT(&htim3);HAL_ADC_Stop(&hadc1);f_close(&fp);f_mount(NULL,"0:",1);		 //取消挂载}if((play_record_flag !=0) && (key1_down_flag==0))  //开始播音{key1_down_flag=1;HAL_TIM_Base_Start_IT(&htim3);HAL_ADC_Start(&hadc1);//在外部 SD 卡挂载文件系统,文件系统挂载时会对 SD 卡初始化f_res = f_mount(&fs, "0:", 1);	f_res = f_open(&fp, "0:ADC_DATA.txt", FA_OPEN_EXISTING | FA_READ);if(f_res==FR_OK){f_lseek(&fp, 44);  //偏移文件起始位置44个字节,后面的就是所需要的数据fp_memory=f_size(&fp);printf("文件大小:%d\r\n",fp_memory);}}else if((play_record_flag ==0) && (key1_down_flag==0)){key1_down_flag=1;HAL_TIM_Base_Stop_IT(&htim3);HAL_ADC_Stop(&hadc1);f_close(&fp);f_mount(NULL,"0:",1);		 //取消挂载	}
}void FILE_RW_Test(void)   //文件系统读写测试
{printf("挂载SD卡驱动\r\n");f_res=f_mount(&fs,"0:",1);f_unlink("0:ADC_DATA.txt");if(f_res == FR_OK){printf("挂载成功\r\n");f_res=f_open(&fp,"0:ADC_DATA.txt",FA_WRITE | FA_OPEN_ALWAYS);if(f_res == FR_OK){printf("文件打开成功\r\n");f_res=f_write(&fp,tab,10,&fp_rw_num);if(f_res == FR_OK){printf("写入成功\r\n实际写入字节数:%d\r\n",fp_rw_num);}}}f_close(&fp);f_res=f_open(&fp,"0:ADC_DATA.txt",FA_READ | FA_OPEN_ALWAYS);if(f_res == FR_OK){printf("文件打开成功\r\n");f_res=f_read(&fp,read_buff,5,&fp_rw_num);if(f_res == FR_OK){printf("读取成功\r\n");printf("%s\r\n",read_buff);}}
}void Audio_SD_Write(void)
{if(fp_wriet_flag == 1){fp_wriet_flag = 0;f_res=f_mount(&fs,"0:",1);if(f_res == FR_OK){printf("挂载成功\r\n");}elseprintf("挂载失败\r\n");f_res=f_open(&fp,"0:ADC_DATA.txt",FA_OPEN_ALWAYS | FA_WRITE);if(f_res == FR_OK)printf("文件打开成功\r\n");elseprintf("打开失败\r\n");f_lseek(&fp, f_size(&fp));//确保写词写入不会覆盖之前的数据f_res=f_write(&fp,val_data_buff,4096,&fp_rw_num);if(f_res == FR_OK){memset(val_data_buff,0,5000);printf("写入成功\r\n实际写入字节数:%d\r\n",fp_rw_num);}elseprintf("写入失败\r\n");}f_close(&fp);f_mount(NULL,"0:",1);		 //取消挂载	
}void Audio_SD_Read(void)
{if(Time_Count>=fnum){  //当DAC输出的字节大于等于读取到的字节数Time_Count = 0;memset(DAC_Data,0,sizeof(DAC_Data));  //清空数组f_res=f_read(&fp,Read_Data,4096,(UINT*)&fnum);//读出4096个字节  memcpy(DAC_Data,Read_Data,fnum);  //数组复制}if(f_eof(&fp)) //已经读取完了{f_lseek(&fp, 44);  //跳过前面44个字节}
}
/* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
int wd4;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance == TIM3){if((sound_record_flag !=0) && (play_record_flag ==0)){val_data[val_count]=HAL_ADC_GetValue(&hadc1);val_count++;if(val_count == 2048){memcpy(val_data_buff,val_data,sizeof(val_data));val_count=0;fp_wriet_flag=1;}}if((sound_record_flag ==0) && (play_record_flag !=0)){Time_Count += DAC_F;wd4 = ((DAC_Data[Time_Count-1]-0x80)<<8)|(DAC_Data[Time_Count-2]);   //将16位的音频数据转为12位。wd4 = 0xfff & (wd4>>4);HAL_DAC_SetValue(&hdac,DAC_CHANNEL_2,DAC_ALIGN_12B_R,wd4);//12位右对齐数据格式设置DAC值}}
}//main里面
HAL_DAC_Start(&hdac,DAC_CHANNEL_2);HAL_TIM_Base_Stop_IT(&htim3);HAL_ADC_Stop(&hadc1);HAL_Delay(1);//	FILE_RW_Test();  //测试函数/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){KEY_Scanf();KEY_Handle();if((sound_record_flag !=0) && (play_record_flag ==0))Audio_SD_Write();  //录音else if((sound_record_flag ==0) && (play_record_flag !=0))Audio_SD_Read();  //播音}/* USER CODE END WHILE */

过程中遇到的问题

我在过程中遇到一个问题,就是在进行SD卡写数据时,一直循环写数据会出现写入失败的情况,我在网上找到几个可能的原因:
STM32读写SD卡

问题1:在循环进行写SD卡时,会出来写多次后出现写错误的情况。

问题原因1:

​ 可能是通过APB2总线往FIFO装填数时,发生了中断,导致总线被占用或其他资源被占用,从而无法及时完成FIFO的装填,而后面从FIFO取数的频率又非常快,导致无法取到数。

解决方案1:

​ 在调用f_write之前调用 __disable_irq() 接口关闭中断,写操作完成后调用 __enable_irq()接口启用中断:

__disable_irq();

if(FR_OK ==f_write())

{ }

else

{}

__disable_irq() ;

优点:简单

缺点:在写操作期间CPU无法响应中断

问题原因2:

​ SD卡写的时候出现了坏块,导致写不成功,在写失败时需要重试一下。

解决方案2:

​ 重写bsp_driver_sd.c文件中的BSP_SD_WriteBlocks函数是_weak 函数,可以在自己的源文件myfile.c中重写该函数,当写发生错误后,清除错误标记,再重试几次即可,在我的单片机上,一般第一次重试即可成功

uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout)

{

​ int i;

​ for (i = 1; i <= TY_SDIO_RETRY_MAX; i ++)

​ {

​ if (HAL_SD_WriteBlocks(&hsd, (uint8_t *)pData, WriteAddr, NumOfBlocks, Timeout) == HAL_OK)

​ {

​ if (i > 1)

​ printf(“[INFO] SDIO writing succeeded: retry %d.\n”, i);

​ return (MSD_OK); // Succeeded

​ }

​ else

​ {

​ printf(“[ERROR] SDIO writing failure: retry %d, error code %#x, addr %#x, %u blocks.\n”,

​ i, hsd.ErrorCode, WriteAddr, NumOfBlocks);

​ HAL_SD_Abort(&hsd); //clear error flag

​ }

​ }

​ return (MSD_ERROR);

}

优点:上层应用软件不需要更改,也不需要禁用中断

缺点:频率较高时(我的是30MHZ)时,经常会发生写重试

问题原因3:

​ 写速度太快,导致FIFO来不及装填,产生错误,需要降速。

解决方案3:

​ 更改sdio.c中的MX_SDIO_SD_Init函数,将hsd.Init.ClockDiv设置为48分频,即SDIO的频率为主频除以48,我这里为72/48=1.5MHz。

优点:非常简单;无需禁用中断;无需对上层软件进行修改。

缺点:降低了写速度

我这里选择的时第3种,降低SD卡的读写速度
在这里插入图片描述
将这里的分频系数修改为48,速度就为72MHz/48.

注意事项:

​ 在挂载SD卡,文件打开,完成一次读或写操作之后,要尽量关闭文件,取消SD卡挂载,下一次操作重新挂载和打开。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/16393.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

海威超市播音源码+成品

源码介绍&#xff1a; 目前一直在用的超市播音软件&#xff0c;送给不会编程的人&#xff0c;下载后打开直接可用&#xff01;会编程的人&#xff0c;可以修改后使用&#xff01; 网盘下载地址&#xff1a; http://www.bytepan.com/8sfiNvAioAc 图片&#xff1a;

基于WASAPI的录音播音系统

最近写了一个小的系统&#xff0c;在VS2022平台上做的&#xff0c;主要是通过调用Windows的API接口实现录音&#xff08;PCM格式&#xff09;&#xff0c;播音&#xff08;PCM、WAV、Mp3格式&#xff09;&#xff0c;PCM格式转WAV格式、遍历指定文件夹下的所有音频文件并播放。…

播音计算机论文,广播中计算机的应用论文

广播中计算机的应用论文 引言 随着社会的发展&#xff0c;人们的物质生活水平也在提高。而在这种发展趋势下&#xff0c;人们对精神生活水平也提出了新的要求。面对这些要求&#xff0c;传统的广播电视技术的应用已经无法满足广播事业的发展需要。而计算机技术的应用&#xff0…

学校的校园广播是如何设置的

9月开学季&#xff0c;各个校园的广播也开始播音了&#xff0c;随着互联网的发展&#xff0c;现在很多校园使用的都是播音软件&#xff0c;通过软件来操作可以节省人力&#xff0c;可以设置一次性、每天、每周、每月定时播放&#xff0c;支持开机自动运行。学校可自动定时广播打…

chatgpt赋能python:Python抄股票的秘诀

Python 抄股票的秘诀 在股票市场中&#xff0c;抄股票是许多投资者都会尝试的一种方式。然而&#xff0c;随着市场变化和行情的波动&#xff0c;抄股票并不是一件容易的事情。但是&#xff0c;有了 Python&#xff0c;我们可以利用其强大的数据处理和可视化功能来进行股票分析…

chatgpt赋能python:学Python炒股:聪明投资策略

学Python炒股&#xff1a;聪明投资策略 在金融市场中&#xff0c;投资者要获取财务知识并实际操作从而创造财富。多年来&#xff0c;投资者一直在寻找有效的技术分析手段&#xff0c;并逐步将其用于各种产品。Python在这方面提供了先进的技术&#xff0c;其跨平台的特性和Pyth…

chatgpt赋能python:利用Python炒股:一篇详细的指南

利用Python炒股&#xff1a;一篇详细的指南 炒股是许多人致富的途径。随着技术的发展&#xff0c;现在在线炒股已经变得越来越普及。在这个数字时代&#xff0c;Python提供了一个强大的数据分析和编程工具&#xff0c;可以帮助投资者更好地研究股市行情和制定更好的交易策略。…

chatgpt赋能python:用Python炒股效益如何?

用Python炒股效益如何&#xff1f; 介绍 随着互联网的不断发展&#xff0c;越来越多的人开始尝试使用Python来炒股。Python作为一种强大的编程语言&#xff0c;其在数据分析和机器学习领域拥有广泛的应用。而在股票投资领域&#xff0c;Python的优势也逐渐显现。 Python在股…

chatgpt赋能python:Python对炒股有用吗?

Python对炒股有用吗&#xff1f; 随着互联网的快速发展&#xff0c;炒股已经成为越来越多人的投资选择。而Python作为一种流行的编程语言&#xff0c;也逐渐被越来越多的投资者应用在炒股分析中。那么&#xff0c;Python对炒股有用吗&#xff1f;这是本文要探讨的问题。 Pyth…

飞书发送消息

import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpResponse; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSON; import cn.hutool.json.JSONUtil;import java.util.HashMap; import java.util.Map;/*** 飞书工具* author: czy* date: 2022-9-14*/ p…

​华为回应出售手机业务传闻:假消息;微软将ChatGPT整合到更多工具中:不用写代码就能开发应用;苹果更新Mac产品线|极客头条...

「极客头条」—— 技术人员的新闻圈&#xff01; CSDN 的读者朋友们早上好哇&#xff0c;「极客头条」来啦&#xff0c;快来看今天都有哪些值得我们技术人关注的重要新闻吧。 整理 | 梦依丹 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; 一分钟速览新闻点&#…

狂飙!GPT-4最新20+个应用案例集锦,附视频

编者按&#xff1a;自OpenAI于3月15日重磅推出GPT-4,一石激起千层浪&#xff0c;全球开发者、创业者们迅速尝试了各种形形色色的场景应用&#xff0c;来体验它的极限&#xff0c;游戏、编程、客户关系、营销、财务、家庭生活、饮食、文学艺术创作等等不一而足。笔者从中筛选了2…

狂团KtAdmin框架正式免费开源发布,助力独立版SAAS系统快速开发

狂团&#xff08;kt8.cn&#xff09;旗下[ KtAdmin ]是为独立版SAAS系统而生的快速开发框架&#xff01; KtAdmin 基于当前流行的ThinkPHP6.xVue3ElementuiVite 开发 , 是一款免费开源的多用户&#xff0c;多应用的独立版SAAS系统开发框架。 【注】[KtAdmin]遵循较为宽松的Ap…

Visual ChatGPT原理解读——大模型论文阅读笔记四

论文&#xff1a;https://arxiv.org/abs/2303.04671 代码&#xff1a;https://github.com/microsoft/TaskMatrix 一. 整体框架 如图所示&#xff0c;用户上传一张黄花的图像并输入一个复杂的语言指令“请根据该图像的预测深度生成一朵红花&#xff0c;然后逐步使其像卡通一样”…

探索 SolidJS,一起体验开源项目(solidjs-use)的乐趣

大厂技术 高级前端 Node进阶 点击上方 程序员成长指北&#xff0c;关注公众号 回复1&#xff0c;加入高级Node交流群 前言 如果你是 React 技术栈&#xff0c;就会发现其对新手其实是不太友好的&#xff0c;会导致新人写出很多重复渲染的组件和 BUG&#xff0c;而且排查难度高…

【人话版】关于“AI替代程序员“的7点碎碎念

都说AI替代这个替代那个&#xff0c;不用浪费时间为这种问题焦虑&#xff0c;因为答案已经越来越明显了... 关键是&#xff0c;什么时候&#xff1f;怎么替&#xff1f;。 1) 设想一个场景&#xff0c;有个需求要用某个技术或某个框架实现&#xff0c;有两个程序员对这些都不是…

未来几年GPT/大模型如何影响软件研发?

具有强大能力的GPT-4横空出世&#xff0c;让我们眼前一亮、惊讶于它能够执行一系列复杂的任务&#xff0c;如代码生成、错误检测、软件设计等&#xff0c;所以我们有必要来探讨一下GPT-4这类多模态语言模型会给软件研发带来怎样的影响&#xff1f;它会重新定义软件开发的新范式…

chatgpt赋能python:Python编程入门指南:Python花钱吗?

Python编程入门指南&#xff1a;Python花钱吗&#xff1f; Python是一个开源、免费的编程语言&#xff0c;当然&#xff0c;这是大家最常听到的关于Python的优点之一。但也有些开发者在使用Python时&#xff0c;会遇到一些需要花费资金的情况。那么&#xff0c;Python到底花钱…

1.2万Star!无差体验GPT-4识图能力,MiniGPT-4看图聊天、还能草图建网站

©作者 | 机器之心编辑部 来源 | 机器之心 GPT-4 已经发布一个多月了&#xff0c;但识图功能还是体验不了。来自阿卜杜拉国王科技大学的研究者推出了类似产品——MiniGPT-4&#xff0c;大家可以上手体验了。 对人类来说&#xff0c;理解一张图的信息&#xff0c;不过是一件…

闻达(Wenda):基于Chatglm6b的知识库+大语言模型融合项目

背景&#xff1a; 随着ChatGPT模型的一炮而红&#xff0c;大语言模型已然风靡全球&#xff0c;成为了全世界闪烁的焦点。目前&#xff0c;越来越多的研发人员投入到大语言模型的扩展开发中&#xff0c;闻达&#xff08;Wenda&#xff09;便是其中一项重要成果。 闻达源于清华大…