MMC WAV PLAYER USING PIC16F877A






Video of my PIC16F877A based MMC wav player 
 (video updated on 06/09/2011 (improved audio quality)):

Later i tried to access an MMC with FAT16 file system using the same PIC16F877A and then successfully played an 8 bit mono wav file of byterates from 8000 to 48000. Here, it reads the first sector of MMC (boot record) to obtain some important information like no of reserved sectors, start of partition, no of t Per FAT ,maximum Root Directory Entries ,Bytes per Sector etc. Using those information, it is possible to calculate the starting sector address of FAT1, FAT2, root directory, data area etc....But due to the limited RAM in PIC16F877A, it is required to read a complete sector multiple number of times to access the entire 512 bytes....
If i made a buffer of 64 bytes, then i need to read and use each successive 64 bytes in a sector for 8 times.  This is the technique I used to access any sector using low RAM. Now, reading the starting cluter address of a wav file from the root directory (assuming wav files are copied to the root directory), it streams the cluster to the PWM register (ie it loads each byte to PWM just after reading the byte from MMC and thus no need of any buffer memory), then after completing one cluster streaming, it calculates the next cluster address using the previous cluster address by checking it in the linked list called the FAT...This process consumed a small valuable time which gives a 'small pause' to the streaming for a small time interval, which results in a periodic distortion in the audio. This is the main problem of my earlier version of wav player (made 2 months ago).  Then after getting the next cluster address, the wav data in the next cluster is streamed to the PWM register, and the process is continued untill a 0xFFFF is read from any successive FAT reading, which denotes the end of file.
However, the above mentioned 'periodic noise' is suppressed to an extent in my updated wav player (updated on 06/09/2011)
   Here, I introduced two buffers of 64-byte each and the steaming is loaded to the 64byte buffers and I used timer interrupt to send the buffered data to the PWM register. Then I observed an improvement in the audio(as in above video). The reason for the improvement is the buffer still streams the data stored in it while the uC is capturing the next cluster address from the FAT. Any way, for high bit rate wav files, still this 64 byte buffer is not enough for the purpose, but I am helpless since RAM memory is limited in PIC16F877A.

       I  didn't used any FAT library for the purpose, and I wrote my own code to access the FAT. Any way, I am trying to do it in a much better way, and if I feel any improvement in audio, then I will update it here.........(last update - 06/09/2011)

   Also, I am planning to introduce a wireless control, most probably a TV remote control to control the wave player. I prefer a TV remote just because it have many keys and thus I could implement a lot of functions (mute, play, pause, fvd, rev, next song, previous song etc etc all in the same PIC16F877A) by software modification.

CIRCUIT DIAGRAM:


FAT16 FILE SYSTEM:
Structure
After formatting an MMC using a FAT16 file system, its total memory is divided to various blocks as in below diagram.


Boot Record

 This information is located in the first sector of every partition.

OffsetDescriptionSize
00hJump Code + NOP3 Bytes
03hOEM Name8 Bytes
0BhBytes Per Sector1 Word
0DhSectors Per Cluster1 Byte
0EhReserved Sectors1 Word
10hNumber of Copies of FAT1 Byte
11hMaximum Root Directory Entries1 Word
13hNumber of Sectors in Partition Smaller than 32MB1 Word
15hMedia Descriptor (F8h for Hard Disks)1 Byte
16hSectors Per FAT1 Word
18hSectors Per Track1 Word
1AhNumber of Heads1 Word
1ChNumber of Hidden Sectors in Partition1 Double Word
20hNumber of Sectors in Partition1 Double Word
24hLogical Drive Number of Partition1 Word
26hExtended Signature (29h)1 Byte
27hSerial Number of Partition1 Double Word
2BhVolume Name of Partition11 Bytes
36hFAT Name (FAT16)8 Bytes
3EhExecutable Code448 Bytes
1FEhExecutable Marker (55h AAh)2 Bytes


FAT16 Drive Layout

OffsetDescription
Start of PartitionBoot Sector
Start + # of Reserved SectorsFat Tables
Start + # of Reserved + (# of Sectors Per FAT * 2)Root Directory Entry
Start + # of Reserved + (# of Sectors Per FAT * 2) + ((Maximum
Root Directory Entries * 32) / Bytes per Sector)
Data Area (Starts with Cluster #2)

Cluster Meaning (FAT Table Entries)

A Cluster is a Group of Sectors on the MMC or Hard Drive that have information in them. A 16K Cluster has 32 Sectors in it (512*32=16384).  Each Cluster is given a spot in the FAT Table.  When you look at an Entry in the FAT, the number there tells you whether or not that cluster has data in it, and if so, if it is the end of the data or there is another cluster after it.  All Data on a Partition starts with Cluster #2 (Right after Root Directory).    If the FAT Entry is 0, then there is no data in that cluster.  If the FAT Entry is FFFFh, then it is the last entry in the chain. 


FAT Code RangeMeaning
0000hAvailable Cluster
0002h-FFEFhUsed, Next Cluster in File
FFF0h-FFF6hReserved Cluster
FFF7hBAD Cluster
FFF8h-FFFFUsed, Last Cluster in File



The link from which i got many information about FAT16 file system is http://home.teleport.com/~brainy/fat16.htm (Thanks to Mr Jack Dobiash for the providing the excellent tutorial about FAT file system)

WAVE FILE STRUCTURE:

       The WAVE file format is a subset of Microsoft's RIFF specification for the storage of multimedia files. A RIFF file starts out with a file header followed by a sequence of data chunks. A WAVE file is often just a RIFF file with a single "WAVE" chunk which consists of two sub-chunks -- a "fmt " chunk specifying the data format and a "data" chunk containing the actual sample data. 






As an example, here are the opening 72 bytes of a WAVE file with bytes shown as hexadecimal numbers:

52 49 46 46 24 08 00 00 57 41 56 45 66 6d 74 20 10 00 00 00 01 00 02 00 
22 56 00 00 88 58 01 00 04 00 10 00 64 61 74 61 00 08 00 00 00 00 00 00 
24 17 1e f3 3c 13 3c 14 16 f9 18 f9 34 e7 23 a6 3c f2 24 f2 11 ce 1a 0d  
 


PROGRAM (C): 
/*
------------------------------------------------------------
PIC16F877A + MMC WAV PLAYER
(code updated on 06/09/2011)
improved audio quality compared to
previous version.
------------------------------------------------------------
Compiler -High Tech C
------------------------------------------------------------
Author: Vinod S
<vinodstanur@gmail.com>
http://vinodstanur.blogspot.com
------------------------------------------------------------
*/
#include<pic.h>
#define _XTAL_FREQ 20e6
#define CS RC2
#define RS RB2
#define EN RB1
#define fst cmd(0x80)
#define snd cmd(0xc0)
unsigned int i, g, trickl, trickr;
unsigned long int lg;
unsigned int fat_start, dir_start, count, data_start, scan, numm, numm1;
unsigned char buf[64], play1[64], play2[64], no, status, sect_per_clst, bb;
unsigned long int long1, long2, bitrate;
unsigned char readdata, readdata2, u, speed, check, zz, zx;
unsigned int count;
float flt;
bit toggle;
bit set;
/*-----------------LCD BEGIN----------------------------*/
void LCD_STROBE(void)
{
    EN = 1;
    __delay_us(0.5);
    EN = 0;
}

void data(unsigned char c)
{
    RS = 1;
    __delay_us(40);
    PORTD = (c >> 4);
    LCD_STROBE();
    PORTD = (c);
    LCD_STROBE();
}

void cmd(unsigned char c)
{
    RS = 0;
    __delay_us(40);
    PORTD = (c >> 4);
    LCD_STROBE();
    PORTD = (c);
    LCD_STROBE();
}

void clear(void)
{
    cmd(0x01);
    __delay_ms(2);
}

void lcd_init()
{
    __delay_ms(20);
    cmd(0x30);
    __delay_ms(1);
    cmd(0x30);
    __delay_ms(1);
    cmd(0x30);
    cmd(0x28);            // Function set (4-bit interface, 2 lines, 5*7Pixels)
    cmd(0x28);            // Function set (4-bit interface, 2 lines, 5*7Pixels)
    cmd(0x28);            // Function set (4-bit interface, 2 lines, 5*7Pixels)
    cmd(0x0c);            // Make cursorinvisible
    clear();
    clear();            // Clear screen
    cmd(0x6);            // Set entry Mode
}

void string(const char *q)
{
    while (*q) {
        data(*q++);
    }
}

void istring(unsigned int q)
{
    data(48 + (q / 10000));
    q %= 10000;
    data(48 + (q / 1000));
    q %= 1000;
    data(48 + (q / 100));
    q %= 100;
    data(48 + (q / 10));
    q %= 10;
    data(48 + (q));
}

itostr(unsigned long int q)
{
    cmd(0x81);
    data(48 + (q / 1000000000));
    q %= 1000000000;
    data(48 + (q / 100000000));
    q %= 100000000;
    data(48 + (q / 10000000));
    q %= 10000000;
    data(48 + (q / 1000000));
    q %= 1000000;
    data(48 + (q / 100000));
    q %= 100000;
    data(48 + (q / 10000));
    q %= 10000;
    data(48 + (q / 1000));
    q %= 1000;
    data(48 + (q / 100));
    q %= 100;
    data(48 + (q / 10));
    q %= 10;
    data(48 + (q));
}

void cstring(unsigned int q)
{
    data(48 + (q / 100));
    q %= 100;
    data(48 + (q / 10));
    q %= 10;
    data(48 + (q));
}

/*-----------------------LCD END--------------------*/
/*-----------------------USRT BEGIN--------------------*/
void usrt_init()
{
    TRISC6 = 0;
    TXSTA = 0b00100110;
    RCSTA = 0b11010000;
    SPBRG = 10;
}

void printf(const char *p)
{
    while (*p) {
        TXREG = *p;
        while (TRMT == 0);
        p++;
    }
}

void txd(unsigned char vv)
{
    TXREG = vv;
    while (TRMT == 0);
}

/*-----------------------USRT END---------------------*/

/*----------------------PWM BEGINS--------------------*/
void pwm_init()
{
    TRISC1 = 0;
    T2CKPS1 = 0;
    T2CKPS0 = 0;
    PR2 = 200;
    CCPR2L = 0x10;
    TMR2ON = 1;
    CCP2CON = 0b00001100;
}

void pwm_disable()
{
    CCP2CON = 0b00000000;
}

void pwm_enable()
{
    CCP2CON = 0b00001100;
}

/*--------------------PWM END------------------------*/
/*----------------------TIMER1 BEGINS--------------------*/
void timer1_init()
{
    T1CON = 0b00000001;
    TMR1IE = 1;
    GIE = 1;
    PEIE = 1;
}

void timer0_init()
{
    OPTION_REG = 0b00000000;
    T0IE = 1;
    GIE = 1;
}

/*--------------------TIMER1 END------------------------*/
/*-------------------MMC BEGIN-----------------------*/
void spi_init()
{
    TRISC4 = 1;
    RC2 = 1;
    RC3 = 0;
    RC5 = 0;
    TRISC2 = TRISC3 = TRISC5 = 0;
    SSPCON = 0b00100010;
    SSPEN = 1;
    SMP = 0;
    CKE = 1;
    CKP = 0;
}

void spi_write(unsigned char kk)
{
    SSPBUF = kk;
    while (BF == 0);
}

void spi_read()
{
    SSPBUF = 0xff;
    while (BF == 0);
    readdata = SSPBUF;
}

void command(char command, unsigned long int fourbyte_arg, char CRCbits)
{
    spi_write(0xff);
    spi_write(0b01000000 | command);
    spi_write((unsigned char) (fourbyte_arg >> 24));
    spi_write((unsigned char) (fourbyte_arg >> 16));
    spi_write((unsigned char) (fourbyte_arg >> 8));
    spi_write((unsigned char) fourbyte_arg);
    spi_write(CRCbits);
    spi_read();
}

void mmc_init()
{
    CS = 1;
    for (u = 0; u < 50; u++) {
        spi_write(0xff);
    }
    CS = 0;
    __delay_ms(1);
    command(0, 0, 0x95);
    count = 0;
    while ((readdata != 1) && (count < 1000)) {
        spi_read();
        count++;
    }
    if (count >= 1000) {
        string("CARD ERROR-CMD0 ");
        while (1);
    }
    command(1, 0, 0xff);
    count = 0;
    while ((readdata != 0) && (count < 1000)) {
        command(1, 0, 0xff);
        spi_read();
        count++;
    }
    if (count >= 1000) {
        string("CARD ERROR-CMD1 ");
        while (1);
    }
    command(16, 512, 0xff);
    count = 0;
    while ((readdata != 0) && (count < 1000)) {
        spi_read();
        count++;
    }
    if (count >= 1000) {
        string("CARD ERROR-CMD16");
        while (1);
    }
    string("MMC INITIALIZED!");
    __delay_ms(290);
    SSPCON = SSPCON & 0b11111101;
}

void write(unsigned char dataa, unsigned long int sector)
{
    long1 = sector;
    long1 *= 512;
    command(24, long1, 0xff);
    while (readdata != 0) {
        spi_read();
    }
    spi_write(0xff);
    spi_write(0xff);
    spi_write(0b11111110);
    for (int g = 0; g < 512; g++) {
        spi_write(dataa);
    }
    spi_write(0xff);
    spi_write(0xff);
    spi_read();
    while ((readdata & 0b00011111) != 0x05) {
        spi_read();
    }
    while (readdata != 0xff) {
        spi_read();
    }
}

void load_to_buf(unsigned long int sector, unsigned char num)
{
    long1 = sector;
    long1 *= 512;
    command(17, long1, 0xff);
    while (readdata != 0) {
        spi_read();
    }
    while (readdata != 0xfe) {
        spi_read();
    }
    trickl = 64;
    trickl *= num;
    trickr = 448 - trickl;
    for (g = 0; g < trickl; g++) {
        spi_read();
    }
    for (g = 0; g < 64; g++) {
        spi_read();
        buf[g] = readdata;
    }
    for (g = 0; g < trickr; g++) {
        spi_read();
    }
    spi_write(0xff);
    spi_write(0xff);
}

void read(unsigned long int c)
{
    for (i = 0; i <= sect_per_clst; i++) {
        long1 = 512 * c;
        command(17, long1, 0xff);
        while (readdata != 0) {
            spi_read();
        }
        while (readdata != 0xfe) {
            spi_read();
        }
        for (g = 0; g < 4; g++) {
            while (toggle == 0);
            {
                for (zx = 0; zx < 64; zx++) {
                    spi_read();
                    play2[zx] = readdata;
                }
            }
            while (toggle == 1);
            {
                for (zx = 0; zx < 64; zx++) {
                    spi_read();
                    play1[zx] = readdata;
                }
            }
        }
        spi_write(0xff);
        spi_write(0xff);
        c += 1;
    }
}

/*--------------------------FAT ACCESS-----------------------------*/
void fat_init()            //BOOT SECTOR SCANNING//
{
    load_to_buf(0, 0);
    fat_start = buf[0x0e];
    dir_start = (fat_start + (((buf[0x17] << 8) + buf[0x16]) * 2));
    data_start = (dir_start + ((((buf[0x12] << 8) + (buf[0x11])) * 32) / 512));
    sect_per_clst = buf[0x0d];
}

unsigned int find_next_cluster(unsigned int clstt)
{
    numm1 = (2 * (clstt % 256));
    load_to_buf((fat_start + (clstt / 256)), numm1 / 64);
    numm = numm1 % 64;
    return ((buf[numm + 1] << 8) + buf[numm]);
}

void play_file(unsigned int clstr)
{
    long2 = clstr - 2;
    long2 *= sect_per_clst;
    long2 += data_start;
    load_to_buf(long2, 0);
    for (u = 31; u > 27; u--) {
        bitrate <<= 8;
        bitrate += buf[u];
    }
    itostr(bitrate);
    flt = 1.4 * 1250000 / bitrate;
    bb = 255 - flt;
    cmd(0xc0);
    istring(bb);
    TMR0IE = 1;
    while (clstr != 0xffff) {
        long2 = clstr - 2;
        long2 *= sect_per_clst;
        long2 += data_start;
        read(long2);
        if (((buf[numm + 3] << 8) + buf[numm + 2]) != (clstr + 1)) {
            clstr = find_next_cluster(clstr);
            } else {
            clstr++;
            numm++;
        }
    }
    cmd(0xc0);
    string("read complete   ");
    __delay_ms(1000);
    TMR0IE = 0;
}

void file_scan()
{
    scan:scan = dir_start;
    no = 0;
    while (1) {
        load_to_buf(scan, no);
        if ((buf[1] != 0) && (buf[2] != 0) && (buf[0] != 0xe5) && (buf[0] != 0x00) && ((buf[11]) & 0b00010000) == 0) {
            fst;
            clear();
            for (g = 0; g < 11; g++) {
                data(buf[g]);
            }
            for (lg = 0; lg < 140000; lg++) {
                if (RE0 == 1) {
                    status = 1;
                    break;
                }
            }
        }
        if (status == 1) {
            play_file((buf[27] << 8) + buf[26]);
            status = 0;
            break;
        }
        if (buf[32] == 0) {
            break;
        }
        if ((buf[33] != 0) && (buf[34] != 0) && (buf[32] != 0xe5) && ((buf[43]) & 0b00010000) == 0) {
            fst;
            clear();
            for (g = 32; g < 43; g++) {
                data(buf[g]);
            }
            for (lg = 0; lg < 140000; lg++) {
                if (RE0 == 1) {
                    status = 2;
                    break;
                }
            }
            fst;
            clear();
        }
        no++;
        if (no == 8) {
            no = 1;
            scan += 1;
        }
        if (status == 2) {
            play_file((buf[27 + 32] << 8) + buf[26 + 32]);
            status = 0;
            break;
        }
    }
    goto scan;
}

/*------------------------------mmc end-------------------------------*/
/*---------------------------ADC functions----------------------------*/
void adc_init()
{
    TRISA0 = 1;
    ADCON0 = 0b10000001;
    ADCON1 = 0b10001110;
}

/*---------------------------ADC END----------------------------*/
void interrupt timer()
{
    if (toggle == 1) {
        CCPR2L = play1[zz];
        zz++;
        if (zz == 64) {
            zz = 0;
            toggle = 0;
        }
        } else if (toggle == 0) {
        CCPR2L = play2[zz];
        zz++;
        if (zz == 64) {
            zz = 0;
            toggle = 1;
        }
    }
    TMR0 = bb;
    TMR0IF = 0;
}

main()
{
    CS = 1;
    PORTD = 0;
    TRISC4 = 0;
    TRISC5 = 0;
    TRISD = 0;
    TRISB2 = 0;
    TRISB1 = 0;
    TRISB6 = 0;
    TRISB7 = 0;
    TRISE0 = 1;
    TRISE1 = 1;
    lcd_init();
    adc_init();
    usrt_init();
    spi_init();
    mmc_init();
    fat_init();
    timer0_init();
    pwm_init();
    pwm_enable();
    speed = 0;
    RB7 = 0;
    count = 0;
    CS = 0;
    no = 0;
    zz = 0;
    while (1) {
        file_scan();
        for (;;);
    }
} 

HEX FILE: (NEW)
:060000000A128A11122809
:10000800FE00030EF1000408F2000A08F300831250
:1000180003137F08F4000A168A11B72D0A168A11ED
:100028002A2D81300A168A11E1240A128A113B30DE
:1000380083120313A3009A30A200CA30A100003033
:10004800A0003108A7003008A6002F08A5002E0838
:10005800A4000A128A15D4200A128A1183120313E3
:100068002008303E0A168A11BD240A128A113B3034
:1000780083120313A3009A30A200CA30A1000030F3
:10008800A0003108A7003008A6002F08A5002E08F8
:10009800A4000A168A1139270A128A118312031337
:1000A8002308B1002208B0002108AF002008AE00E4
:1000B8000530A300F530A200E130A1000030A00017
:1000C8003108A7003008A6002F08A5002E08A400B4
:1000D8000A128A15D4200A128A11831203132008DF
:1000E800303E0A168A11BD240A128A11053083127D
:1000F8000313A300F530A200E130A1000030A000F6
:100108003108A7003008A6002F08A5002E08A40073
:100118000A168A1139270A128A118312031323082F
:10012800B1002208B0002108AF002008AE0000305E
:10013800A3009830A2009630A1008030A0003108BA
:10014800A7003008A6002F08A5002E08A4000A1250
:100158008A15D4200A128A11831203132008303E0C
:100168000A168A11BD240A128A1100308312031359
:10017800A3009830A2009630A1008030A00031087A
:10018800A7003008A6002F08A5002E08A4000A160C
:100198008A1139270A128A11831203132308B1001E
:1001A8002208B0002108AF002008AE000030A300EC
:1001B8000F30A2004230A1004030A0003108A70053
:1001C8003008A6002F08A5002E08A4000A128A15D8
:1001D800D4200A128A11831203132008303E0A160B
:1001E8008A11BD240A128A11003083120313A30056
:1001F8000F30A2004230A1004030A0003108A70013
:100208003008A6002F08A5002E08A4000A168A1197
:1002180039270A128A11831203132308B10022080E
:10022800B0002108AF002008AE000030A300013064
:10023800A2008630A100A030A0003108A700300835
:10024800A6002F08A5002E08A4000A128A15D4209B
:100258000A128A11831203132008303E0A168A11E3
:10026800BD240A128A11003083120313A30001303F
:10027800A2008630A100A030A0003108A7003008F5
:10028800A6002F08A5002E08A4000A168A113927EF
:100298000A128A11831203132308B1002208B0003E
:1002A8002108AF002008AE000030A3000030A200F3
:1002B8002730A1001030A0003108A7003008A600A0
:1002C8002F08A5002E08A4000A128A15D4200A12A5
:1002D8008A11831203132008303E0A168A11BD249E
:1002E8000A128A11003083120313A3000030A200FF
:1002F8002730A1001030A0003108A7003008A60060
:100308002F08A5002E08A4000A168A1139270A12F8
:100318008A11831203132308B1002208B0002108B0
:10032800AF002008AE000030A3000030A200033068
:10033800A100E830A0003108A7003008A6002F0867
:10034800A5002E08A4000A128A15D4200A128A11C0
:10035800831203132008303E0A168A11BD240A129C
:100368008A11003083120313A3000030A200033067
:10037800A100E830A0003108A7003008A6002F0827
:10038800A5002E08A4000A168A1139270A128A1114
:10039800831203132308B1002208B0002108AF001C
:1003A8002008AE000030A3000030A2000030A100F9
:1003B8006430A0003108A7003008A6002F08A50067
:1003C8002E08A4000A128A15D4200A128A11831250
:1003D80003132008303E0A168A11BD240A128A1116
:1003E800003083120313A3000030A2000030A100E4
:1003F8006430A0003108A7003008A6002F08A50027
:100408002E08A4000A168A1139270A128A118312A3
:1004180003132308B1002208B0002108AF00200808
:10042800AE000030A3000030A2000030A1000A3066
:10043800A0003108A7003008A6002F08A5002E0844
:10044800A4000A128A15D4200A128A1183120313EF
:100458002008303E0A168A11BD240A128A1100307B
:1004680083120313A3000030A2000030A1000A3059
:10047800A0003108A7003008A6002F08A5002E0804
:10048800A4000A168A1139270A128A118312031343
:100498002308B1002208B0002108AF002008AE00F0
:1004A8002E08303E0A168A11BD240A128A11080045
:1004B800831203134308FE3ED10044080318013E8B
:1004C800FF3ED200D301D4016A08C500C601C701A6
:1004D800C8014808A3004708A2004608A10045082B
:1004E800A0005408A7005308A6005208A500510808
:1004F800A4000A128A11B1270A128A11831203135F
:100508002308D4002208D3002108D2002008D100F3
:100518005708C5005808C600C701C8014508D107D3
:10052800460803110318013E03199B2AD2074708FE
:1005380003110318013E0319A22AD307480803111F
:100548000318013E0319A92AD4075408AE0053081A
:10055800AD005208AC005108AB00AF010A128A1571
:10056800E6240A128A111F3083120313C5004508B6
:10057800ED001C306D020318C22AC32AC52A0F2BAE
:100588000F2B0830C500031083160313E50DE60D85
:10059800E70DE80D83120313C50BC72A6D08A03EAB
:1005A800840083130008C500C601C701C8014508B7
:1005B80083160313E5078312031346080311031870
:1005C800013E0319EA2A83160313E607831203136D
:1005D800470803110318013E0319F52A831603136C
:1005E800E70783120313480803110318013E031990
:1005F800002B83160313E8078312031383160313D0
:10060800013083120313ED021C306D0203180D2B09
:100618000E2BC52A0F2B83160313680883120313A6
:10062800B10083160313670883120313B0008316FF
:100638000313660883120313AF00831603136508B8
:1006480083120313AE000A128A1115200A128A11A6
:1006580083160313680883120313AB00831603136E
:10066800670883120313AA0083160313660883120C
:100678000313A90083160313650883120313A80044
:100688000A168A1181250A128A118312031328086F
:10069800AE002908AF002A08B000A030B100D5305C
:1006A800B2004930B3000A128A1550230A128A117F
:1006B800831203132E0883160313E0008312031317
:1006C8002F0883160313E1008312031330088316DF
:1006D8000313E200600883120313A00083160313B8
:1006E800610883120313A10083160313620883129F
:1006F8000313A2000A168A115D240A128A118312B2
:1007080003132008B9002108BA002208BB000030F2
:10071800B6007F30B7004330B8000A128A15BA26EF
:100728000A128A11831203133608A8003708A90091
:100738003808AA000A128A15AA220A128A118312F4
:1007480003132808C5004508E700C0300A168A11B7
:10075800E1240A128A11831203136708C500C6012F
:100768004508A8004608A9000A128A1518240A1282
:100778008A118B16592C831203134308FE3ED100AD
:1007880044080318013EFF3ED200D301D4016A0891
:10079800C500C601C701C8014808A3004708A20050
:1007A8004608A1004508A0005408A7005308A60061
:1007B8005208A5005108A4000A128A11B1270A128A
:1007C8008A11831203132308D4002208D3002108B6
:1007D800D2002008D1005708C5005808C600C70134
:1007E800C8014508D107460803110318013E03193B
:1007F800FE2BD207470803110318013E0319052CE5
:10080800D307480803110318013E03190C2CD40719
:100818005408AE005308AD005208AC005108AB00B4
:100828000A128A15C8250A128A118312031361084D
:10083800033EA03E840083130008C5006108023E01
:10084800A03E84004308013EC60044080318013E48
:10085800003EC70045084706031D342C000846061D
:100868000319372C382C4C2C4408B301B307430820
:10087800B201B2070A168A11DD260A128A118312FA
:1008880003133308C401C4073208C301C307592C32
:100898000130C3070318C40A0030C4070130E10758
:1008A8000318E20A0030E207592CFF3083120313C1
:1008B8004406031D612CFF304306031D642C652C80
:1008C800BF2B662CC0300A168A11E1240A128A113D
:1008D80001300A168A1105250A128A111A30831264
:1008E8000313C7005E30C6008630C500C50B7A2CDE
:1008F800C60B7A2CC70B7A2C64008B120800831263
:1009080003135A0883160313E401E407831203133D
:10091800590883160313E301E30783120313E8015D
:10092800952C83160313630883120313AB008316F5
:100938000313640883120313AC00AD01AE01680809
:1009480083160313E900690883120313AF000A1220
:100958008A15E6240A128A11831603132108031D37
:10096800B62C442D2208031DBA2C442D2008E53A44
:100978000319BF2CC02C442D2008031DC42C442D62
:100988002B1AC72CC82C442D80300A168A11E12452
:100998000A128A110A168A116B240A128A11831202
:1009A8000313DD01DE0100305E020B3003195D0226
:1009B800031CDF2CE02CE22CFE2CFE2C5D08A03E54
:1009C8008400831300080A168A11BD240A128A11AA
:1009D800013083120313DD070318DE0A0030DE0737
:1009E80000305E020B3003195D02031CFC2CFD2C49
:1009F800E22CFE2C0030CC000030CB000030CA00C6
:100A08000030C90000304C02031D142D02304B0287
:100A1800031D142D22304A02031D142DE030490213
:100A2800031C172D182D1A2D442D442D091C1D2D7E
:100A38001E2D222DEC010314EC0D442D0130C907A5
:100A4800003003180130CA07003003180130CB0703
:100A5800003003180130CC0700304C02031D3E2D36
:100A680002304B02031D3E2D22304A02031D3E2D4B
:100A7800E0304902031C412D422D1A2D442D442DEE
:100A880083126C08013A031D4A2D4B2D6A2D8316DB
:100A980003133B08E900EA016908EA00E9013A089A
:100AA800690783120313C30000300318013083164B
:100AB80003136A0783120313C4000A128A115C2203
:100AC8000A128A1183120313EC01832C8316031371
:100AD800C008031D702D712D732D832C832C4108A4
:100AE800031D772D132E4208031D7B2D132E40085E
:100AF800E53A0319802D812D132E4B1A842D852D4F
:100B0800132E80300A168A11E1240A128A110A1655
:100B18008A116B240A128A11203083120313DD0014
:100B28000030DE0000305E022B3003195D02031C2A
:100B38009E2D9F2DA12DBD2DBD2D5D08A03E8400AD
:100B4800831300080A168A11BD240A128A1101307B
:100B580083120313DD070318DE0A0030DE070030B6
:100B68005E022B3003195D02031CBB2DBC2DA12D89
:100B7800BD2D0030CC000030CB000030CA00003062
:100B8800C90000304C02031DD32D02304B02031D57
:100B9800D32D22304A02031DD32DE0304902031C15
:100BA800D62DD72DD92D072E072E091CDC2DDD2D8E
:100BB800E62D023083160313E90069088312031334
:100BC800EC00072E0130C907003003180130CA07AE
:100BD800003003180130CB07003003180130CC0770
:100BE80000304C02031D022E02304B02031D022E60
:100BF80022304A02031D022EE0304902031C052E52
:100C0800062ED92D072E80300A168A11E1240A12E1
:100C18008A110A168A116B240A128A11132E0130BE
:100C280083160313E900690883120313E8076808A9
:100C3800083A031D202E212E2D2EE8010314E80D5D
:100C4800013083160313E3070318E40A0030E407AE
:100C58002D2E83126C08023A031D332E342E952C48
:100C6800831603135B08E900EA016908EA00E90151
:100C78005A08690783120313C300003003180130B0
:100C8800831603136A0783120313C4000A128A1116
:100C98005C220A128A1183120313EC01832C952C0F
:100CA800952C832C0800831203130715ED013230AD
:100CB8006D02031C602E612E632E752E752EFF307B
:100CC8000A168A114F240A128A110130831203135B
:100CD800AB002B08ED0732306D02031C742E752E05
:100CE800632E07110730AC007D30AB00AB0B7A2EBA
:100CF800AC0B7A2E003083120313A4000030A3003B
:100D08000030A2000030A1009530AB002B08A500F0
:100D180000300A128A1544210A128A118312031319
:100D2800D501D601A52E0A168A1190240A128A1115
:100D3800013083120313D5070318D60A0030D607EB
:100D4800A52E6908013A0319AA2EAB2EB62E033038
:100D58005602E83003195502031CB32EB42E972E01
:100D6800B62EB62E03305602E83003195502031C7E
:100D7800BE2EBF2EC82E12300A168A1105250A1259
:100D88008A11C62EC62EC82E003083120313A40063
:100D98000030A3000030A2000030A100FF30AB00FB
:100DA8002B08A50001300A128A1544210A128A115B
:100DB80083120313D501D601012F0030A40000309F
:100DC800A3000030A2000030A100FF30AB002B08C8
:100DD800A50001300A128A1544210A128A110A163E
:100DE8008A1190240A128A11013083120313D5073D
:100DF8000318D60A0030D607012F6908031D052FEE
:100E0800102F03305602E83003195502031C0D2F2A
:100E18000E2FE12E102F102F03305602E830031941
:100E28005502031C182F192F222F23300A168A1156
:100E380005250A128A11202F202F222F0030831215
:100E48000313A4000030A3000230A2000030A10068
:100E5800FF30AB002B08A50010300A128A15442178
:100E68000A128A1183120313D501D601492F0A16D3
:100E78008A1190240A128A11013083120313D507AC
:100E88000318D60A0030D607492F6908031D4D2FCD
:100E9800582F03305602E83003195502031C552F0A
:100EA800562F3B2F582F582F03305602E83003197E
:100EB8005502031C602F612F6A2F45300A168A11CC
:100EC80005250A128A11682F682F6A2F34300A16EE
:100ED8008A1105250A128A111A3083120313AD00EC
:100EE8005E30AC008630AB00AB0B782FAC0B782FA4
:100EF800AD0B782F640080300A168A11E1240A129B
:100F08008A110A168A116B240A128A1166300A1687
:100F18008A1105250A128A11C0300A168A11E1249D
:100F28000A128A1156300A168A1105250A128A11E0
:100F38007F3083120313AD00D430AC00AE30AB0069
:100F4800AB0BA42FAC0BA42FAD0BA42FAB2F83128C
:100F580003131408FD3994000800003083120313AA
:100F6800AC000030AB000030AA000030A900BC2F54
:100F7800201CBF2FC02FD82F2408A907250803112C
:100F88000318013E0319C92FAA07260803110318DD
:100F9800013E0319D02FAB07270803110318013EA0
:100FA8000319D72FAC07D82F0130A8000310A40DC0
:100FB800A50DA60DA70DA80BDA2F01300310A30C61
:100FC800A20CA10CA00CFF3E031DE22F2308220453
:100FD80021042004031DF12FF22FBC2FF32F2C081E
:100FE800A3002B08A2002A08A1002908A000FC2FB2
:020FF8000800EF
:1010000008308A000408840A820700347234653488
:1010100061346434203463346F346D3470346C3430
:10102000653474346534203420342034003443343F
:1010300041345234443420344534523452344F34E1
:1010400052342D3443344D3444343034203400345D
:1010500043344134523444342034453452345234CD
:101060004F3452342D3443344D34443431342034ED
:1010700000344D344D344334203449344E344934F3
:101080005434493441344C3449345A34453444346A
:101090002134003443344134523444342034453410
:1010A000523452344F3452342D3443344D3444345A
:1010B00031343634003462346C346F3467342E3457
:1010C000763469346E3475342E3463346F342E3490
:1010D00069346E340034763469347334693474346A
:1010E00020346D347934203462346C346F34673496
:0210F0000034CA
:1010F400823083120313A500DD30A400A40B8028E2
:10110400A50B8028852830300A168A11E1240A129A
:101114008A15073083120313A5007D30A400A40BA5
:101124009128A50B912830300A168A11E1240A125D
:101134008A15073083120313A5007D30A400A40B85
:10114400A128A50BA12830300A168A11E1240A121D
:101154008A1528300A168A11E1240A128A152830C1
:101164000A168A11E1240A128A1528300A168A11ED
:10117400E1240A128A150C300A168A11E1240A1293
:101184008A150A168A116B240A128A150A168A11FC
:101194006B240A128A1506300A168A11E1240A12EF
:1011A4008A150800003083120313AC000030AB0032
:1011B4000030AA000030A9002308220421042004DE
:1011C4000319E528E6283A29AD010314AD0DF828E2
:1011D4000130A8000310A00DA10DA20DA30DA80BB2
:1011E400EC280130A8002808AD07F828A31FFB2825
:1011F400FC28EA28FE28FE280130A8000310A90DC7
:10120400AA0DAB0DAC0DA80B002923082702031D62
:10121400152922082602031D152921082502031D6C
:10122400152920082402031C182919292929200812
:10123400A4022108031C210FA5022208031C220F6B
:10124400A6022308031C230FA7022914292901300D
:101254000310A30CA20CA10CA00CFF3E031D2A2911
:101264000130AD02031D37293829FE283A293A29CD
:101274002C08A3002B08A2002A08A1002908A0001A
:101284004329080083120313AA00FF300A168A11A7
:101294004F240A128A15831203132A0840380A16A7
:1012A4008A114F240A128A15831203132108A600F7
:1012B4002208A7002308A8002408A9001830031056
:1012C400A90CA80CA70CA60CFF3E031D6129260837
:1012D4000A168A114F240A128A158312031321084D
:1012E400A6002208A7002308A8002408A90010309B
:1012F4000310A90CA80CA70CA60CFF3E031D7A2909
:1013040026080A168A114F240A128A158312031317
:101314002108A6002208A7002308A8002408A90081
:1013240008300310A90CA80CA70CA60CFF3E031D43
:10133400932926080A168A114F240A128A15831241
:10134400031321080A168A114F240A128A158312DC
:10135400031325080A168A114F240A128A150A163D
:101364008A1190240A128A15080083120313A60115
:10137400A11FBD29BE29C729A009A109A00A0319D3
:10138400A10AA6010314A60DC729A31FCA29CB29A4
:10139400D529A209A309A20A0319A30A0130A400AA
:1013A4002408A606D529A701A801210820040319A9
:1013B400DC29DD291B2AA5010314A50DED29013023
:1013C4000310A00DA10DFF3E031DE2290130A4006E
:1013D4002408A507ED29A11FF029F129E129F32902
:1013E400F32901300310A70DA80DFF3E031DF429B6
:1013F40021082302031D002A20082202031C032AB9
:10140400042A0C2A2008A2022108031CA303A30215
:1014140027140C2A01300310A10CA00CFF3E031D5D
:101424000D2A0130A502031D182A192AF3291B2AA3
:101434001B2A2608031D1F2A252AA709A809A70A6B
:101444000319A80A252A2808A101A1072708A00131
:10145400A0072C2A0800831203132308031D332A30
:101464003B2A220821042004031D392A3A2A512A3E
:101474003B2A0030A0000030A1000030A200A92ABD
:10148400A92A512A0130A5002508A3070130031019
:10149400A20CA10CA00CFF3E031D492A512AFE30C8
:1014A4002205031D562A572A442A6F2A6F2A01301F
:1014B400A5002508A3070130A00700300318013058
:1014C400A107003003180130A20701300310A20C59
:1014D400A10CA00CFF3E031D682AFF302205031D4A
:1014E400742A752A592A822A822A0130A3020130D9
:1014F4000310A00DA10DA20DFF3E031D7A2A822A1E
:10150400A11F852A862A772A2318892A8A2A902ABB
:10151400FF30A0057F30A105FF30A2050310A30C06
:101524002308A500A601A70110300310A50DA60DE0
:10153400A70DFF3E031D972A2508A0042608A10431
:101544002708A2042408031DA82AA92AA217080010
:10155400831203132808AC002908AD002A08AE0042
:1015640003102D0D2E0DAF002F08B500B508031D77
:10157400BC2ABD2AC72A0030AB000030AA000030C4
:10158400A9000030A8004F2B4F2B2808AC002908D5
:10159400AD002A08AE0017300310AE0CAD0CAC0C35
:1015A400FF3E031DCE2A2C08AF002F08B000A91758
:1015B400FF30A805FF30A9050030AA052808B100AE
:1015C4002908B2002A08B300B4018E30B502B51F51
:1015D400EC2AED2A122B3508803A8F3E0318F32AA1
:1015E400F42AFF2A0030AB000030AA000030A90022
:1015F4000030A8004F2B4F2BFF2A01300310B40CEE
:10160400B30CB20CB10CFF3E031D002B0130AC0037
:101614002C08B507031D0F2B102BFF2A362B362B56
:1016240018303502031C172B182B2F2B0030AB005E
:101634000030AA000030A9000030A8004F2B4F2B27
:101644002F2B0130AC000310B10DB20DB30DB40D4E
:10165400AC0B252B0130B5022F2BB508031D332B02
:10166400342B232B362B362B3008031D3A2B462BD9
:10167400B109B209B309B409B10A0319B20A0319C9
:10168400B30A0319B40A462B3408AB003308AA0082
:101694003208A9003108A8004F2B08008312031355
:1016A4003108B4003208B5003308B6000310350D14
:1016B400360DB7003708BC00BC08031D622B632B32
:1016C4006B2B0030AE000030AF000030B000172CA0
:1016D400172C2E08B4002F08B5003008B6000310EC
:1016E400350D360DB7003708BD00BD08031D7B2B33
:1016F4007C2B842B0030AE000030AF000030B000F3
:10170400172C172C0030B9000030BA000030BB0091
:1017140089303D07B4003408BC023108B4003208F3
:10172400B5003308B60010300310B60CB50CB40C79
:10173400FF3E031D962B3408B7003708BD002E0862
:10174400B4002F08B5003008B60010300310B60CF2
:10175400B50CB40CFF3E031DA82B3408B7003708A2
:10176400BD068030B4003408BD05B217FF30B105A2
:10177400FF30B2050030B305AF17FF30AE05FF30C0
:10178400AF050030B0051830B4003408B800CA2BD7
:1017940001300310B90DBA0DBB0DFF3E031DCB2B59
:1017A40030083302031DDC2B2F083202031DDC2B0F
:1017B4002E083102031CDF2BE02BEC2B2E08B10288
:1017C4002F08031C2F0FB2023008031C300AB30287
:1017D4003914EC2B01300310B10DB20DB30DFF3EE3
:1017E400031DED2B0130B802031DF92BFA2BCA2B74
:1017F400FB2B3908A0003A08A1003B08A2003C08D2
:10180400B4003408A3003D08B5003508A4000A124A
:101814008A152D220A128A15831203132008AE009A
:101824002108AF002208B000172C080010308312E2
:101834000313A0002730A1002908A301A307280847
:10184400A201A2070A168A113C260A128A158312DB
:1018540003132008303E0A168A11BD240A128A1581
:10186400103083120313A0002730A1002908A3011C
:10187400A3072808A201A2070A168A11F6250A124C
:101884008A15831203132108A901A9072008A801B6
:10189400A807E830A0000330A1002908A301A3078A
:1018A4002808A201A2070A168A113C260A128A15E0
:1018B400831203132008303E0A168A11BD240A122B
:1018C4008A15E83083120313A0000330A10029080D
:1018D400A301A3072808A201A2070A168A11F62564
:1018E4000A128A15831203132108A901A9072008E3
:1018F400A801A8076430A0000030A1002908A301B2
:10190400A3072808A201A2070A168A113C260A1274
:101914008A15831203132008303E0A168A11BD2447
:101924000A128A15643083120313A0000030A10048
:101934002908A301A3072808A201A2070A168A11ED
:10194400F6250A128A15831203132108A901A9078F
:101954002008A801A8070A30A0000030A100290827
:10196400A301A3072808A201A2070A168A113C268C
:101974000A128A15831203132008303E0A168A11AC
:10198400BD240A128A150A3083120313A000003002
:10199400A1002908A301A3072808A201A2070A1687
:1019A4008A11F6250A128A15831203132108A90144
:1019B400A9072008A801A8072808303E0A168A119A
:1019C400BD240A128A150800831203132E08D000BE
:1019D4002D08CF002C08CE002B08CD000930B00014
:1019E4000310CD0DCE0DCF0DD00DB00BF22C500841
:1019F400A4004F08A3004E08A2004D08A100FF3028
:101A0400B0003008A50011300A128A1544210A12C8
:101A14008A15122D0A168A1190240A128A15122D7B
:101A240083120313E908031D182D192D0C2D212DE4
:101A3400212D0A168A1190240A128A15212D831247
:101A440003136908FE3A031D282D292D1B2D2A2D69
:101A54004030E5000030E6002F08B000B101300846
:101A6400A0003108A1006608A301A3076508A2012C
:101A7400A2070A168A1155250A128A15831203131E
:101A84002108E601E6072008E501E5076509B0003D
:101A94006609B100B00A0319B10A3008C03EF50066
:101AA40031080318013E013EF600DD01DE01682D18
:101AB4000A168A1190240A128A150130831203131C
:101AC400DD070318DE0A0030DE07682D66085E02B3
:101AD400031D6E2D65085D02031C712D722D5A2D98
:101AE400732DDD01DE0100305E02403003195D021A
:101AF400031C7D2D7E2D802D9F2D9F2D0A168A116E
:101B040090240A128A15831203136908B0005D0831
:101B1400A03E84003008831380000130DD070318E1
:101B2400DE0A0030DE0700305E02403003195D0239
:101B3400031C9D2D9E2D802D9F2DDD01DE01B02DDA
:101B44000A168A1190240A128A150130831203138B
:101B5400DD070318DE0A0030DE07B02D76085E02CA
:101B6400031DB62D75085D02031CB92DBA2DA22DD7
:101B7400BB2DFF300A168A114F240A128A15FF3032
:101B84000A168A114F240A128A15080083120313B5
:101B9400DF01E001AB2E2B08AF002C08B0002D08AC
:101BA400B1002E08B20009300310AF0DB00DB10D15
:101BB400B20DFF3E031DD62D3208D0003108CF00F0
:101BC4003008CE002F08CD005008A4004F08A30011
:101BD4004E08A2004D08A100FF30AF002F08A50059
:101BE40011300A128A1544210A128A15FF2D0A1689
:101BF4008A1190240A128A15FF2D83120313E9080F
:101C0400031D052E062EF92D0E2E0E2E0A168A11F0
:101C140090240A128A150E2E831203136908FE3AC1
:101C2400031D152E162E082E172EDD01DE010030A1
:101C34005E02043003195D02031C212E222E252E80
:101C4400882E882E252EF91C282E292E252E831227
:101C54000313EE0140306E02031C312E322E342E5B
:101C64004F2E4F2E0A168A1190240A128A158312B7
:101C740003136908AF006E08103E84002F08831711
:101C840080000130AF002F08EE0740306E02031CC5
:101C94004C2E4D2E342E4F2E4F2EF918522E532EDD
:101CA4004F2E83120313EE0140306E02031C5B2E91
:101CB4005C2E5E2E782E782E0A168A1190240A1233
:101CC4008A15831203136908AF006E08903E8400DE
:101CD4002F08831780000130AF002F08EE07403033
:101CE4006E02031C762E772E5E2E782E0130DD07D1
:101CF4000318DE0A0030DE0700305E0204300319E8
:101D04005D02031C862E872E252E882EFF300A1690
:101D14008A114F240A128A15FF300A168A114F2499
:101D24000A128A15013083120313AB07003003181B
:101D34000130AC07003003180130AD070030031840
:101D44000130AE070130DF070318E00A0030E00776
:101D5400AB2E6A08AF00B00160083002031DB42E38
:101D64005F082F020318B72EB82ECD2DB92E080008
:101D7400831203133608BC003708BD003808BE00C0
:101D840003103D0D3E0DBF003F08C2003908BC00E2
:101D94003A08BD003B08BE0003103D0D3E0DBF00D8
:101DA4003F08C1004208031DD82EE92E4108420213
:101DB4000318DD2EDE2EF12E4203FF3A4107BC004C
:101DC40019303C02031CE72EE82EF12EE92E3908C7
:101DD400B6003A08B7003B08B800FF2FFF2F4108B0
:101DE400031DF52E052F420841020318FA2EFB2E7F
:101DF400062F4103FF3A4207BC0019303C02031C82
:101E0400042F052F062FFF2F0630BC003C08C0000E
:101E1400B81F0D2F0E2F0F2FC017BB1F122F132FFC
:101E2400142F4017B717FF30B605FF30B705003041
:101E3400B805BA17FF30B905FF30BA050030BB0545
:101E4400410842020318272F282F592F292F013028
:101E54000310B90DBA0DBB0DFF3E031D2A2F01302F
:101E6400C102410842060319382F392F512F01307E
:101E7400C00240080739031D402F412F292F512F3D
:101E8400512F512F01300310B80CB70CB60CFF3E84
:101E9400031D452F0130BC003C08C207512F4208E6
:101EA4004106031D562F572F442F902F902F420881
:101EB400410203185E2F5F2F902F602F0130031013
:101EC400B60DB70DB80DFF3E031D612F0130C202E0
:101ED4004108420603196F2F702F882F0130C0026A
:101EE40040080739031D772F782F602F882F882FFC
:101EF400882F01300310BB0CBA0CB90CFF3E031D34
:101F04007C2F0130BC003C08C107882F42084106E1
:101F1400031D8D2F8E2F7B2F902F902FC01F932F5B
:101F2400942FA52FFF30B606FF30B706FF30B80652
:101F34000130B607003003180130B707003003182A
:101F44000130B807A52F401FA82FA92FBA2FFF30A3
:101F5400B906FF30BA06FF30BB060130B9070030BE
:101F640003180130BA07003003180130BB07BA2F39
:101F7400C0013608B907370803110318370A0319D3
:101F8400C42FBA07380803110318380A0319CB2FD2
:101F9400BB07BB1FCE2FCF2FE32FFF30B906FF3077
:101FA400BA06FF30BB060130B90700300318013010
:101FB400BA07003003180130BB07C0010314C00D79
:101FC400E32F3908A0003A08A1003B08A200420808
:101FD400BC003C08A3004008BD003D08A4000A1250
:101FE4008A152D220A128A15831203132008B600BB
:0C1FF4002108B7002208B800FF2F0800E9
:102834000C30831203139D000800831603138101D7
:102844008B168B170800831203138614292C83120A
:1028540003138610080064008001840A0406031927
:10286400003404062E2C83160313051481308312BE
:1028740003139F008E30831603139F0008008316F2
:102884000313071326309800D030831203139800E3
:102894000A30831603139900080083120313A0005F
:1028A40020089300552C83160313141C5A2C5B2CFC
:1028B400552C5C2C080083120313220821042004E5
:1028C4000319652C662C692C8030A206692C6A2CAD
:1028D400080001300A168A11E1240A168A110D3003
:1028E40083120313A300FB30A200A20B772CA30BCB
:1028F400772C7C2C08008316031387108312031390
:1029040092101210C83083160313920010308312F1
:1029140003139B0012150C309D000800FF30831236
:1029240003139300952C83160313141C9A2C9B2CCD
:10293400952C9C2C831203131308A0002008E90093
:102944000800831603130716831203130715871150
:1029540087128316031387128711071122308312FB
:1029640003139400941683160313941314178312F9
:1029740003131412080083120313A1000615423036
:10298400A000A00BC32C6400831203132108A00031
:1029940004300310A00CFF3E031DCB2C200888003C
:1029A4000A168A1125240A168A1183120313210890
:1029B40088000A168A1125240A168A11080083122F
:1029C4000313A10006114230A000A00BE72C640001
:1029D400831203132108A00004300310A00CFF3E4F
:1029E400031DEF2C200888000A168A1125240A16D4
:1029F4008A1183120313210888000A168A112524D8
:102A04000A168A11080083120313A3001C2D23083D
:102A140084000A128A1500200A168A110A168A11DD
:102A2400BD240A168A11013083120313A20022085E
:102A3400A3071C2D230884000A128A1500200A16F5
:102A44008A110038031D272D282D092D292D080052
:102A5400F901F501F601F701F80183134930840007
:102A640070300A168A112D240A168A11A0308400A7
:102A7400E9300A168A112D240A168A118317903018
:102A84008400D0300A168A112D240A168A111030B7
:102A9400840050300A168A112D240A168A118301E3
:102AA4000A168A118C2E83120313A401A5015A2D30
:102AB400201C5D2D5E2D642D2208A4070318A50A91
:102AC4002308A50701300310A20DA30DFF3E031D2B
:102AD400652D01300310A10CA00CFF3E031D6C2DCD
:102AE40021082004031D772D782D5A2D792D2508D2
:102AF400A101A1072408A001A007802D08008E30A1
:102B040083120313AC002C08AD00962D0130031082
:102B1400AB0CAA0CA90CA80CFF3E031D892D013097
:102B2400AC002C08AD07962DFF302B05031D9B2D03
:102B34009C2D882D9D2D2808A0002908A1002A0875
:102B4400A2002D08AC002C08A300A4010A128A15C7
:102B54002D220A168A11831203132008A8002108C3
:102B6400A9002208AA00B62D0800F91CBA2DBB2D15
:102B7400CF2D6F08903E8400831700089B0001301E
:102B8400F0007008EF076F08403A031DCA2DCB2DE3
:102B9400E82DEF01F910E82DE82DF918D22DD32DE9
:102BA400E82D6F08103E8400831700089B00013055
:102BB400F0007008EF076F08403A031DE22DE32D83
:102BC400E82DEF01F914E82DE82DE82D67088100C0
:102BD4000B117408FF0073088A0072088400710ED8
:102BE4008300FE0E7E0E09008312031321082004C5
:102BF4000319FD2DFE2D342EA5010314A50D0E2E53
:102C040001300310A00DA10DFF3E031D032E013062
:102C1400A4002408A5070E2EA11F112E122E022E89
:102C2400142E142E21082302031D1A2E200822021A
:102C3400031C1D2E1E2E252E2008A2022108031C73
:102C4400A303A302252E01300310A10CA00CFF3E08
:102C5400031D262E0130A502031D312E322E142E03
:102C6400342E342E2308A101A1072208A001A007B5
:102C74003B2E080083120313A601A7012108200498
:102C84000319452E462E842EA5010314A50D562E98
:102C940001300310A00DA10DFF3E031D4B2E01308A
:102CA400A4002408A507562EA11F592E5A2E4A2ED9
:102CB4005C2E5C2E01300310A60DA70DFF3E031DF4
:102CC4005D2E21082302031D692E20082202031C05
:102CD4006C2E6D2E752E2008A2022108031CA3035E
:102CE400A3022614752E01300310A10CA00CFF3E84
:102CF400031D762E0130A502031D812E822E5C2E2B
:102D0400842E842E2708A101A1072608A001A0076C
:102D14008B2E0800831203130715880183160313EF
:102D240007128712880106118610061386130914E8
:102D340089140A128A157A200A168A110A168A1127
:102D440035240A168A110A168A1141240A168A1190
:102D54000A168A11A3240A168A110A128A115726FE
:102D64000A168A110A168A1197270A168A110A1650
:102D74008A111F240A168A110A168A117D240A163A
:102D84008A110A168A111A240A168A118312031345
:102D9400EB018613D501D6010711E801EF01D22E0C
:102DA4000A128A1183240A168A11D72ED22ED22E01
:102DB4000A128A111228FF30831203133205B40059
:102DC40000303305B5000130FF000310B40DB50D1C
:102DD400FF0BE72E3408E3003508E4003308B500A0
:102DE4003208B40008300310B50CB40CFF3E031DC8
:102DF400F52E5B083407AB005C0803185C0A350742
:102E0400AC00AD01AE016408B7006308B60006303B
:102E14000310B70CB60CFF3E031D0A2F3608B8008A
:102E24003808AF000A128A15E6240A168A113F30C0
:102E3400831203136305E10000306405E2006108B6
:102E4400013EA03E840083130008B400B501340899
:102E5400B500B4016108A03E840000083407B20044
:102E64000030031801303507B300382F08008312EF
:102E7400031323082204210420040319422F432F9F
:102E84008D2FA9010314A90D552F0130A80003109B
:102E9400A00DA10DA20DA30DA80B492F0130A80070
:102EA4002808A907552FA31F582F592F472F5B2FE9
:102EB4005B2F23082702031D692F22082602031D06
:102EC400692F21082502031D692F20082402031CF1
:102ED4006C2F6D2F7C2F2008A4022108031C210FC6
:102EE400A5022208031C220FA6022308031C230F99
:102EF400A7027C2F01300310A30CA20CA10CA00C80
:102F0400FF3E031D7D2F0130A902031D8A2F8B2F45
:102F14005B2F8D2F8D2F2708A3002608A2002508DC
:102F2400A1002408A000962F080000308312031388
:102F3400AE000030AD000030AC000030AB00AF019B
:102F44000A128A15E6240A168A11831603132E0818
:102F540083120313B200B3013208DB003308DC0030
:102F640083160313370883120313B3008316031362
:102F7400360883120313B2000130FF000310B20DB0
:102F8400B30DFF0BC02F5B083207D9005C08031890
:102F94005C0A3307DA000030A0000230A100831677
:102FA4000313320883120313B30083160313310887
:102FB40083120313B2000530FF000310B20DB30DEA
:102FC400FF0BDF2F3208A2003308A3000A128A1570
:102FD400B7210A168A118312031359082007D70050
:102FE4005A0803185A0A2107D800831603132D0818
:0C2FF40083120313B2003208EA00080048
:00000001FF

14 comments :

  1. zip file is not right , it is empty ,could you check for us who is reading and deciding works on your project

    ReplyDelete
  2. Hello Vinod, this project seems pretty cool. However, I'm having a hard time compiling your source code in MPLab with HI-TECH C. I could test your HEX file directly but the other problem I have is that I don't know how you connected your LCD display. I'm using a standard LCD with an HD44780 chipset (the most standard). I currently have it setup to be used in 4-bit mode (D4-D7). In your schematics above, you don't specify which pin is used for LCD R/*W nor how many data bits are used. Can you please provide me with some more details? It would be greatly appreciated. Thanks.

    Ben from Canada

    ReplyDelete
  3. I found your project by googling "wave player using pic". You gave me exactly wg=hat i need for my projec (and it's my first ). But the problem is , When i Try to extract the hex file from the c code using Hi-tech This error shows up:
    Error [141] G:\ukyk.c; 7.21 can't open include file "p16f877a.h": No such file or directory.
    I really don't know what to do .
    Nebras from Tunisia

    ReplyDelete
  4. hi ur hexfile isnt working :(

    please help me

    can u send mplab project file me ?

    ReplyDelete
  5. HI, I don't have the mplap project files. I missed all those. Actually I did this code before learning proper C, it will be reflected in my code.
    Anyway, why you are not trying to compile it using mplab hi tech c compiler?

    Note:
    You can also check out my latest high quality wav player made using atemga32. It can even play wav files upto 160KHz sampling and I did it recently... http://blog.vinu.co.in/2012/02/tv-remote-controller-high-quality.html

    ReplyDelete
  6. sir,
    i am new to microcontroller based projects.
    i am looking forward to do a project as Smart Voltage Stabilizer Using PIC16F877A.
    i wanted to know that how can i burn the program into the pic microcontroller. what are the hardware and software needed for this.

    regards,
    akhil

    ReplyDelete
  7. i use your project in pratique but it is not work. please put us the good program in your site

    ReplyDelete
  8. The code is very interesting and good for learning FAT16 wav player.
    The code will compile on HiTechC v9.83 with only a Warning [356]. Older HiTechC will not compile and have errors.
    However, the code will not work as is due to the fat_init() function seem to have error. Below is the correction I have made and it works on SD card V1 formatted to FAT16 on windows PC.

    void fat_init() //BOOT SECTOR SCANNING//
    {
    load_to_buf(0, 7); //Load MBR into buffer to look for Partition 1 LBA (Boot Sector Entry)
    bse_start = ((buf[0x07] << 8) + buf[0x06]); //Boot Sector Entry
    load_to_buf(bse_start, 0); // Load Boot Sector Entry to buffer
    fat_start = (bse_start + ((buf[0x0f] << 8) + buf[0x0e])); //Compute FAT Table Sector
    dir_start = (bse_start + ((buf[0x0f] << 8) + buf[0x0e]) + (((buf[0x17] << 8) + buf[0x16]) * 2));
    data_start = (dir_start + ((((buf[0x12] << 8) + (buf[0x11])) * 32) / 512)); //DATA Area Start
    sect_per_clst = buf[0x0d];
    }

    another missing information is the configuration bit setting. But my guess is
    __CONFIG(FOSC_HS & PWRTE_ON & WDTE_OFF & BOREN_OFF & LVP_OFF);
    and should work. Hope this helps.

    ReplyDelete
  9. hi vinod.s i try to make simple mp3 ,now i can access sd card and reads sample byte by byte but how can out this sample using pwm ( pwm freq_init,duty cycle)!!!

    ReplyDelete
  10. congratulations on the project

    ReplyDelete
  11. This comment has been removed by the author.

    ReplyDelete
  12. Hi Vinod, i have a question about the code, can i have the timer2 of the pic16f887a running with interrup when the song is playing to make a pair of leds go on and off during the play of the wav file?

    ReplyDelete