mp3 player

I am very close to finishing my little project. I had a proper pcb made for an mp3 player circuit, and mounted all the components yesterday. I programmed the chip with an mp3 palyer program i found on avrfreaks and it works

I am now trying to get it so that i can take four timing readings from a user input of clicking a button, add the number of seconds together and then play the track that has that index number (or name, but i think thats a bit more difficult). Below is the main function, that initialises the mp3 chip, and under that is a while loop that takes in the two sets of timings (each stores two times, 4 in total) stored as time_ms1, time_ms2, time_ms3 and time_ms4.

It them calls the function “equation” which does a little sum, adding all four times together, then the bit i am having trouble with is making the mp3 player play the track with that index number

I think it sounds more complex than it is, because the timers allready work, i just am struggling with the equation function and getting it to play the right song

Please can someone help me

Thanks:

    unsigned int time_ms1 = 0;
             unsigned int time_ms2 = 0;
          unsigned int time_ms3 = 0;
          unsigned int time_ms4 = 0;
            volatile unsigned int timer_tick;            //global timer variable MUST BE DECLARED VOLATILE
          volatile unsigned int timer_tick_2;     //global timer variable MUST BE DECLARED VOLATILE
           



    //main function
    int main()
    {
       uint8 retry = 0;

       DDRD &= 0x03;//³õʼ»¯¶Ë¿Ú
       PORTD |= 0xfc;
       
       LED1_CON();
       LED1_OFF();
       LED2_CON();
       LED2_OFF();


       

       OSCCAL = 0x00;//×îСRCÕñµ´ÆµÂÊ   //in order to operate some low speed card the initialization should run at lowest speed

       Delay(0xffff);

       MMC_SD_Init();//³õʼ»¯spi¿Ú      //SPI initialize

       Delay(0xffff);

       if(VS1003B_Init())
       {
          //LED1_ON();//ÅäÖÃVS1003   //config vs1003
          while(1)
          {
             LED1_ON();
             Delay(0xffff);
             LED1_OFF();
             Delay(0xffff);
          }
       }
       Delay(0xffff);//Ìṩ×ã¹»µÄÑÓʱ            //supply enough delay
       Delay(0xffff);
       Delay(0xffff);
       Delay(0xffff);
       Delay(0xffff);

       while(MMC_SD_Reset())//³õʼ»¯SD¿¨               //sd card initialize
       {
          retry++;
          if(retry>20)
          {
          //   LED2_ON();
             while(1)
             {
                LED2_ON();
                Delay(0xffff);
                LED2_OFF();
                Delay(0xffff);
             }
          }
       }

       OSCCAL = 0xff;//×î´óRCÕñµ´ÆµÂÊ            //normal operation maximum the frequency

       Delay(0xffff);                        //wait for stable

       if(FAT_Init())//³õʼ»¯Îļþϵͳ Ö§³ÖFAT16ºÍFAT32   //initialize file system  FAT16 and FAT32 are supported
       {
       //   LED1_ON();
       //   LED2_ON();
       //   while(1);
          while(1)
          {
             LED1_ON();LED2_ON();
             Delay(0xffff);
             LED1_OFF();LED2_OFF();
             Delay(0xffff);
          }

       }
       Search(PATH,&MusicInfo,&totalsongs,&type);
       //search the songs in the root directery on the SD card
       //You can also specify the directery where the songs are placed
       //eg: Search("\\new\\mp3",&MusicInfo,&totalsongs,&type);
       //      means search the file in the foler C:\new\mp3



    DDRD &= ~(1 << PD6);
       PORTD|=(1<<PD6);
       
       DDRD &= ~(1 << PD7);
       PORTD|=(1<<PD7);

       DDRD &= ~(1 << PD5);
       PORTD|=(1<<PD5);
         
       //initialize timer 0
        TCNT0=~(124);//preload counter to overflow after 1 ms (125 counts)
       TIMSK0=(1<<TOIE0);//enable interrupt on timer0 overflow
       TCCR0B=(1<<CS01)|(1<<CS00);//set timer to normal mode with CPU clock/64 (125 kHz)
       
       sei();//enable all interrupts
       
       // time an event:
       timer_tick=0;
       timer_tick_2=0;            //start timer, clear global millisecond counter
       TCNT0 = ~(124);
         
       while(1){
         

                   //first timing
                      time_ms1 = 0;
                      time_ms2 = 0;

       
                       while (PIND&(1<<PD6));  // loop here until first button press
                       TCNT0 = 0;
                       timer_tick=0;// here is where we start timing
                       _delay_ms(1);  // delay for 1 ms to debounce button press
                /*      LED1_ON();LED2_ON();
                   Delay(0xffff);
                   LED1_OFF();LED2_OFF();
                   Delay(0xffff);*/
                       while (!(PIND&(1<<PD6)));  // loop here until button is released
                       _delay_ms(10);  // delay for 10 ms to debounce button release
       
       
                       while (PIND&(1<<PD6));  // loop here until second button press
                       time_ms1 = timer_tick;      //get the value of the millisecond counter
                        timer_tick=0;// here is where reset the timer
                       _delay_ms(1);  // delay for 1 ms to debounce button press
           
                       while (!(PIND&(1<<PD7)));  // loop here until button is released
       
                       _delay_ms(10);  // delay for 10 ms to debounce button release
       
                       while (PIND&(1<<PD6));  // loop here until 3rd button press
                       time_ms2 = timer_tick;      //get the value of the millisecond counter
       
    //    lcd_line1();// display the times
    //    lcd_time(time_ms1);
    //    lcd_line2();
    //    lcd_time(time_ms2);

                   _delay_ms(10);  // delay for 10 ms to debounce button release
    //  lcd_clear();
       }   
                      //second timing
                      {
                      time_ms3 = 0;
                      time_ms3 = 0;

       
                       while (PIND&(1<<PD6));  // loop here until first button press
                       TCNT0 = 0;
                       timer_tick_2=0;// here is where we start timing
                       _delay_ms(1);  // delay for 1 ms to debounce button press

                       while (!(PIND&(1<<PD6)));  // loop here until button is released
                       _delay_ms(10);  // delay for 10 ms to debounce button release
       
       
                       while (PIND&(1<<PD6));  // loop here until second button press
                       time_ms3 = timer_tick_2;      //get the value of the millisecond counter
                     timer_tick_2=0;// here is where reset the timer
                       _delay_ms(1);  // delay for 1 ms to debounce button press
           
                       while (!(PIND&(1<<PD6)));  // loop here until button is released
       
                       _delay_ms(10);  // delay for 10 ms to debounce button release
       
                       while (PIND&(1<<PD6));  // loop here until 3rd button press
                       time_ms4 = timer_tick_2;      //get the value of the millisecond counter
       
    //    lcd_line1();// display the times
      //  lcd_time(time_ms3);
        //lcd_line2();
        //lcd_time(time_ms4);

                    _delay_ms(1000); //for button debounce
       //lcd_clear();   
                         equation(); //call equation to add four times together
       

       

    PlaySongs();   
       while(1)
       {
          while(1)
          {
             LED1_ON();LED2_OFF();
             Delay(0xffff);
             LED2_ON();LED1_OFF();
             Delay(0xffff);
          }
       }
       return 0;
    }

    }
    //-----------------------------------
    // Function
    //----------------------------------


    int equation()
    {

    //little eqn adding the two four timings together
    return(0);
    }
    //-----------------------------------
    // End of Function detmining ball position
    //-----------------------------------

    /*
    TIMER 0 overflow interrupt service routine
    This routine is called every millisecond
    Operation: increment global variable timer_tick, reload TCNT0 to count 125 clock cycles
    */

    ISR(TIMER0_OVF_vect)
    {
       timer_tick++;
       timer_tick_2++;
       TCNT0 = ~(125);         //preload counter to overflow after 1 ms (125 counts)
    }

Below is the function that gets a song to play:

void PlaySong(uint16 songs){
   uint16 keylen;         //ÓÃÓÚ¼ü´¦Àí      //for key processing
   uint16 count;         //Êý¾Ý¼ÆÊý         //data counting
   uint8 i;            //Ñ­»·±äÁ¿         //loop variable
   uint16 j;            //Ñ­»·±äÁ¿         //loop variable
   uint32 p;            //´Øָʾֵ         //cluster
   uint32 totalsect;      //ÎļþÓµÓеÄÉÈÇøÊý   //cotain the total sector number of a file
   uint16 leftbytes;      //Ê£Óà×Ö½Ú         //cotain the left bytes number of a file //the last cluster usually not fully occupied by the file
   uint8 *buffer;         //»º³å            //buffer
   uint32 sector;         //ÉÈÇø            //recor the current sector to judge the end sector
   uint8 flag;            //²¥·Å/ÔÝÍ£±êÖ¾      //flag of pause
//   uint16 vol=DefaultVolume;//³õʼÒôÁ¿£¬Ó¦Óëvs1003º¯ÊýÀïµÄ³õʼÒôÁ¿Ïàͬ   //default volume
   uint8 mode=DEFAULT_MODE;//µ¥ÇúÖظ´         //repet all by default
   uint16 songs_cnt = 0;               //how many songs have been played
   if(totalsongs==0)return;//Èç¹ûûÓиèÇúÔòÒì³£Í˳ö   //if no music file return
   uint32 rand_val;
   Timer1_Initial();//Æô¶¯¶¨Ê±Æ÷£¬ÓÃÓÚ²úÉúËæ»úº¯ÊýµÄÖÖ×Ó   //initialize the timer
   ClearTrackInfo();
//next://ÏÂÒ»Ê׸èµÄÆðʼµØ·½                  //label for "goto"
   if(mode==RANDOM)//Ëæ»ú²¥·Å¸èÇú             //if the mode is shuffle the songs
   {
      songs_cnt++;
      if(songs_cnt == totalsongs && totalsongs<1025)
      {
         ClearTrackInfo();
         songs_cnt = 0;
      }
      rand_val = TCNT1;
      Delay((random() && 0x00ff));
      rand_val <<= 16;
      rand_val += TCNT1;
      srandom(rand_val);
      if(totalsongs>1024)
      {
         songs = (uint16)(((random()/214749)*(uint32)totalsongs)/10000)+1;//Ëæ»ú²úÉú¸èÇúÐòºÅ   //create random song number
      }
      while(totalsongs<1025)
      {
         songs = (uint16)(((random()/214749)*(uint32)totalsongs)/10000)+1;//Ëæ»ú²úÉú¸èÇúÐòºÅ   //create random song number
         if(SetTrack(songs) == 0)break;
      }   
   }
   count=0;//Çå»ùÊý   //clear count
   flag=1;
   while(count<2048 && (type != MID))//recommand 2048 zeros honoring DREQ befor soft reset
   {                           //ÓÃÓÚ´ÓwmaÌø³öµ½ÏÂÒ»Ê׸裬ºÍÒ»Ê׸è½áÊøÌî³äÊý¾Ý//midi¸ñʽ²»ÐèÒª
      if((VS1003B_PIN & _BV(VS1003B_DREQ))!=0)
      {
         for(j=0;j<32;j++)
         {
            VS1003B_WriteDAT(0x00);//Ìî³ä0   //fill 0
            count++;
         }
         if(count == 2047)break;
      }
   }
   VS1003B_SoftReset();//soft reset //in case of playing wma files//Èí¼þ¸´Î»
   Search(PATH,&MusicInfo,&songs,&type);      //ÕÒµ½ÏàÓ¦µÄÎļþ      //find the file
   p     = MusicInfo.deStartCluster+(((uint32)MusicInfo.deHighClust)<<16);//¶ÁÎļþÊ×´Ø   //the first cluster of the file
      
   totalsect = MusicInfo.deFileSize/512; //¼ÆËãÉÈÇøÊý         //calculate the total sectors
   leftbytes = MusicInfo.deFileSize%512; //¼ÆËãÊ£ÓàµÄ×Ö½ÚÊý   //calculate the left bytes   
   i=0;
   sector=0;
   
   while(1)
   {
      keylen=0;
       for(;i<SectorsPerClust;i++)      //Ò»¸ö´Ø   //a cluster
      {
         buffer=malloc(512);
         FAT_LoadPartCluster(p,i,buffer);//¶ÁÒ»¸öÉÈÇø   //read a sector
         count=0;
         while(count<512)
         {
            if(flag==0){if(keylen){Delay(100);keylen--;}}
            else if(type == MID){if(keylen){Delay(100);keylen--;}}
            if((VS1003B_PIN & _BV(VS1003B_DREQ))!=0 && flag)   //¸ù¾ÝÐèÒªËÍÊý¾Ý  //send data  honoring DREQ
            {
               for(j=0;j<32;j++)         //ÿ´ÎËÍ32¸öÊý¾Ý      //32 Bytes each time
               {
                  VS1003B_WriteDAT(buffer[count]);
                  count++;
               }
               if(keylen)keylen--;         //ÓÃÓÚ¼ü´¦Àí         //for key processing
               if(sector == totalsect && count >= leftbytes)      //Èç¹ûÎļþÒѽáÊø      //if this is the end of the file
               {
                  if(type == MID)//waiting the midi file was decoded
                  {//¶ÔÓÚmidÒôÀÖÒª½Ó×ÅËÍ2048¸öÁã
                     count=0;
                     while(count<2048)//recommand 2048 zeros honoring DREQ goto next songs
                     {
                        if((VS1003B_PIN & _BV(VS1003B_DREQ))!=0 )
                        {
                           for(j=0;j<32;j++)
                           {
                              VS1003B_WriteDAT(0x00);
                              count++;
                           }
                           if(count == 2047)break;
                        }
                     }
                  }
                  i=SectorsPerClust;
                  break;
               }//Îļþ½áÊø         //file ended
               if(count == 511){break;}//512×Ö½ÚËÍÍêÌø³ö      //break if a sector was sent
            }
            if((PIND&STOP)==0 /*&& keylen==0*/)//²¥·ÅÔÝÍ£¼ü      //key PLAY/PAUSE
             {
                 Delay(100);
               if(!(PIND&STOP))
               {
                  while(!(PIND&STOP));
                   if(flag)flag=0;
                   else flag=1;
                   Delay(1000);
                }
             }
          
             
             
             
         }
         sector++;
         free(buffer);
      }
   }
}

Hi Alex, glad to see you’re still keeping with your microcontroller projects.

Your code doesn’t compile for me, so I’m not sure if this is exactly what you want, but you could write your equation function something like this:

void equation(int t1_ms, int t2_ms, int t3_ms, int t4_ms){
	PlaySong(((t1_ms+t2_ms+t3_ms+t4_ms)/1000)%totalsongs);
}

This function divides the sum by 1000 to get the value in seconds. The “%totalsongs” part takes the sum in seconds, divides it by the number of tracks (assuming that variable gets set by the mp3 chip during initialization) and calls the PlaySong function with the remainder. That way if there are only five tracks, but your sum is seven seconds, the function will play track 5, not track 7 which doesn’t exist (I’m not sure if this is causing you trouble or not, but just to be on the safe side…).

You would call this function from your main loop like this:

equation(time_ms1,time_ms2,time_ms3,time_ms4);

Another thing that might be causing you trouble right now is the order of your functions. C code is compiled in order, so you can’t have a function call a function below it that hasn’t been compiled yet! You can either move your main function to the very bottom of the code, or create a list of function prototypes up above your main function. A prototype is simply the statement of the function without the actual function code. So, for example, if you added that version of the equation function to your code below the main function, you would also need to add this function prototype on a line above the main function:

void equation(int t1_ms, int t2_ms, int t3_ms, int t4_ms)

Good luck finishing your project!

-Adam

Hi,

Yeah I am pretty much there now, I have it so that if the total number of seconds from the timers is less than 5, it plays one song, if it is greater it plays another.

The only thing though, i hoped you could help me with is, I am trying to get the program to loop back after it has played the song, I.E you could then do it again and again, at the moment you have to turn it off and on again. I think it takes the timer readings, (because the lights flash - which it told them to when a button was pressed), but it cannot, or doesnt play the equivelent song…

/*******************************************************************/
/*          Mega8 MP3 Player (mega8 + VS1003 + SD)  V1.8           */
/*                                                                 */
/* Discription: Can play mp3/wma/wav/mid SF0 files in the root     */
/*              directery on the SD card which file system is FAT16*/
/*              or FAT32.                                          */
/*              It has six keys to control this player             */
/*              MODE: switch between repeat all (default),repeat 1 */
/*                    and shuffle                                  */
/*              PLAY/PAUSE:                                        */
/*              PREV: previous songs                               */
/*              NEXT: next songs                                   */
/*              UP  : volume up                                    */
/*              DOWN: volume down                                  */
/* Platform   : AVRStudio4.13 b528 + WinAVR20070525                */
/*              optimize -0s                                       */
/* Author     : bozai(Zhang Qibo)                                  */
/* E-mail     : sudazqb@163.com                                    */
/* MSN        : zhangqibo_1985@hotmail.com                         */
/* Date       : 2007-06-16                                         */
/*******************************************************************/
/*  V1.8                                                           */
/*  2007-06-16                                                     */
/*  Still the bug of FAT, it's not resolved totally                */
/*                                                                 */
/*  V1.7                                                           */
/*  2007-05-21                                                     */
/*  Fix a serious bug of FAT                                       */
/*  Set the default mode to "Shuffle"                              */
/*  Because the mode button is inside the box                      */
/*  So I don't want to open the box when I turn on it              */
/*  If the button is easy to press of your mp3 player              */
/*  just change the macro below to:                                */
/*            0 = repet all    1 = repet one  2 = shuffle          */

#define DEFAULT_MODE   1

/*                                                                 */
/*  V1.6                                                           */
/*  2007-05-09                                                     */
/*  And a track function to make the shuffle a real shuffle        */
/*  Due to the limted RAM space of mega8. Maximum no repetition    */
/*  songs is 1024. And songs more than that will use randomly play */
/*  Special thanks to Ronald Ausloos (Belgium)'s advice            */ 
/*                                                                 */
/*  V1.5                                                           */
/*  2007-05-03                                                     */
/*  Change the behavior of the LEDs:                               */
/*                      VS1003 faild: LED1 blink                   */
/*                      SD faild    : LED2 blink                   */
/*                      FAT faild   : LED1 & LED2 blink alternatly */
/*                      File not found: Both LED blink             */
/*  Add read capacity function, fix the bug of FAT init            */
/*  Add slow start up code of VS1003                               */ 
/*                                                                 */                                                              
/*  V1.4                                                           */
/*  2007-05-02                                                     */
/*  Add enough delay when operate VS1003                           */ 
/*                                                                 */                                                              
/*  V1.3                                                           */
/*  2007-04-21                                                     */
/*  Modify the retry time of sd reset                              */
/*  Enable some code incase that when FAT initialize               */
/*  faild program can't jump out the loop                          */
/*  so the error LED can't light up                                */
/*  And light up both leds when FAT_Ini fails                      */
/*                                                                 */
/*  V1.2:                                                          */
/*  2007-04-04:                                                    */
/*  Add a macro of path                                            */
/*                                                                 */
/*  V1.1:                                                          */
/*  2007-02-25                                                     */
/*  Change the directory to C:\music\                              */
/*  A bug fixed                                                    */
/*  Modify some code to adjust new GCC compiler                    */
/*                                                                 */
/*  V1.0:                                                          */
/*  2006-12-03:                                                    */
/*  Original Version                                               */
/*******************************************************************/

#include<avr/io.h>
#include"MMC_SD/MMC_SD.h" //head files
#include"FAT/FAT.h"

#include"VS1003B/VS1003B.h"
#include<avr/pgmspace.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#define uint8 unsigned char
#define uint16 unsigned int
#define uint32 unsigned long


#define PATH (unsigned char *)("\\music")
//It's the path where the file placed
//Change it if you want to placed it to anoter foler
//The path should not have blanks, and each foler name's length should less than 8 with no extention

//diagnose and state indicate leds
//at start up this two led indicate error
//at normal they indicate the state of the MODE 
#define LED1_CON() DDRC|=_BV(PC5)
#define LED1_ON()  PORTC|=_BV(PC5)
#define LED1_OFF() PORTC&=~_BV(PC5)

#define LED2_CON() DDRB|=_BV(PB1)
#define LED2_ON()  PORTB|=_BV(PB1)
#define LED2_OFF() PORTB&=~_BV(PB1)

//keys
#define STOP _BV(PD2)
#define MODE _BV(PD3)
#define NEXT _BV(PD7)
#define UP   _BV(PD4)
//#define DOWN _BV(PD6)
#define PREV _BV(PD5)

#define MP3 1
#define WMA 2
#define MID 3

//mode
#define REPET_ALL 0
#define REPET_ONE 1
#define RANDOM    2

extern uint16 SectorsPerClust;//ÿ´ØÉÈÇøÊý
extern uint16 FirstDataSector;//µÚÒ»¸öÊý¾ÝÉÈÇøÊý   //struct of file information
extern uint8  FAT32_Enable;

struct FileInfoStruct FileInfo;//ÎļþÐÅÏ¢

struct direntry MusicInfo;	//Òª²¥·ÅµÄmp3ÎļþÐÅÏ¢		//the mp3 file item whichi will be played
uint16 totalsongs;			//×ܵÄÒôÀÖÎļþÊýÄ¿			//total songs in the root directery on the SD card
uint8 type;					//ÎļþÀàÐÍ					//file type

uint8 track[128];			//stroe the information of songs (bit set indicate songs has been played)

void ClearTrackInfo()		//cleare the array track[128]
{
	uint8 i;
	for(i=0;i<128;i++)track[i] = 0;
}

uint8 SetTrack(uint16 songs)//set the track bit, return 1 means the song has been played
{
	uint8 byte_offset;
	uint8 bit_offset;
	songs--;
	byte_offset = songs/8;
	bit_offset = songs%8;
	if(track[byte_offset] & (1<<bit_offset))return 1;
	else
	{
		track[byte_offset] |= 1<<bit_offset;
		return 0;
	}
}

void Delay(uint16 n)//ÑÓʱ
{
	while(n--)asm("nop");
}

//Timer initialization offer seed of the srandom()
void Timer1_Initial()
{
 TCNT1H=0x00;
 TCNT1L=0x00;
 TCCR1B=0x01;//system clock;
 ICR1H=0xff;
 ICR1L=0xff;
}


unsigned int final_value;
 	unsigned int time_ms1 = 0;
   		unsigned int time_ms2 = 0;
		unsigned int time_ms3 = 0;
		unsigned int time_ms4 = 0;

     	volatile unsigned int timer_tick;      		//global timer variable MUST BE DECLARED VOLATILE
		volatile unsigned int timer_tick_2;     //global timer variable MUST BE DECLARED VOLATILE


void PlayMusic()//²¥·ÅÒôÀÖº¯Êý£¬Ò»µ©Ö´Ðв»»áÍ˳ö
{
	uint16 keylen;			//ÓÃÓÚ¼ü´¦Àí		//for key processing
	uint16 count;			//Êý¾Ý¼ÆÊý			//data counting
	uint8 i;				//Ñ­»·±äÁ¿			//loop variable
	uint16 j;				//Ñ­»·±äÁ¿			//loop variable
	uint32 p;				//´Øָʾֵ			//cluster
	uint32 totalsect;		//ÎļþÓµÓеÄÉÈÇøÊý	//cotain the total sector number of a file
	uint16 leftbytes;		//Ê£Óà×Ö½Ú			//cotain the left bytes number of a file //the last cluster usually not fully occupied by the file
	uint8 *buffer;			//»º³å				//buffer
	uint32 sector;			//ÉÈÇø				//recor the current sector to judge the end sector
	uint8 flag;				//²¥·Å/ÔÝÍ£±êÖ¾		//flag of pause
	uint16 vol=DefaultVolume;//³õʼÒôÁ¿£¬Ó¦Óëvs1003º¯ÊýÀïµÄ³õʼÒôÁ¿Ïàͬ	//default volume
	uint16 songs=final_value;			//ĬÈϷŵÚÒ»Ê׸è	//play the fist songs by default
	uint8 mode=DEFAULT_MODE;//µ¥ÇúÖظ´			//repet all by default
	uint16 songs_cnt = 0;					//how many songs have been played
	if(totalsongs==0)return;//Èç¹ûûÓиèÇúÔòÒì³£Í˳ö	//if no music file return
	uint32 rand_val;
	Timer1_Initial();//Æô¶¯¶¨Ê±Æ÷£¬ÓÃÓÚ²úÉúËæ»úº¯ÊýµÄÖÖ×Ó	//initialize the timer
	ClearTrackInfo();
next://ÏÂÒ»Ê׸èµÄÆðʼµØ·½						//label for "goto"
	if(mode==RANDOM)//Ëæ»ú²¥·Å¸èÇú 				//if the mode is shuffle the songs
	{
		songs_cnt++;
		if(songs_cnt == totalsongs && totalsongs<1025)
		{
			ClearTrackInfo();
			songs_cnt = 0;
		}
		rand_val = TCNT1;
		Delay((random() && 0x00ff));
		rand_val <<= 16;
		rand_val += TCNT1;
		srandom(rand_val);
		if(totalsongs>1024)
		{
			songs = (uint16)(((random()/214749)*(uint32)totalsongs)/10000)+1;//Ëæ»ú²úÉú¸èÇúÐòºÅ	//create random song number
		}
		while(totalsongs<1025)
		{
			songs = (uint16)(((random()/214749)*(uint32)totalsongs)/10000)+1;//Ëæ»ú²úÉú¸èÇúÐòºÅ	//create random song number
			if(SetTrack(songs) == 0)break;
		}	
	}
	count=0;//Çå»ùÊý	//clear count
	flag=1;
	while(count<2048 && (type != MID))//recommand 2048 zeros honoring DREQ befor soft reset
	{									//ÓÃÓÚ´ÓwmaÌø³öµ½ÏÂÒ»Ê׸裬ºÍÒ»Ê׸è½áÊøÌî³äÊý¾Ý//midi¸ñʽ²»ÐèÒª
		if((VS1003B_PIN & _BV(VS1003B_DREQ))!=0)
		{
			for(j=0;j<32;j++)
			{
				VS1003B_WriteDAT(0x00);//Ìî³ä0	//fill 0
				count++;
			}
			if(count == 2047)break;
		}
	}
	VS1003B_SoftReset();//soft reset //in case of playing wma files//Èí¼þ¸´Î»
	Search(PATH,&MusicInfo,&songs,&type);		//ÕÒµ½ÏàÓ¦µÄÎļþ		//find the file
	p     = MusicInfo.deStartCluster+(((uint32)MusicInfo.deHighClust)<<16);//¶ÁÎļþÊ×´Ø	//the first cluster of the file
		
	totalsect = MusicInfo.deFileSize/512; //¼ÆËãÉÈÇøÊý			//calculate the total sectors
	leftbytes = MusicInfo.deFileSize%512; //¼ÆËãÊ£ÓàµÄ×Ö½ÚÊý	//calculate the left bytes	
	i=0;
	sector=0;
	
	
		keylen=0;
    	for(;i<SectorsPerClust;i++)		//Ò»¸ö´Ø	//a cluster
		{
			buffer=malloc(512);
			FAT_LoadPartCluster(p,i,buffer);//¶ÁÒ»¸öÉÈÇø	//read a sector
			count=0;
			while(count<512)
			{
				if(flag==0){if(keylen){Delay(100);keylen--;}}
				else if(type == MID){if(keylen){Delay(100);keylen--;}}
				if((VS1003B_PIN & _BV(VS1003B_DREQ))!=0 && flag)	//¸ù¾ÝÐèÒªËÍÊý¾Ý  //send data  honoring DREQ
				{
					for(j=0;j<32;j++)			//ÿ´ÎËÍ32¸öÊý¾Ý		//32 Bytes each time
					{
						VS1003B_WriteDAT(buffer[count]);
						count++;
					}
					if(keylen)keylen--;			//ÓÃÓÚ¼ü´¦Àí			//for key processing
					if(sector == totalsect && count >= leftbytes)		//Èç¹ûÎļþÒѽáÊø		//if this is the end of the file
					{
						if(type == MID)//waiting the midi file was decoded
						{//¶ÔÓÚmidÒôÀÖÒª½Ó×ÅËÍ2048¸öÁã
							count=0;
							while(count<2048)//recommand 2048 zeros honoring DREQ goto next songs
							{
								if((VS1003B_PIN & _BV(VS1003B_DREQ))!=0 )
								{
									for(j=0;j<32;j++)
									{
										VS1003B_WriteDAT(0x00);
										count++;
									}
									if(count == 2047)break;
								}
							}
						}
						i=SectorsPerClust;
						break;
					}//Îļþ½áÊø			//file ended
					if(count == 511){break;}//512×Ö½ÚËÍÍêÌø³ö		//break if a sector was sent
				}
				if((PIND&STOP)==0 /*&& keylen==0*/)//²¥·ÅÔÝÍ£¼ü		//key PLAY/PAUSE
			    {
	 			    Delay(100);
					if(!(PIND&STOP))
					{
						while(!(PIND&STOP));
						 if(flag)flag=0;
						 else flag=1;
						 Delay(1000);
					 }
				 }
				
				 else if(!(PIND&UP) && keylen==0) //ÒôÁ¿+			//Volume up
	  			 {
					 Delay(100);
				 	 if(!(PIND&UP)) 
					 {
					 keylen=200;
					   vol=vol-((uint16)(1<<8)+1);
					   if(vol<=0x0101) vol=0x0101;
					   else VS1003B_WriteCMD(0x0b,vol);
	   			     }
				  }
				 else if(!(PIND&NEXT)) //ÏÂÒ»Ê×						next songs
	 			 {
					Delay(0x7fff);		
					if(!(PIND&NEXT))
					{
						Delay(0x7fff);
						if(!(PIND&NEXT))
						{
							while(!(PIND&NEXT));
							songs++;
							if(songs > totalsongs)songs=1;
							{
								free(buffer);
							//	Delay(0xffff);
								goto next;
							}
						}
					}
	  			 }
				 else if(!(PIND&PREV)) //ÉÏÒ»Ê×						previous songs
	 			 {
					Delay(0x7fff);		
					if(!(PIND&PREV))
					{
						Delay(0x7fff);
						if(!(PIND&PREV))
						{
							while(!(PIND&PREV));
							if(songs == 1)songs=totalsongs;
							else songs--;
							{
								free(buffer);
							//	Delay(0xffff);
								goto next;
							}
						}
					}
	  			 }
				 else if((!(PIND&MODE)) && keylen==0) //ģʽ			//mode key
	 			 {
					Delay(100);		
					if(!(PIND&MODE))
					{
						keylen=0xffff;
						if(mode==REPET_ALL)
						{
							mode=REPET_ONE;
							LED1_ON();
							LED2_OFF();
						}
						else if(mode==REPET_ONE)//next mode is shuffle
						{
							mode=RANDOM;
							LED1_OFF();
							LED2_ON();
							srandom(((uint32)TCNT1)<<16);//²úÉúËæ»úÊýµÄÖÖ×Ó
						}
						else 
						{
							mode=REPET_ALL;
							LED1_OFF();
							LED2_OFF();
						}
					}
	  			 }
			}
			sector++;
			free(buffer);
		}
		i=0;
	/*	p=FAT_NextCluster(p);//¶ÁÏÂÒ»´ØÊý¾Ý			//read next cluster
		if(p == 0x0fffffff || p == 0x0ffffff8 || (FAT32_Enable == 0 && p == 0xffff))//Èç¹ûÎÞºóÐø´ØÔò½áÊø£¬	//no more cluster
		{
				if(mode==REPET_ALL)songs++;
				if(songs>totalsongs)songs=1;
				
		}*/
	return 0;
}

//timing function

int timings()
{
	DDRD &= ~(1 << PD6);
   PORTD|=(1<<PD6); 

   //initialize timer 0
    TCNT0=~(124);//preload counter to overflow after 1 ms (125 counts)
   TIMSK0=(1<<TOIE0);//enable interrupt on timer0 overflow
   TCCR0B=(1<<CS01)|(1<<CS00);//set timer to normal mode with CPU clock/64 (125 kHz)
   
   sei();//enable all interrupts
   
   // time an event:
   timer_tick=0;
   timer_tick_2=0;            //start timer, clear global millisecond counter
   TCNT0 = ~(124);



   					//first timing
   					time_ms1 = 0; 
   					time_ms2 = 0;

   
   					 while (PIND&(1<<PD6));  // loop here until first button press
   					 TCNT0 = 0;
   					 timer_tick=0;// here is where we start timing
    					_delay_ms(10);  // delay for 1 ms to debounce button press
						LED1_ON();LED2_ON();
					Delay(0xffff);
					LED1_OFF();LED2_OFF();
					Delay(0xffff);  
   					 while (!(PIND&(1<<PD6)));  // loop here until button is released
   					 _delay_ms(10);  // delay for 10 ms to debounce button release
   
   
   					 while (PIND&(1<<PD6));  // loop here until second button press
   					 time_ms1 = timer_tick;      //get the value of the millisecond counter
   					  timer_tick=0;// here is where reset the timer
   					 _delay_ms(10);  // delay for 1 ms to debounce button press
					 LED1_ON();LED2_ON();
					Delay(0xffff);
					LED1_OFF();LED2_OFF();
					Delay(0xffff);
       
   					 while (!(PIND&(1<<PD6)));  // loop here until button is released
   
  					  _delay_ms(10);  // delay for 10 ms to debounce button release
   
   					 while (PIND&(1<<PD6));  // loop here until 3rd button press
   					 time_ms2 = timer_tick;      //get the value of the millisecond counter
   
//    lcd_line1();// display the times
//    lcd_time(time_ms1);
//    lcd_line2();
//    lcd_time(time_ms2);

 					_delay_ms(10);  // delay for 10 ms to debounce button release
					LED1_ON();LED2_ON();
					Delay(0xffff);
					LED1_OFF();LED2_OFF();
					Delay(0xffff);


				
//  lcd_clear();


//second timing
  					 
  					 time_ms3 = 0; 
  					 time_ms4 = 0;

   
  					  while (PIND&(1<<PD6));  // loop here until first button press
   					 TCNT0 = 0;
  					  timer_tick_2=0;// here is where we start timing
  					  _delay_ms(10);  // delay for 1 ms to debounce button press
					  LED1_ON();LED2_ON();
					Delay(0xffff);
					LED1_OFF();LED2_OFF();
					Delay(0xffff);

   					 while (!(PIND&(1<<PD6)));  // loop here until button is released
   					 _delay_ms(10);  // delay for 10 ms to debounce button release
   
   
   					 while (PIND&(1<<PD6));  // loop here until second button press
   					 time_ms3 = timer_tick_2;      //get the value of the millisecond counter
    				 timer_tick_2=0;// here is where reset the timer
   					 _delay_ms(10);  // delay for 1 ms to debounce button press
					 LED1_ON();LED2_ON();
					Delay(0xffff);
					LED1_OFF();LED2_OFF();
					Delay(0xffff);
       
   					 while (!(PIND&(1<<PD6)));  // loop here until button is released
   
   					 _delay_ms(10);  // delay for 10 ms to debounce button release
   
   					 while (PIND&(1<<PD6));  // loop here until 3rd button press
   					 time_ms4 = timer_tick_2;      //get the value of the millisecond counter
   
//    lcd_line1();// display the times
  //  lcd_time(time_ms3);
    //lcd_line2();
    //lcd_time(time_ms4);

					 _delay_ms(10); //for button debounce 

					 LED1_ON();LED2_ON();
					Delay(0xffff);
					LED1_OFF();LED2_OFF();
					Delay(0xffff);

			//lcd_clear();	
   return 0;
}



//main function
int main()
{
	uint8 retry = 0;

	DDRD &= 0x03;//³õʼ»¯¶Ë¿Ú
	PORTD |= 0xfc;
	
	LED1_CON();
	LED1_OFF();
	LED2_CON();
	LED2_OFF();


	OSCCAL = 0x00;//×îСRCÕñµ´ÆµÂÊ	//in order to operate some low speed card the initialization should run at lowest speed

	Delay(0xffff);

	MMC_SD_Init();//³õʼ»¯spi¿Ú		//SPI initialize

	Delay(0xffff);

	if(VS1003B_Init())
	{
		//LED1_ON();//ÅäÖÃVS1003	//config vs1003
		while(1)
		{
			LED1_ON();
			Delay(0xffff);
			LED1_OFF();
			Delay(0xffff);
		}
	}
	Delay(0xffff);//Ìṩ×ã¹»µÄÑÓʱ				//supply enough delay
	Delay(0xffff);
	Delay(0xffff);
	Delay(0xffff);
	Delay(0xffff);

	while(MMC_SD_Reset())//³õʼ»¯SD¿¨					//sd card initialize
	{
		retry++;
		if(retry>20)
		{
		//	LED2_ON();
			while(1)
			{
				LED2_ON();
				Delay(0xffff);
				LED2_OFF();
				Delay(0xffff);
			}
		}
	}

	OSCCAL = 0xff;//×î´óRCÕñµ´ÆµÂÊ				//normal operation maximum the frequency

	Delay(0xffff);								//wait for stable

	if(FAT_Init())//³õʼ»¯Îļþϵͳ Ö§³ÖFAT16ºÍFAT32	//initialize file system  FAT16 and FAT32 are supported
	{
	//	LED1_ON();
	//	LED2_ON();
	//	while(1);
		while(1)
		{
			LED1_ON();LED2_ON();
			Delay(0xffff);
			LED1_OFF();LED2_OFF();
			Delay(0xffff);
		}

	}
	Search(PATH,&MusicInfo,&totalsongs,&type);//ËÑË÷¸ùĿϵĸèÇú ²»°üº¬×ÓĿ¼
	//Ò²¿ÉÒÔÖ¸¶¨Îļþ¼Ð ÈçSearch("\\new\\mp3",&MusicInfo,&totalsongs,&type);
	//´ú±íÔÚ¸ùĿ¼ÏµÄnewÎļþ¼ÐϵÄmp3ÎļþϵÄÒôÀÖÎļþ

	//search the songs in the root directery on the SD card
	//You can also specify the directery where the songs are placed
	//eg: Search("\\new\\mp3",&MusicInfo,&totalsongs,&type);
	//		means search the file in the foler C:\new\mp3

	
while (1)
{
			LED1_ON();LED2_ON();
			Delay(1000);
			LED1_OFF();LED2_OFF();
final_value = 0;
timings();
if(time_ms1 + time_ms2 + time_ms3 + time_ms4 > 5000)
{
final_value = 2;
}
else
{
final_value = 1;
}
	PlayMusic();		//play songs

}
/*	while(1)
	{
		while(1)
		{
			LED1_ON();LED2_OFF();
			Delay(0xffff);
			LED2_ON();LED1_OFF();
			Delay(0xffff);
		}
	}
	*/
	return 0;
}

/*
TIMER 0 overflow interrupt service routine
This routine is called every millisecond
Operation: increment global variable timer_tick, reload TCNT0 to count 125 clock cycles
*/

ISR(TIMER0_OVF_vect)
{
   timer_tick++;
   timer_tick_2++;
   TCNT0 = ~(125);         //preload counter to overflow after 1 ms (125 counts)
}

Lastly, did you ever find out how to write to a textfile on the sd card? I remember you said it was on your list of things to do. I have looked and asked around extensively, but this project uses a FAT.h and FAT.c libraries, and the only one anyone seemed to know about or want to help with was one called FatFs. Another, more avr based filing system that could be read by windows. I am trying to find the command in the fat.h library that says ammend text file - of course I cant find it…

I took a look at the code, but I don’t see the problem. I would try adding a different LED blink speed function to various places in the code to try to figure out exactly where it’s getting stuck.

SPI SD card read/write is still on my list of things to do. It would be neat, but there are various chips/devices you can purchase that handle the hard work for you though, so I haven’t spent the time to figure out how to do it the hard way yet.

-Adam

Oh really, there is something out there that will sort out writing a few results (the timings) to a text file on sd card already - please could you point me in the right direction…

About the code, thats what i thought also, when it loops backround, to take the timings again, if you want to do it more than once, it does take the timings, i can tell that from the flashing led’s i have put in when you press the buttons, to start/stop the timer, but it doesnt play anything, I wondered whether i should get it to reset everything each time it runs - i was wondering if there is a command that can make it act as though the program was starting all over again???

There are ways to make the program execution jump back to the beginning (don’t just call “main” though) or to even physically reset the chip from software, but before you get into that there’s no reason you shouldn’t be able to get the code to just loop properly. I would try taking out all but one LED flash event, so you can see exactly (like down to what line of code) is causing the trouble.

There are other devices that can make interfacing with an SD card much simpler, but unfortunately you wouldn’t be able to use them in parallel with the MP3 player chip on the same SD card. I’ve had some luck with the SparkFun LogoMatic (the V1 was quite nice, but the V2 has insufficient support), and for a while I’ve been interested in trying one of these DosOnChip boards out.

I’ve also had some luck with a USB memory stick datalogger from Parallax, but had to abandon it because it couldn’t guarantee buffer/write speeds.

-Adam

Ok will try that tomorrow, by the way, did an internet check but couldnt get my hex to work, i’m trying to make a flash of the led to be a reasonable, not too long but definately noticed it, length flash, but just cant find the right number, petit i know, but really annoying!

Also, its very easy to accidently (and often without knowing it) press the button twice in quick succession, do i just increase the button bounce delay, to say 50ms?