Мне понадобилось запустить модуль MP3-TF-16P в режиме проигрывания случайных треков. К сожалению, плеер сам не стартует воспроизведение при подаче питания. Необходима какая-либо команда — либо закоротить соответствующую ножку, либо подавать сигналы. На ножках функционал ограничен — только трек «плюс»/»минус». А вот согласно талмуда на модуль он поддерживает режим случайного выбора аудиофайлов (играет бесконечно), — для этого достаточно подать по UART посылку: 7E FF 06 18 00 00 00 EF. Но использование для этого отдельной платы (типа ардуины) как-то увеличивает конструкцию. Хотелось-бы заминималистичить всё это..
Я уже рассказывал несколько лет назад о чипах STC15W20x. Это китайские ноу-хау, которые они паяют во всё что можно. Прошиваются предельно просто, программы пишутся тоже легко, используя многочисленные примеры. Схема незамысловатая — подаём на STC питание (выв.2 «+», а выв.4 «GND»), а TX (выв.6) uart-а соединяем с RX-ом mp3-модуля. Дополнительно подключил D+ и D- от USB, что позволяет при подключении к ПК видеть карту как флешку, проигрывание в этом случае невозможно.
Видео работы можно посмотреть на ютубе. Как программировать STC я рассказывал в этой статье. Прошивка HEX здесь (546 байт). Проект для Keil тутака.
#include "reg51.h" #include "intrins.h" typedef unsigned char BYTE; typedef unsigned int WORD; #define FOSC 11059200L //系统频率 #define BAUD 9600 //串口波特率 #define NONE_PARITY 0 //无校验 #define ODD_PARITY 1 //奇校验 #define EVEN_PARITY 2 //偶校验 #define MARK_PARITY 3 //标记校验 #define SPACE_PARITY 4 //空白校验 #define PARITYBIT NONE_PARITY //定义校验位 sfr P0M1 = 0x93; sfr P0M0 = 0x94; sfr P1M1 = 0x91; sfr P1M0 = 0x92; sfr P2M1 = 0x95; sfr P2M0 = 0x96; sfr P3M1 = 0xb1; sfr P3M0 = 0xb2; sfr P4M1 = 0xb3; sfr P4M0 = 0xb4; sfr P5M1 = 0xC9; sfr P5M0 = 0xCA; sfr P6M1 = 0xCB; sfr P6M0 = 0xCC; sfr P7M1 = 0xE1; sfr P7M0 = 0xE2; sfr AUXR = 0x8e; //辅助寄存器 sfr T2H = 0xd6; //定时器2高8位 sfr T2L = 0xd7; //定时器2低8位 sfr P_SW1 = 0xA2; //外设功能切换寄存器1 #define S1_S0 0x40 //P_SW1.6 #define S1_S1 0x80 //P_SW1.7 sbit P22 = P2^2; bit busy; void Delay1500ms(); void SendData(BYTE dat); void main() { P0M0 = 0x00; P0M1 = 0x00; P1M0 = 0x00; P1M1 = 0x00; P2M0 = 0x00; P2M1 = 0x00; P3M0 = 0x00; P3M1 = 0x00; P4M0 = 0x00; P4M1 = 0x00; P5M0 = 0x00; P5M1 = 0x00; P6M0 = 0x00; P6M1 = 0x00; P7M0 = 0x00; P7M1 = 0x00; ACC = P_SW1; ACC &= ~(S1_S0 | S1_S1); //S1_S0=0 S1_S1=0 P_SW1 = ACC; //(P3.0/RxD, P3.1/TxD) #if (PARITYBIT == NONE_PARITY) SCON = 0x50; //8位可变波特率 #elif (PARITYBIT == ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY) SCON = 0xda; //9位可变波特率,校验位初始为1 #elif (PARITYBIT == SPACE_PARITY) SCON = 0xd2; //9位可变波特率,校验位初始为0 #endif T2L = (65536 - (FOSC/4/BAUD)); //设置波特率重装值 T2H = (65536 - (FOSC/4/BAUD))>>8; AUXR = 0x14; //T2为1T模式, 并启动定时器2 AUXR |= 0x01; //选择定时器2为串口1的波特率发生器 ES = 1; //使能串口1中断 EA = 1; Delay1500ms(); SendData(0x7E); // 7E FF 06 18 00 00 00 EF SendData(0xFF); SendData(0x06); SendData(0x18); SendData(0x00); SendData(0x00); SendData(0x00); SendData(0xEF); while(1); } void Delay1500ms() //@11.0592MHz { unsigned char i, j, k; _nop_(); _nop_(); i = 64; j = 9; k = 179; do { do { while (--k); } while (--j); } while (--i); } /*---------------------------- UART 中断服务程序 -----------------------------*/ void Uart() interrupt 4 using 1 { if (RI) { RI = 0; //清除RI位 P0 = SBUF; //P0显示串口数据 P22 = RB8; //P2.2显示校验位 } if (TI) { TI = 0; //清除TI位 busy = 0; //清忙标志 } } /*---------------------------- 发送串口数据 ----------------------------*/ void SendData(BYTE dat) { while (busy); //等待前面的数据发送完成 ACC = dat; //获取校验位P (PSW.0) if (P) //根据P来设置校验位 { #if (PARITYBIT == ODD_PARITY) TB8 = 0; //设置校验位为0 #elif (PARITYBIT == EVEN_PARITY) TB8 = 1; //设置校验位为1 #endif } else { #if (PARITYBIT == ODD_PARITY) TB8 = 1; //设置校验位为1 #elif (PARITYBIT == EVEN_PARITY) TB8 = 0; //设置校验位为0 #endif } busy = 1; SBUF = ACC; //写数据到UART数据寄存器 }