打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
51单片机软件解码MP3码流速率提升后的!!!!
由于MP3文件的码率不同导致了有的歌曲不能正常播放!故而在不改变晶振频率的情况下,把内部对SD的FLASH 和送往MP3解码器的数据流速率做了调整!使他们达到最高速!比如:播放一首《第一次爱的人》音质就很好!但是播放《断桥残雪》就出现卡顿现象!是故也!
这里取消了移位算法!采用顺序架构!主要还是改变SPI的通信速率!其实还可以继续增强播放流速度!尽一切的减小指令的执行周期!但是经调试 这个速度已经可以满足了!就不做不必要的调整了!还有一招那就是改变 时钟!但是过高的外部时钟对系统的稳定性有影响的,这里不予考虑!实在不行再综合考虑!总之:要千方百计的挖掘可以提高的潜在的可提升的速度因素!达到播放要求!音质完美再现!


  1. #include <reg52.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. //******************
  5. sbit p1_7=P1^7;
  6. sbit CS=P2^0; //片选信号(低电平有效)
  7. sbit DATEIN =P2^1;//主-从数据输入
  8. sbit SCLK=P2^2;//时钟信号
  9. sbit DATEOUT=P2^3;//从-主数据输出
  10. unsigned char bdata dat;
  11. sbit dat_0=dat^0;
  12. sbit dat_1=dat^1;
  13. sbit dat_2=dat^2;
  14. sbit dat_3=dat^3;
  15. sbit dat_4=dat^4;
  16. sbit dat_5=dat^5;
  17. sbit dat_6=dat^6;
  18. sbit dat_7=dat^7;

  19. bit is_init;//决定是否延时;
  20. uchar lpp;
  21. unsigned char fhz;//返回值
  22. uchar fhz_buff; //读返回值中间量
  23. unsigned char xdata tab[512];

  24. ///*******************以上是SD卡
  25. /*
  26. VS1003mp3模块的接口定义

  27. */
  28. sbit XRST=P1^0;//复位
  29. sbit DREQ=P1^1; //数据请求
  30. sbit XDCS=P1^2;  //数据片选
  31. sbit XCS=P1^3; //命令片选
  32. /*
  33. /* VS1003mp3SPI通信接口定义
  34. */
  35. sbit SCK=P1^4; //时钟
  36. sbit SI=P1^5; //串行输入
  37. sbit SO=P1^6;  //串行输出
  38. //*******************************

  39. void delay(uint time)
  40. {  while(time)
  41.   time--;
  42. }
  43. //***************************
  44. unsigned char bdata datmp3;
  45. sbit datmp3_0=datmp3^0;
  46. sbit datmp3_1=datmp3^1;
  47. sbit datmp3_2=datmp3^2;
  48. sbit datmp3_3=datmp3^3;
  49. sbit datmp3_4=datmp3^4;
  50. sbit datmp3_5=datmp3^5;
  51. sbit datmp3_6=datmp3^6;
  52. sbit datmp3_7=datmp3^7;
  53. //**********************************************
  54. /*读sd卡子程序,无返回值,有参函数,参数为要写入DATEIN数据线的字节*/
  55. void write(unsigned char wr_)// 写入一个字节SD卡
  56. {
  57.            dat=wr_;
  58.         DATEIN=dat_7;
  59.    
  60.       SCLK=0;
  61.    if(is_init)delay(200);
  62.     //if(!is_init)delay(1);
  63.       SCLK=1;
  64.       if(is_init) delay(200);
  65.       // if(!is_init)delay(1);
  66.   
  67.       DATEIN=dat_6;
  68.    
  69.       SCLK=0;
  70.      //if(!is_init)delay(1);
  71.     if(is_init)delay(200);
  72.       SCLK=1;
  73.       if(is_init) delay(200);
  74.     // if(!is_init)delay(1);

  75.       DATEIN=dat_5;
  76.    
  77.       SCLK=0;
  78.     if(is_init)delay(200);
  79.     // if(!is_init)delay(1);
  80.       SCLK=1;
  81.       if(is_init) delay(200);
  82.     //if(!is_init)delay(1);

  83.       DATEIN=dat_4;
  84.    
  85.       SCLK=0;
  86.     if(is_init)delay(200);
  87.      // if(!is_init)delay(1);
  88.       SCLK=1;
  89.       if(is_init) delay(200);
  90.     // if(!is_init)delay(1);

  91.      DATEIN=dat_3;
  92.    
  93.       SCLK=0;
  94.     if(is_init)delay(200);
  95.       //if(!is_init)delay(1);
  96.       SCLK=1;
  97.       if(is_init) delay(200);
  98.    // if(!is_init)delay(1);

  99.      DATEIN=dat_2;
  100.    
  101.       SCLK=0;
  102.     if(is_init)delay(200);
  103.      // if(!is_init)delay(1);
  104.       SCLK=1;
  105.       if(is_init) delay(200);
  106.      // if(!is_init)delay(1);

  107.     DATEIN=dat_1;
  108.    
  109.       SCLK=0;
  110.     if(is_init)delay(200);
  111.     // if(!is_init)delay(1);
  112.       SCLK=1;
  113.       if(is_init) delay(200);
  114.     // if(!is_init)delay(1);

  115.     DATEIN=dat_0;
  116.    
  117.       SCLK=0;
  118.     if(is_init)delay(200);
  119.       //if(!is_init)delay(1);
  120.       SCLK=1;
  121.       if(is_init) delay(200);
  122.      //if(!is_init)delay(1);
  123. }
  124. unsigned char read()// 读取一个字节SD卡
  125. {
  126.           DATEOUT=1;
  127.          SCLK=1;
  128.    if(is_init)delay(200);
  129.      //if(!is_init)delay(1);
  130.    SCLK=0;
  131.     if(is_init)delay(200);
  132.    //if(!is_init)delay(1);
  133.     dat_7=DATEOUT;

  134.      SCLK=1;
  135.    if(is_init)delay(200);
  136.    //if(!is_init)delay(1);
  137.    SCLK=0;
  138.     if(is_init)delay(200);
  139.      //if(!is_init)delay(1);
  140.     dat_6=DATEOUT;

  141.     SCLK=1;
  142.    if(is_init)delay(200);
  143.    // if(!is_init)delay(1);
  144.    SCLK=0;
  145.     if(is_init)delay(200);
  146.    // if(!is_init)delay(1);
  147.     dat_5=DATEOUT;

  148.     SCLK=1;
  149.    if(is_init)delay(200);
  150.     // if(!is_init)delay(1);
  151.    SCLK=0;
  152.     if(is_init)delay(200);
  153.   // if(!is_init)delay(1);
  154.     dat_4=DATEOUT;

  155.      SCLK=1;
  156.    if(is_init)delay(200);
  157.    // if(!is_init)delay(1);
  158.    SCLK=0;
  159.     if(is_init)delay(200);
  160.     // if(!is_init)delay(1);
  161.     dat_3=DATEOUT;

  162.     SCLK=1;
  163.    if(is_init)delay(200);
  164.       // if(!is_init)delay(1);
  165.    SCLK=0;
  166.     if(is_init)delay(200);
  167.       // if(!is_init)delay(1);
  168.     dat_2=DATEOUT;

  169.      SCLK=1;
  170.    if(is_init)delay(200);
  171.        // if(!is_init)delay(1);
  172.    SCLK=0;
  173.     if(is_init)delay(200);
  174.      //  if(!is_init)delay(1);
  175.     dat_1=DATEOUT;


  176.      SCLK=1;
  177.    if(is_init)delay(200);
  178.         // if(!is_init)delay(1);
  179.    SCLK=0;
  180.     if(is_init)delay(200);
  181.          // if(!is_init)delay(1);
  182.     dat_0=DATEOUT;


  183.    return (dat);

  184. }

  185. void restsd()//复位SD卡
  186. {  uchar i;
  187. uchar pcmd[6]={0x40,0x00,0x00,0x00,0x00,0x95};
  188. is_init=1;

  189. CS=1;
  190. for(i=0;i<15;i++)
  191. {
  192.        //120时钟
  193.    write(0xff);
  194. }


  195.   
  196.   
  197.       CS=1;
  198.    write(0xff);//据说是提高兼容性
  199.    CS=0;//片选开

  200.    write( pcmd[0]);
  201.    write( pcmd[1]);
  202.    write( pcmd[2]);
  203.    write( pcmd[3]);
  204.    write( pcmd[4]);
  205.    write( pcmd[5]);

  206.    fhz=read();
  207. for(;;)
  208. {
  209.    fhz=read();
  210.    if(fhz==0x01)break;


  211. }

  212.   
  213.   CS=1;
  214.   write(0xff);

  215. }




  216. void initsd()//初始化
  217. {
  218. //
  219.    uchar pcmd[6]={0x41,0x00,0x00,0x00,0x00,0xff};//
  220. //

  221.       CS=1;
  222.    write(0xff);//据说是提高兼容性
  223.    CS=0;//片选开

  224.    write( pcmd[0]);
  225.    write( pcmd[1]);
  226.    write( pcmd[2]);
  227.    write( pcmd[3]);
  228.    write( pcmd[4]);
  229.    write( pcmd[5]);

  230.   
  231.    fhz=read();
  232. for(;;)
  233. {
  234.    fhz=read();
  235.    if(fhz==0x00)break;


  236. }

  237.   
  238.   CS=1;
  239.   write(0xff);








  240. }

  241. void readsd(unsigned long addstart)//读SD卡物理扇区
  242.    
  243. {  unsigned long sdbuff1,sdbuff2,sdbuff3,sdbuff4;  
  244.    uint j,n;
  245. uchar zh1,zh2,zh3,zh4;
  246.   sdbuff1=addstart;
  247.   sdbuff2=addstart;
  248.   sdbuff3=addstart;
  249.   sdbuff4=addstart;

  250.      zh1=(sdbuff1>>24)&0x000000ff;
  251.     zh2=(sdbuff2>>16)&0x000000ff;
  252.       zh3=(sdbuff3>>8)&0x000000ff;
  253.      zh4=sdbuff4&0x000000ff;
  254.    // uchar pcmd[6]={0x51,zh1,zh2,zh3,zh4,0xff};//原来这里是高地址字节在前地地址在后啊201012月14日逻辑扇区在253*512=0X0001fa00



  255.        CS=1;
  256.    write(0xff);//据说是提高兼容性
  257.    CS=0;//片选开

  258.    write( 0x51);
  259.    write( zh1);
  260.    write( zh2);
  261.    write( zh3);
  262.    write( zh4);
  263.    write( 0xff);
  264.    DATEOUT=1;
  265.   
  266. for(;;)
  267. {
  268.    fhz=read();
  269.    if(fhz==0x00)break;


  270. }
  271. DATEOUT=1;

  272.    for(;;)
  273. {
  274.    fhz=read();
  275.    if(fhz==0xfe)break;


  276. }

  277.   DATEOUT=1;
  278. n=0;
  279. for(j=512;j;j--)
  280. {  
  281.    tab[n]=read();
  282.     n++;

  283. }
  284. fhz=read();
  285. fhz=read();
  286. CS=1;
  287. write(0xff);








  288. }


  289. ////***************************************以上是SD主程序


  290. ///*************************************以下是MP3模块的程序

  291. void delay1ms(uint j)//延时100us
  292. {unsigned char i;

  293.    for(i=j;i;i--)
  294.    {
  295.   }
  296. }



  297. void spi_write_mp3(uchar h)//SPI写入一个字节,这里是最底层的数据发送!
  298. {
  299.   datmp3=h;

  300. /*SCLK=1;
  301. for(i=8;i;i--)
  302. {

  303.       SI=h&0x80;
  304.    h=h<<1;
  305.    SCK=0;
  306.    //delay1ms(1);  //这里不要加任何的延时!提高写入MP3模块的写入速度!
  307.       SCK=1;
  308.   // delay1ms(1);





  309. }*/

  310.            SI=datmp3_7;
  311.          //为了进一步提高速度我这里采用了顺序结构!全是断桥残雪惹的祸!第一次爱的人播放正常!而断桥残雪不行了!一定尽全力
  312.       SCK=0;   //从SD读取和MP3写数据流下手
  313.       SCK=1;
  314.    
  315.       SI=datmp3_6;
  316.    
  317.       SCK=0;
  318.       SCK=1;
  319.    

  320.       SI=datmp3_5;
  321.    
  322.       SCK=0;
  323.       SCK=1;
  324.    

  325.       SI=datmp3_4;
  326.    
  327.       SCK=0;
  328.       SCK=1;
  329.      

  330.       SI=datmp3_3;
  331.    
  332.       SCK=0;
  333.       SCK=1;
  334.      

  335.      SI=datmp3_2;
  336.    
  337.       SCK=0;
  338.       SCK=1;


  339.     SI=datmp3_1;
  340.    
  341.       SCK=0;
  342.       SCK=1;
  343.      

  344.     SI=datmp3_0;
  345.    
  346.       SCK=0;
  347.       SCK=1;
  348.      




  349. }


  350. /*uchar spi_read_mp3()// SPI读取一个字节
  351. {
  352.     uchar i,read;
  353.    for(i=8;i;i--)
  354.    {
  355.     SCLK=1;
  356.        delay();
  357.        SCLK=0;
  358.     delay();
  359.        read=SO&0x80;
  360.        read=(read<<1);

  361.     }
  362.     SCLK=1;

  363.   return (read);
  364. }
  365. */
  366. void write_comd_mp3(uchar add,uint date)//写入控制命令add地址date是数据注意这里是16位的数据,内部做分开了处理
  367. {     
  368.     uchar h,l;
  369.     l=date;
  370.     h=(date>>8);

  371.         DREQ=1;
  372.        while(!DREQ); //检测MP3模块的忙状态
  373.   XCS=0;
  374.     spi_write_mp3(2); //表示写操作
  375.     spi_write_mp3(add);
  376.     spi_write_mp3(h);  //先写高8位
  377.     spi_write_mp3(l);
  378.     XCS=1;




  379. }

  380. void write_date_mp3(uchar dat)//写入音频数据信息这里还有一点是XDCS在此函数外拉低
  381. {

  382.    DREQ=1;
  383.        while(!DREQ);
  384.   spi_write_mp3(dat);



  385. }

  386. void init_mp3()  //初始化vs1003
  387. {
  388.   XRST=1;
  389.   delay1ms(100);
  390.   XRST=0;
  391.   delay1ms(100);
  392.   XRST=1;
  393.   delay1ms(100);

  394.     write_comd_mp3(0x00,0x0804);//模式设置
  395. write_comd_mp3(0x03,0x9800);//时钟控制
  396. write_comd_mp3(0x0b,250);//声音音量控制 00是最大的!!!!!

  397. XDCS=0;//数据片选
  398. spi_write_mp3(0);
  399. spi_write_mp3(0);
  400. spi_write_mp3(0);
  401. spi_write_mp3(0);
  402. XDCS=1;


  403. }

  404. void sing(uchar fhz)//正选测试
  405. {
  406.   
  407.   
  408.    write_comd_mp3(0x00,0x0820);
  409.    DREQ=1;
  410.        while(!DREQ);
  411.     XDCS=0;
  412.     write_date_mp3(0x53);
  413.     write_date_mp3(0xef);
  414.     write_date_mp3(0x6e);//正选测试开启
  415.     write_date_mp3(fhz); //频率选择

  416.     write_date_mp3(0);
  417.     write_date_mp3(0);
  418.        write_date_mp3(0);
  419.     write_date_mp3(0);
  420.      delay1ms(60000);
  421.     write_date_mp3(0x45);   //正选关段
  422.     write_date_mp3(0x78);
  423.     write_date_mp3(0x69);
  424.     write_date_mp3(0x74);

  425.     write_date_mp3(0);
  426.     write_date_mp3(0);
  427.        write_date_mp3(0);
  428.     write_date_mp3(0);
  429.      XDCS=1;











  430. }

  431. //以上是MP3程序
  432. void main() //主程序
  433. {


  434. unsigned long numb;
  435. uint  i;
  436. uchar sd_mp3_buff;
  437.   


  438. init_mp3();//初始化MP3
  439. ////////////////
  440. is_init=1;
  441. restsd();
  442. initsd();
  443. is_init=0;//提高始终频率
  444. ///////////////




  445. sing(100);//正选测试

  446.       
  447.   while(1)
  448.   {
  449.    
  450.      numb=4327936; //从4327936物理地址开始读歌曲!




  451.                       for(;;)
  452.                         {    XDCS=0;
  453.                          readsd(numb);//读物理扇区

  454.                               for(i=0;i<512;i++)  //一个扇区的数据送入MP3中
  455.                                {
  456.       
  457.    
  458.    
  459.                                    sd_mp3_buff=tab[i];
  460.                                    write_date_mp3( sd_mp3_buff);
  461.    
  462.    

  463.                                  }

  464.              numb=(numb+512);



  465.                        }




  466.    XDCS=1;



  467.   }

  468.   


  469. }



本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
AT89C51单片机1602液晶显示时钟程序 此博文包含图片
51单片机液晶显示(含lcd12864和lcd1602)时钟_liutao2588的空间_...
AD7714.rar main1.c
51/51单片机第9课:DS18B20温度检测系统
adxl345传感器计步器 单片机程序
EX91 将数据"0xaa"写入X5045再读出送P1口显示
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服