Ant_V1三期工程(未完结)

简介 此次的制作也不是很顺利像是屏幕发热啦,元器件损坏啦,耽误了比较多的时间,本来器件是好的话驱动应该很快,但是排查是错误的过程是一个比较痛苦的过程,焊接,编写测试,测试这几个步骤循环的做起来还是很让人闹心的。这里呢希望我分享的经验能够帮助到他人,减少愚蠢的错误。

    述:由于上次打印的失败,但是检验电路时大部分电路还是能用的所以第三次主要是修改后的电路,以及测试的代码。关键的地方笔者也是卡了两三天。一点是我买的LCD坏了一个,三分之一的几率让我给碰上了,然后折腾了两天多的驱动,一直出问题,但是当我将Vs1053B 的驱动加进去时VS1053B居然能工作了,在之后考虑到以前驱动LCD屏幕,这些屏幕对电压有限制所以我第一时间想到的是换背光的限流电阻(其实还有其他原因,在于LCD发热),然后我想为啥不换一个屏幕试试,然后直接一上电,啊,简直了,一下就解决了,这无法驱动的问题我可是到处去找驱动源码(开始我以为是驱动源码的问题)。

 

声明:所有的源码只做学习交流使用,如做他用后果自负。

 

重画PCB再次打样

         更改晶振的背部干扰的问题

image.png

实物图如下:

image.png

更改驱动(出现的问题)

         这里主要是LCD的驱动,顺便说一下驱动LCD的步骤:

1.      初始化驱动管脚如:CS RESETD/C之类的,SPI或者FMSC

2.      LCD写驱动代码

3.      你可以写一个设置背景色为白色(用以验证)

 

 

 

 

集成文件系统

1.      MicroSD卡的准备

2.      更改diskio的底层驱动

3.      加入内存管理代码(这里直接使用正点原子的代码)

         这是一个比较难搞的事情:

         需要移植自己的气动SD卡的代码,同时还有一些操蛋的小细节,例如要将储存卡格式化为FAT32格式(建议直接格式化,有东西要转移出来)。

MP3播放器的实现

#include "Player.h"

#include "vs10xx.h"         

#include "delay.h"

#include "Key.h"

#include "FrameBox.h"

#include "LCD_2_0.h"   

#include "malloc.h"

#include "string.h"

#include "exfuns.h" 

#include "ff.h"  

#include "flac.h"    

#include "usart.h"  

#include "StringOperation.h"

 

 

extern char StringOperation_Buff[5][50];

//用于保存音量

int volume=220;

 

 

//显示曲目索引

//index:当前索引

//total:总文件数

void mp3_index_show(u16 index,u16 total)

{

//显示当前曲目的索引,及总曲目数

         StringInt(index);

         FrameShowString(0,20,40,16,16,(u8 *)"Now:",BLACK);

         FrameShowString(40,20,50,16,16,(u8 *)StringOperation_Buff[0],BLACK);

         StringInt(total);

         FrameShowString(90,20,40,16,16,(u8 *)"All:",BLACK);

         FrameShowString(130,20,50,16,16,(u8 *)StringOperation_Buff[0],BLACK);

//     LCD_ShowxNum(30+0,230,index,3,16,0X80);               //索引

//     LCD_ShowChar(30+24,230,'/',16,0);

//     LCD_ShowxNum(30+32,230,total,3,16,0X80);    //总曲目        

         printf("the music index:%d  \n",index);

}

//显示当前音量

void mp3_vol_show(u8 vol)

{                            

         FrameShowString(0,0,50,16,16,(u8 *)"VOL:",BLACK);

         StringInt(vol);

         FrameShowString(50,0,50,16,16,(u8 *)StringOperation_Buff[0],BLACK);

        

         printf("The volume:%d  \n",vol);

}

u16 f_kbps=0;//歌曲文件位率    

//显示播放时间,比特率 信息

//lenth:歌曲总长度

void mp3_msg_show(u32 lenth)

{      

         static u16 playtime=0;//播放时间标记            

        u16 time=0;// 时间变量

         u16 temp=0;    

         if(f_kbps==0xffff)//未更新过

         {

                  playtime=0;

                  f_kbps=VS_Get_HeadInfo();     //获得比特率

         }                

         time=VS_Get_DecodeTime(); //得到解码时间

         if(playtime==0)playtime=time;

         else if((time!=playtime)&&(time!=0))//1s时间到,更新显示数据

         {

                  playtime=time;//更新时间                                        

                  temp=VS_Get_HeadInfo(); //获得比特率                                    

                  if(temp!=f_kbps)

                  {

                          f_kbps=temp;//更新KBPS                                           

                  }                          

                  //显示播放时间

                  printf("played %d m %d s\n\n",time/60,time%60);

                 

                 

                  StringInt(time/60);

                  FrameShowString(0,40,30,16,16,(u8 *)StringOperation_Buff[0],BLACK);

                  FrameShowString(30,40,20,16,16,(u8 *)"m",BLACK);

                  FrameShowString(50,40,10,16,16,(u8 *)":",BLACK);

                  StringInt(time%60);

                  FrameShowString(70,40,30,16,16,(u8 *)StringOperation_Buff[0],BLACK);

                  FrameShowString(100,40,50,16,16,(u8 *)"s",BLACK);

//              LCD_ShowxNum(30,210,time/60,2,16,0X80);               //分钟

//              LCD_ShowChar(30+16,210,':',16,0);

//              LCD_ShowxNum(30+24,210,time%60,2,16,0X80);      //秒钟             

//             LCD_ShowChar(30+40,210,'/',16,0);                   

                  //显示总时间

                  if(f_kbps)time=(lenth/f_kbps)/125;//得到秒钟数   (文件长度(字节)/(1000/8)/比特率=持续秒钟数              

                  else time=0;//非法位率          

//             LCD_ShowxNum(30+48,210,time/60,2,16,0X80);        //分钟

//              LCD_ShowChar(30+64,210,':',16,0);

//              LCD_ShowxNum(30+72,210,time%60,2,16,0X80);      //秒钟                        

                  //显示位率    

                  printf("Fre:%d fkbps\n\n",f_kbps);

                  StringInt(f_kbps);

                  FrameShowString(0,60,40,16,16,(u8 *)"Fre:",BLACK);

                  FrameShowString(40,60,50,16,16,(u8 *)StringOperation_Buff[0],BLACK);

                  FrameShowString(90,60,40,16,16,(u8 *)"fkps",BLACK);

                 

//          LCD_ShowxNum(30+110,210,f_kbps,3,16,0X80);       //显示位率      

//              LCD_ShowString(30+134,210,200,16,16,"Kbps");                

//              LED0=!LED0;            //DS0翻转

         }             

}                                         

//得到path路径下,目标文件的总个数

//path:路径                

//返回值:总有效文件数

u16 mp3_get_tnum(u8 *path)

{        

         u8 res;

         u16 rval=0;

        DIR tdir;                   //临时目录

         FILINFO tfileinfo;    //临时文件信息            

         u8 *fn;                                                                          

  res=f_opendir(&tdir,(const TCHAR*)path); //打开目录

  tfileinfo.lfsize=_MAX_LFN*2+1;                                                    //长文件名最大长度

         tfileinfo.lfname=mymalloc(SRAMIN,tfileinfo.lfsize);   //为长文件缓存区分配内存

         if(res==FR_OK&&tfileinfo.lfname!=NULL)

         {

                  while(1)//查询总的有效文件数

                  {

             res=f_readdir(&tdir,&tfileinfo);                       //读取目录下的一个文件

             if(res!=FR_OK||tfileinfo.fname[0]==0)break;      //错误了/到末尾了,退出               

           fn=(u8*)(*tfileinfo.lfname?tfileinfo.lfname:tfileinfo.fname);                       

                          res=f_typetell(fn); 

                          if((res&0XF0)==0X40)//取高四位,看看是不是音乐文件   

                          {

                                   rval++;//有效文件数增加1

                          }          

                  } 

         }

         myfree(SRAMIN,tfileinfo.lfname);

         return rval;

}

 

 

//播放音乐

void mp3_play(void)

{

         u8 res;

        DIR mp3dir;                     //目录

         FILINFO mp3fileinfo;//文件信息

         u8 *fn;                           //长文件名

         u8 *pname;                      //带路径的文件名

         u16 totmp3num;            //音乐文件总数

         u16 curindex;           //图片当前索引

         u8 key;                               //键值               

        u16 temp;

         u16 *mp3indextbl; //音乐索引表

        

         FrameClear(WHITE);

         delay_ms(10);

        while(f_opendir(&mp3dir,"0:/MUSIC"))//打开图片文件夹

        {          

                  printf("MUSIC文件夹错误!\n\n");

                  delay_ms(200);                 

         }                                                                              

         totmp3num=mp3_get_tnum((u8 *)"0:/MUSIC"); //得到总有效文件数

      while(totmp3num==NULL)//音乐文件总数为0         

        {          

                  printf("没有音乐文件!");

                  delay_ms(200);                          

         }                                                                                        

  mp3fileinfo.lfsize=_MAX_LFN*2+1;                                             //长文件名最大长度

         mp3fileinfo.lfname=mymalloc(SRAMIN,mp3fileinfo.lfsize);       //为长文件缓存区分配内存

        pname=mymalloc(SRAMIN,mp3fileinfo.lfsize);                              //为带路径的文件名分配内存

        mp3indextbl=mymalloc(SRAMIN,2*totmp3num);                                  //申请2*totmp3num个字节的内存,用于存放音乐文件索引

        while(mp3fileinfo.lfname==NULL||pname==NULL||mp3indextbl==NULL)//内存分配出错

        {          

                  printf("内存分配失败!");

                  delay_ms(200);

         }    

         VS_HD_Reset();

         VS_Soft_Reset();

         vsset.mvol=volume;                                                   //默认设置音量为220.

         mp3_vol_show((vsset.mvol-100)/5);    //音量限制在:100~250,显示的时候,按照公式(vol-100)/5,显示,也就是0~30  

         //记录索引

    res=f_opendir(&mp3dir,"0:/MUSIC"); //打开目录

         if(res==FR_OK)

         {

                  curindex=0;//当前索引为0

                  while(1)//全部查询一遍

                  {

                          temp=mp3dir.index;                                                                     //记录当前index

                 res=f_readdir(&mp3dir,&mp3fileinfo);                  //读取目录下的一个文件

                 if(res!=FR_OK||mp3fileinfo.fname[0]==0)break;        //错误了/到末尾了,退出               

                    fn=(u8*)(*mp3fileinfo.lfname?mp3fileinfo.lfname:mp3fileinfo.fname);                     

                          res=f_typetell(fn); 

                          if((res&0XF0)==0X40)//取高四位,看看是不是音乐文件   

                          {

                                   mp3indextbl[curindex]=temp;//记录索引

                                   curindex++;

                          }          

                  }

         }  

  curindex=0;                                                                                        //0开始显示

  res=f_opendir(&mp3dir,(const TCHAR*)"0:/MUSIC");    //打开目录

         while(res==FR_OK)//打开成功

         {      

                  dir_sdi(&mp3dir,mp3indextbl[curindex]);                       //改变当前目录索引      

    res=f_readdir(&mp3dir,&mp3fileinfo);                   //读取目录下的一个文件

    if(res!=FR_OK||mp3fileinfo.fname[0]==0)break;        //错误了/到末尾了,退出

    fn=(u8*)(*mp3fileinfo.lfname?mp3fileinfo.lfname:mp3fileinfo.fname);

                  /********打印出名称**********/

                  //AddMessage((char *)fn);

                 

                  FrameShowString(0,80,50,16,16,(u8 *)"Song:",BLACK);

                  FrameShowString(0,100,178,16,16,(u8 *)fn,BLACK);

                  mp3_vol_show((volume-100)/5);

                 

                  strcpy((char*)pname,"0:/MUSIC/");                                //复制路径(目录)

                  strcat((char*)pname,(const char*)fn);                          //将文件名接在后面

                //LCD_Fill(30,190,240,190+16,WHITE);                                   //清除之前的显示

                 

                  mp3_index_show(curindex+1,totmp3num);

                  key=mp3_play_song(pname);                                                 //播放这个MP3   

                  if(key==2)                 //上一曲

                  {

                          if(curindex)curindex--;

                          else curindex=totmp3num-1;

                }else if(key<=1)//下一曲

                  {

                          curindex++;                  

                          if(curindex>=totmp3num)curindex=0;//到末尾的时候,自动从头开始

                }else break;     //产生了错误         

         }                                                                                                

         myfree(SRAMIN,mp3fileinfo.lfname);  //释放内存                         

         myfree(SRAMIN,pname);                                 //释放内存                         

         myfree(SRAMIN,mp3indextbl);                       //释放内存      

}

 

//播放一曲指定的歌曲                                                                                                                                       

//返回值:0,正常播放完成

//               1,下一曲

//       2,上一曲

//       0XFF,出现错误了

u8 mp3_play_song(u8 *pname)

{        

        FIL* fmp3;

   u16 br;

         u8 res,rval;

         u8 *databuf;

         u16 i=0;

         u8 key;       

         rval=0;        

         fmp3=(FIL*)mymalloc(SRAMIN,sizeof(FIL));//申请内存

         databuf=(u8*)mymalloc(SRAMIN,4096);               //开辟4096字节的内存区域

         if(databuf==NULL||fmp3==NULL)rval=0XFF ;//内存申请失败.

         if(rval==0)

         {        

           VS_Restart_Play();                                      //重启播放

                  VS_Set_All();                                              //设置音量等信息                          

                  VS_Reset_DecodeTime();                                          //复位解码时间     

                  res=f_typetell(pname);                                   //得到文件后缀                                                                                        

                  if(res==0x4c)//如果是flac,加载patch

                  {      

                          VS_Load_Patch((u16*)vs1053b_patch,VS1053B_PATCHLEN);

                  }                                                                                                                  

                  res=f_open(fmp3,(const TCHAR*)pname,FA_READ);//打开文件        

                if(res==0)//打开成功.

                  {

                          VS_SPI_SpeedHigh();      //高速                                                   

                          while(rval==0)

                          {

                                   res=f_read(fmp3,databuf,4096,(UINT*)&br);//读出4096个字节 

                                   i=0;

                                   do//主播放循环

                              {    

                                            if(VS_Send_MusicData(databuf+i)==0)//VS10XX发送音频数据

                                            {

                                                     i+=32;

                                            }else  

                                            {

                                                     key=GetKeyCilk();

                                                     switch(key)

                                                     {

                                                             case KEY_Right:

                                                                      rval=1;              //下一曲

                                                                      break;

                                                             case KEY_Left:

                                                                      rval=2;              //上一曲

                                                              break;

                                                             case KEY_Up:

                                                                      if(volume<255)volume++;               //上一曲

                                                                       VS_Set_Vol(volume);

                                                                       mp3_vol_show((volume-100)/5);

                                                              break;

                                                             case KEY_Down:

                                                                      if(volume>0)volume--;            //上一曲

                                                                       VS_Set_Vol(volume);

                                                                       mp3_vol_show((volume-100)/5);

                                                              break;

                                                     }

                                                     vsset.mvol=volume;

                                                     mp3_msg_show(fmp3->fsize);//显示信息     

                                            }                        

                                   }while(i<4096);//循环发送4096个字节

                                   if(br!=4096||res!=0)

                                   {

                                            rval=0;

                                            break;//读完了.               

                                   }                                                            

                          }

                          f_close(fmp3);

                  }else rval=0XFF;//出现错误          

         }                                                               

         myfree(SRAMIN,databuf);                                     

         myfree(SRAMIN,fmp3);

         return rval;                                      

}

播放效果:这里没有写什么复杂的界面(关键是下一步的考虑用不到)

image.png

 

 

以后的打算

由于这里的调度啥的都是用一个一个的函数,但是stm32其实可以加一个实时的系统,现在也有类似的经历了所以有望在年后重构一个实时系统暂且叫它Rutral吧,系统是会复杂但是打包以后任务的加入就简单了。


文章评论

Top