用于将音频文件录制到 ISD1700 芯片的软件
组件和用品
| × | 1 | ||||
| × | 2 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 2 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
应用和在线服务
| ||||
|
关于这个项目
在我最近的一个项目中,我需要添加短文本消息的语音。像带有 SD 卡的 MP3 模块之类的屏蔽在我看来是多余的,而“教”Arduino 重现人类语音将意味着仅将微控制器的所有资源都用于这项任务,这实际上是辅助任务。而且无论如何我都会耗尽内存。
简单搜索发现ISD1700系列录音回放芯片,SPI控制,可存储长达几分钟的信息。
语音消息是事先以单独文件的形式准备好的。唯一的问题是如何将这些记录到 IC 存储器中。 ISD1700 的编程器普及度不高,成本远高于芯片本身。有一些关于如何构建一个的信息 (https://laserwar.ru/sound_lasertag.html),但我是一名程序员而不是无线电爱好者,所以我想使用标准硬件——Arduino 板非常适合这个角色。
在研究了数据表(《ISD1700 设计指南》)后,我意识到有一个模拟输入可以记录文件。对于流程自动化,我决定编写特殊软件 - ISD1700 Record Tool。
ISD1700 录音工具允许您通过 Arduino 板将一组音频文件录制到 ISD1700 中。该软件由两部分组成:Arduino 板的草图 (ISD1700.ino ) 和独立的 Windows 应用程序 (ISD1700.exe ).
ISD1700.ino 中的草图 是为基于 ATMega328P 的 ARUINO 开发板编写的(在 Arduino Uno 和 Arduino Nano 上测试),但可能也适用于其他开发板。
支持的 ISD1700 列表:
1) ISD1730;
2) ISD1740;
3) ISD1750;
4) ISD1760;
5) ISD1790;
6) ISD17120;
7) ISD17150;
8) ISD17180;
9) ISD17210;
10) ISD17240。
Windows 应用程序基于 BASS 音频库,支持最广泛使用的格式:MP3、WAV、OGG 等。
1.硬件连接
在软件开发期间,我使用现成的录音模块而不是单独的 ISD1700 IC。在尝试任何其他可能的连接变体之前,我强烈建议您阅读原始 ISD1700 数据表。
图 1-5 显示了我的硬件设置。本例中使用的是ARDUINO NANO。
在一块小面包板上,我放了两个 3.5 毫米插孔(图 2),用于音频输入(左)和耳机(右)。
我建议使用额外的电源单元,而不是通过 Arduino 的 5V 输出为所有组件供电,因为我在没有外部电源的情况下有很多连接错误。但是,这可能是由于电线连接质量差或其他原因造成的。
2. 闪烁 Arduino
通过 USB 将 Arduino 板连接到您的 PC,打开 ISD1700.ino 在 ADUINO IDE 中并照常上传草图(图 6)。
3. 应用用户界面
运行 ISD1700.exe .各控制元件的说明如图7所示。
4. 典型操作顺序
图 8 显示了 Windows 应用程序中的典型操作顺序。
说明:
1. 打开要录制到 ISD1700 的音频文件。只需通过鼠标拖动即可对它们进行排序,或者在必要时删除不需要的文件(之前已检查过)。您还可以播放每个文件并调整音量。
2. 选择ARDUINO板所连接的COM端口(图9)。
3、点击“检测ISD1700”按钮,确认右侧框中显示的是ISD1700的型号。
4.确保所有音频文件的总时长以秒为单位小于ISD1700容量;否则您将无法开始录制。
5. 按“开始记录”按钮。您可以在栏上看到进度。必要时按“停止记录”。
6. 处理完成后,您可以将所有曲目的地址复制到剪贴板。图 10 显示了两个选项之间的差异。
使用ISD1700录音模块,在录音完成后,借助耳机和板载按键,即可播放音频文件。
代码
- ISD1700 ARDUINO 代码
ISD1700 ARDUINO 代码C/C++
// ISD1700 记录工具的 Arduino 代码// 测试:Arduino Uno、Arduino Nano (ATMega328P)// 版权所有:Anton Tsaritsynskyy,2019 年 8 月// 电子邮件:[email protected]//// 这软件按“原样”提供,不提供任何保证。// 作者不对因使用该软件而造成的任何不良影响负责。// 不允许对本软件进行商业分发。// 第三方库和组件是其财产#includeconst unsigned int ISD_ERASE_OK =3002;const unsigned int ISD_REC_OK =3003;const unsigned int ISD_STOP_OK =3004;const unsigned int ISD_RESET_OK =3005;const unsigned int ISD_CANCEL_OK =3003;const unsigned int ISD_CANCEL_OK =3006 int 3007;const 字节 ISD_SS_PIN =8;boolean isdIsUp =false;boolean isdNotifyIfFull =true;boolean isdPowerUp(void) { byte SR0B1 =1; SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE3));数字写入(ISD_SS_PIN,低); SR0B1 =SPI.transfer(0x01); SPI.transfer(0x00);数字写入(ISD_SS_PIN,高); SPI.endTransaction();返回 (SR0B1 &1) !=1; }boolean isdPowerDown(void) { SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE3));数字写入(ISD_SS_PIN,低); SPI.传输(0x07); SPI.transfer(0x00);数字写入(ISD_SS_PIN,高); SPI.endTransaction();}boolean isdReset(void) { SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE3));数字写入(ISD_SS_PIN,低); SPI.传输(0x03); SPI.transfer(0x00);数字写入(ISD_SS_PIN,高); SPI.endTransaction();延迟(20);}void isdClrInt(void){ SPI.beginTransaction(SPISettings(1000000,LSBFIRST,SPI_MODE3));数字写入(ISD_SS_PIN,低); SPI.transfer(0x04); SPI.transfer(0x00);数字写入(ISD_SS_PIN,高); SPI.endTransaction();}boolean isdIsReady(void) { byte SR1 =0; SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE3));数字写入(ISD_SS_PIN,低); SPI.transfer(0x05); SPI.transfer(0x00); SR1 =SPI.transfer(0x00);数字写入(ISD_SS_PIN,高); SPI.endTransaction();返回 (~SR1 &1) !=1; }void isdEnableAnaIn(void) { 字节 APC[2]; SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE3));数字写入(ISD_SS_PIN,低); SPI.transfer(0x44); SPI.transfer(0x00); APC[0] =SPI.transfer(0x00); APC[1] =SPI.transfer(0x00);数字写入(ISD_SS_PIN,高); SPI.endTransaction(); APC[0] &=~B01010000; SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE3));数字写入(ISD_SS_PIN,低); SPI.transfer(0x45); SPI.transfer(APC[0]); SPI.transfer(APC[1]);数字写入(ISD_SS_PIN,高); SPI.endTransaction();}byte isdDeviceID(void) { byte ID; SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE3));数字写入(ISD_SS_PIN,低); SPI.transfer(0x09); SPI.transfer(0x00); ID =SPI.transfer(0x00);数字写入(ISD_SS_PIN,高); SPI.endTransaction();返回 ID;}布尔值 isdIsFull(void) { 字节 SR0B1 =2; SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE3));数字写入(ISD_SS_PIN,低); SR0B1 =SPI.transfer(0x05); SPI.transfer(0x00); SPI.transfer(0x00);数字写入(ISD_SS_PIN,高); SPI.endTransaction();返回 (SR0B1 &2) ==2; }void isdRec(void) { SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE3));数字写入(ISD_SS_PIN,低); SPI.transfer(0x41); SPI.transfer(0x00);数字写入(ISD_SS_PIN,高); SPI.endTransaction();延迟(40);}void isdStop(void){ SPI.beginTransaction(SPISettings(1000000,LSBFIRST,SPI_MODE3));数字写入(ISD_SS_PIN,低); SPI.transfer(0x02); SPI.transfer(0x00);数字写入(ISD_SS_PIN,高); SPI.endTransaction();延迟(100);}void isdErase(void){ SPI.beginTransaction(SPISettings(1000000,LSBFIRST,SPI_MODE3));数字写入(ISD_SS_PIN,低); SPI.transfer(0x43); SPI.transfer(0x00);数字写入(ISD_SS_PIN,高); SPI.endTransaction(); while ( !isdIsReady() ) {} }unsigned int isdReadRecordPointer(void) { byte DB[2]; SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE3));数字写入(ISD_SS_PIN,低); SPI.transfer(0x08); SPI.transfer(0x00); DB[0] =SPI.transfer(0x00); DB[1] =SPI.transfer(0x00);数字写入(ISD_SS_PIN,高); SPI.endTransaction();返回 (DB[1] <<8) | DB[0];}unsigned int isdInit(void) { while (!isdPowerUp() ) {} delay(100); isdClrInt(); while ( !isdIsReady() ) {} isdEnableAnaIn(); return 3000+isdDeviceID();}void setup() { pinMode(ISD_SS_PIN, OUTPUT);数字写入(ISD_SS_PIN,高); Serial.begin(9600); SPI.begin(); }字符命令; void loop() { if (Serial.available()) { cmd =Serial.read(); switch (cmd) { case 'D':Serial.print( isdInit() ); isdPowerDown(); isdIsUp =假;休息;案例'E':isdInit(); isdErase(); Serial.print(ISD_ERASE_OK); isdIsUp =真; isdNotifyIfFull =true;休息;案例'R':isdRec(); Serial.print(ISD_REC_OK);休息;案例'S':isdStop(); Serial.print( isdReadRecordPointer() );休息;案例'X':isdReset(); Serial.print(ISD_RESET_OK); isdIsUp =假;休息; case 'C':if (isdIsUp) { isdStop(); isdReset(); Serial.print(ISD_CANCEL_OK); isdIsUp =假; } 休息; } } if (isdNotifyIfFull &&isdIsUp) { if (isdIsFull()) { isdReset(); isdIsUp =假; Serial.print(ISD_FULL); isdNotifyIfFull =false; } }}
示意图
制造工艺