An attempt to access a memory card (MMC) using a PIC with limited RAM (PIC16F877A)


PIC16F877A BASED  MMC VOICE RECORDER



                                      Video of my PIC16F877A based MMC digital voice recorder:




This is my first digital voice recorder which is made using a mid range PIC with a total RAM of only 256 bytes. Generally people may say that  we cannot access MMC/SD card using a microcontroller with a RAM < 512. I had seen such posts and comments in many electronics forums, sites etc. But now i could comment  it is also possible to access MMC/SD using a uC with limited RAM but may have much limitations compared to uC with enough RAM.
        Here, i used a PIC16F877A to access an MMC.  MMC is interfaced to PIC16F877A via SPI. I didn't used any file system here. It writes the 8 bit digital data from ADC to the MMC using a multiple block write command. A single block consist of 512 bytes , also called as a sector.

 Similarly it reads the 8bit digital data (digital samples)  using a mutliple block read command. After reading each byte, it is sent to the PWM register to generate PWM signal corresponding to the audio recorded.  Then after passing the PWM signal throuh a low pass filter, the analog  signal could be obtained which is then amplified and introduced to a speaker to reproduce the recorded voice.
       The audio quality was beyond my expectation. The reason for the good audio quality is the high bit rate.. Since i didn't used any file system (FAT etc) I could easily use multiple block read and multiple block write commands to read and write MMC and thus it could achieve the maximum bit rate.

DOWNLOAD THE SOURCE CODE AND CIRCUIT DIAGRAM (ZIP) FROM BELOW:


click here to download the zip file


INTERFACING MMC to PIC:


    MMC is interfaced to PIC via SPI (serial peripheral interfacing). Inbuilt SPI module is available in PIC16F877A. The SPI mode allows 8 bits of data to be synchronously transmitted and received simultaneously. Here, PIC16F877A is SPI master and MMC is SPI slave. To accomplish communication, typically three pins are used:
         • Serial Data Out (SDO) – RC5/SDO
         • Serial Data In (SDI) – RC4/SDI/SDA
         • Serial Clock (SCK) – RC3/SCK/SCL


       MMC works at 3.6 V(max) and PIC16F877A at 5V. So, we need a voltage level convertor for interfacing PIC to MMC. A simple resistor based voltage divider is used to connect CS, CLK and SCK. Now, if a 4.3v (max o/p of PIC) appears across any of the above three pins, then the voltage at corresponding MMC pins will be 2.48v (comes in range of logic high of MMC). 'Data out' of MMC is directly connected to spi 'data in' of PIC. 
MMC COMMAND & RESPONSE


 To initiate an operation on MMC, we need to send corresponding 6byte long MMC command (structure on above figure) which is specific to each operation like single block read, multiple block read, single block write, multiple block write, mmc initialization etc etc etc ...
Now, i think is better to explain the MMC command using command function in program.

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();
    }

The above function is the command function. If we call the command function with 6 byte arguments then it will send the 6 bytes to MMC using spi_write function.
In MMC command, the Most significant byte is the command byte. In the command byte, the 2 'MSB' bits are always 01. The remaining 6 bits are the actual command. So, a CMD0 means this 6 bits will be 000000 and the msb 2 bits will be 01. So, the command byte for CMD0 is 0b01000000. ie in hex, it will be 0x40 and in decimal, it will be 64. Now, comes the 4 argument bytes, which carry some information to be transferred to MMC ie the information such as sector address, block size etc...It depends on the command whether it requires the 4 byte argument or not. If it is not required to certain commands (like CMD0) then 0x00 is send four times ie the fourbyte_arg is zero. Now comes the CRC byte, which is not cared in the SPI mode of MMC. So, we send 0xff as CRC byte. 

Command 0 (CMD0) is called like this :

        command(0,0,0x95);

There are different types of command responses. Now, for getting a response from MMC, 0xff is send and the received data will be the response. For some commands, we need to wait until the correct response is received, by continuously checking for the response. 
There are commands for reading, writing etc. Every data read or data write operation is completed by reading or writing of a total of 512 bytes of data. A sector is 512 bytes.(default block size). We cannot terminate the read or write operation in the midway with in a block. 

MMC INITIALIZATION:

      When an MMC is powered ON, we need to initialize the MMC and bring it to SPI  mode . This requires a series of commands (will be there in MMC spec) and need to check the response (as per the spec) whether it is correct or not for the particular command. 

     Actually initialization was the main problem which i faced at the beginning. It took 3 days for me to successfully initialize an MMC card. I used hyperterminal in PC for checking the response of each command. I feel it is the best testing method. Later i used a 16x2 LCD. (check mmc_init() in my program below.)

DATA TRANSFER:
-------------------------------------------------------------------------------------------------------------------------------




 Timing diagram of CMD1, single block read and write:












----------------------------------------------------------------------------------------------------------



 ---------------------------------------------------------------------------------------------------------
Single Block Read:
                             
       The argument specifies the location to start to read in unit of byte or block. The sector address specified by upper layer must be scaled properly. When a CMD17 is accepted, a read operation is initiated and the read data block will be sent to the host. After a valid data token (FEh) is detected, the host controller receives following data field and two byte CRC. The CRC bytes must be flushed even if it is not needed. If any error occured during the read operation, an error token will be returned instead of data packet.

Multiple Block Read:
        The Multiple Block Read command reads multiple blocks in sequence from the specified address. When number of transfer blocks has not been specified before this command, the transaction will be initiated as an open-ended multiple block read, the read operation will continue until stopped with a CMD12. The received byte immediately following CMD12 is a stuff byte, it should be discarded before receiving the response of the CMD12. Before every data packet, a data token (FEh) is sent by the card. If the data token is not received, then it waits for the token.

Single Block Write:
         When a write command is accepted, the host controller sends a data packet to the card after a byte space. The packet format is same as Block Read command. The CRC field can have any invalid value unless the CRC function is enabled. When a data packet has been sent, the card responds a Data Response immediately following the data packet. The data response trails a busy flag to process the write operation. Most cards cannot change write block size and it is fixed to 512 bytes. Before every data packets a data token is written so that the MMC/SD could confirm that the next 512 bytes received after the write token (FEh) is the data block to be stored in the SD/MMC.
In principle of the SPI mode, the CS signal must be asserted during a transaction, however there is an exception to this rule. When the card is busy, the host controller can de assert CS to release SPI bus for any other SPI devices. The card will drive DO signal low again when reselect it during internal process is in progress. Therefore a preceding busy check (wait ready immediately before command and data packet) instead of post wait can eliminate waste wait time. In addition the internal process is initiated a byte after the data response, this means eight clocks are required to initiate internal write operation. The state of CS signal during the eight clocks is negligible so that it can done by bus release process described below.

Multiple Block Write:
      The Multiple Block Read command writes multiple blocks in sequence from the specified address. When number of transfer blocks has not been specified prior to this command, the transaction will be initiated as an open-ended multiple block write, the write operation will continue until it is terminated with a Stop Tran token(FDh). The busy flag will appear on the DO line a byte after the Stop Tran token. As for SDC, the multiple block write transaction must be terminated with a Stop Tran token independent of the transfer type, pre-defined or open-ended.

AUDIO OUT:
     Here, I used inbuilt PWM module of the PIC as a DAC. PWM is really a good and cheap solution for DAC. Here, if i put an 8 bit data to CCPR2L register of PIC, it will generate PWM signal corresponding to that data. If i stream the voice data to CCPR2L with a speed according to the specified bitrate then a Pulse Width Modulated signal corresponding to the voice is generated which could be easily converted to analog signal by using a low pass filter. This could be amplified and introduced to  a speaker to reproduce the voice.
 PWM out could be obtained from RC1/CCP2 pin of PIC16F877A.


ADC:
        ADC in PIC is used to convert the analog audio signal from a condenser mic pre-amp. PIC16F877A have inbuilt 10 bit ADC module. I used only the 8 LS bits to store in the MMC. RA0 of PIC16F877A is used configured as ADC input channel where the mic preamp is connected.

CIRCUIT DIAGRAM:



PROGRAM:


/*
------------------------------------------------------------------------------------
PIC16F877A + MMC voice recored (no file system)
------------------------------------------------------------------------------------
COMPILER: HI-TECH C , TARGET uC PIC16F877A
------------------------------------------------------------------------------------
by Vinod.S <vinodstanur@gmail.com>
------------------------------------------------------------------------------------
*/
#include<pic.h>
#define _XTAL_FREQ 20e6
__CONFIG(0x3F3A);
#define CS RC2
#define RS RB2
#define EN RB1
#define fst cmd(0x80)
#define snd cmd(0xc0)
unsigned char readdata, u;
unsigned int count;
unsigned long int arg = 0;
/*-----------------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)
{
    clear();
    while (*q) {
        data(*q++);
    }
}

void istring(unsigned int q)
{
    cmd(0x81);
    data(48 + (q / 100));
    q %= 100;
    data(48 + (q / 10));
    q %= 10;
    data(48 + (q));
    __delay_ms(500);
}

/*-----------------------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 = 0x50;
    CCPR2L = 0x17;
    TMR2ON = 1;
    CCP2CON = 0b00001100;
}

void pwm_disable()
{
    CCP2CON = 0b00000000;
}

void pwm_enable()
{
    CCP2CON = 0b00001100;
}

/*--------------------PWM END-------------------------*/
/*-------------------MMC BEGIN-----------------------*/
void spi_init()
{
    TRISC4 = 1;
    RC2 = 1;
    RC3 = 0;
    RC5 = 0;
    TRISC2 = TRISC3 = TRISC5 = 0;
    SSPCON = 0b00100010;
    SSPEN = 1;
    SMP = 1;
    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(1000);
    SSPCON = SSPCON & 0b11111101;
}

void write()
{
    pwm_disable();
    command(25, arg, 0xff);
    while (readdata != 0) {
        spi_read();
        string("WRITE ERROR");
    }
    string("WRITING MMC");
    while (1) {
        spi_write(0xff);
        spi_write(0xff);
        spi_write(0b11111100);
        for (int g = 0; g < 512; g++) {
            GO = 1;
            while (GO);
            spi_write(ADRESL);
            PORTD = ~ADRESL;
        }
        spi_write(0xff);
        spi_write(0xff);
        spi_read();
        while ((readdata & 0b00011111) != 0x05) {
            spi_read();
        }
        while (readdata != 0xff) {
            spi_read();
        }
        if (RE0 == 1) {
            spi_write(0xff);
            spi_write(0xff);
            spi_write(0b11111101);    //stop token
            spi_read();
            spi_read();
            while (readdata != 0xff) {
                spi_read();
            }
            break;
        }
    }
}

void read()
{
    pwm_enable();
    command(18, (arg), 0xff);
    while (readdata != 0) {
        spi_read();
        string("READ ERROR");
    }
    string("READING MMC");
    while (1) {
        while (readdata != 0xfe) {
            spi_read();
        }
        for (int g = 0; g < 512; g++) {
            spi_read();
            __delay_us(16.5);
            CCPR2L = readdata;
            PORTD = ~readdata;
        }
        spi_write(0xff);
        spi_write(0xff);
        if (RE0 == 1) {
            command(12, arg, 0xff);
            spi_read();
            while (readdata != 0) {
                spi_read();
            }
            while (readdata != 0xff) {
                spi_read();
            }
            break;
        }
    }
}

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

/*-------------------main function-------------------*/
main()
{
    CS = 1;
    PORTD = 0;
    TRISC4 = 0;
    TRISC5 = 0;
    TRISD = 0;
    TRISB2 = 0;
    TRISB1 = 0;
    TRISE0 = 1;
    lcd_init();
    adc_init();
    usrt_init();
    spi_init();
    mmc_init();
    pwm_init();
    lcd_init();
    count = 0;
    CS = 0;
    arg = 0;
    while (1) {
        arg = 0;
        fst;
        pwm_enable();
        string("READ MODE");
        __delay_ms(1000);
        read();
        arg = 0;
        fst;
        pwm_disable();
        string("WRITE MODE");
        __delay_ms(1000);
        write();
    }
}
 






HERE IS THE SCREENSHOT OF THE BUILD and HEX FILE....:-)

 



:100000000A128A11C42A00308A000408840A82076E
:10001000003443344134523444342034453452346F
:1000200052344F3452342D3443344D34443430340C
:100030002034003443344134523444342034453481
:10004000523452344F3452342D3443344D344434CA
:100050003134203400344D344D3443342034493469
:100060004E3449345434493441344C3449345A348C
:10007000453444342134003443344134523444341C
:1000800020344534523452344F3452342D344334B6
:100090004D3444343134363400344234593420340D
:1000A0002D342034563449344E344F344434533490
:1000B000543441344E34553452340034523445347F
:1000C0004134443449344E34473420344D344D3473
:1000D00043340034573452344934543449344E3460
:1000E000473420344D344D34433400345734523483
:1000F00049345434453420344534523452344F3426
:100100005234003457345234493454344534203452
:100110004D344F3444344534003452344534413442
:10012000443420344534523452344F345234003441
:10013000523445344134443420344D344F34443403
:04014000453400340E
:10054E00831203139D0108000C30831203139D00C8
:10055E000800831203138614B42A83120313861021
:10056E0008008316031305148130831203139F00B2
:10057E008E30831603139F000800A001A101A20173
:10058E00A301A401A501A601A70183010A128A11E4
:10059E00902C83160313071326309800D030831245
:1005AE00031398000A308316031399000800F00015
:1005BE007008831203139300E42A83160313141C8A
:1005CE00E92AEA2AE42AEB2A080001300A128A11E3
:1005DE0060230A128A110D30F300FB30F200F20B89
:1005EE00F62AF30BF62AFB2A08008316031387104C
:1005FE0083120313921012105030831603139200BD
:10060E001730831203139B0012150C309D00080047
:10061E00FF30831203139300142B83160313141C41
:10062E00192B1A2B142B1B2B831203131308F000F8
:10063E007008A6000800831603130716831203130F
:10064E000715871187128316031387128711071157
:10065E0022308312031394009416831603139417F7
:10066E0014178312031314120800F10083120313DC
:10067E0006154230F000F00B422B64007108F000BA
:10068E0004300310F00CFF3E031D482B700883123C
:10069E00031388000A128A11B0220A128A117108F5
:1006AE008312031388000A128A11B0220A128A11C9
:1006BE000800F1008312031306114230F000F00B14
:1006CE00662B64007108F00004300310F00CFF3E3E
:1006DE00031D6C2B70088312031388000A128A11F3
:1006EE00B0220A128A1171088312031388000A12AB
:1006FE008A11B0220A128A110800F300C0300A12C1
:10070E008A1160230A128A119D2B730884000A1223
:10071E008A1103200A128A110A128A113C230A1224
:10072E008A110130F2007208F3079D2B73088400C2
:10073E000A128A1103200A128A110038031DA82BEF
:10074E00A92B8C2BAA2B0800F5000A128A11EC2279
:10075E000A128A11C32B750884000A128A1103200B
:10076E000A128A110A128A113C230A128A110130C6
:10077E00F4007408F507C32B750884000A128A1159
:10078E0003200A128A110038031DCE2BCF2BB22B59
:10079E00D02B45300A128A1184230A128A110800BE
:1007AE008230F500DD30F400F40BDB2BF50BDB2B88
:1007BE00E02B30300A128A1160230A128A11073098
:1007CE00F5007D30F400F40BEA2BF50BEA2B3030FC
:1007DE000A128A1160230A128A110730F5007D3041
:1007EE00F400F40BF82BF50BF82B30300A128A11AB
:1007FE0060230A128A1128300A128A1160230A1203
:10080E008A1128300A128A1160230A128A1128309E
:10081E000A128A1160230A128A110C300A128A11E6
:10082E0060230A128A110A128A11EC220A128A1104
:10083E000A128A11EC220A128A1106300A128A1141
:10084E0060230A128A110800FA00FF300A128A1178
:10085E00DE220A128A117A0840380A128A11DE2222
:10086E000A128A117108F6007208F7007308F80070
:10087E007408F90018300310F90CF80CF70CF60C8C
:10088E00FF3E031D422C76080A128A11DE220A123E
:10089E008A117108F6007208F7007308F8007408E0
:1008AE00F90010300310F90CF80CF70CF60CFF3EA3
:1008BE00031D592C76080A128A11DE220A128A1199
:1008CE007108F6007208F7007308F8007408F90052
:1008DE0008300310F90CF80CF70CF60CFF3E031D54
:1008EE00702C76080A128A11DE220A128A117108F9
:1008FE000A128A11DE220A128A1175080A128A1148
:10090E00DE220A128A110A128A110F230A128A1182
:10091E0008008312031307158801831603130712A9
:10092E00871288010611861009140A128A11D7231C
:10093E000A128A110A128A11B8220A128A110A128E
:10094E008A11D0220A128A110A128A1122230A123D
:10095E008A110A128A11DB260A128A110A128A11C8
:10096E00FC220A128A110A128A11D7230A128A113C
:10097E0083120313A401A50107110030A300003058
:10098E00A2000030A1000030A000CD2C0030831258
:10099E000313A3000030A2000030A1000030A0001D
:1009AE0080300A128A1160230A128A110A128A11E1
:1009BE00AB220A128A1190300A128A11AB230A1244
:1009CE008A111A3083120313AA004530A9007E3013
:1009DE00A800A80BF02CA90BF02CAA0BF02C0A12D5
:1009EE008A112E250A128A11003083120313A300D6
:1009FE000030A2000030A1000030A00080300A12AA
:100A0E008A1160230A128A110A128A11A7220A1267
:100A1E008A117A300A128A11AB230A128A111A30FD
:100A2E0083120313AA004530A9007E30A800A80B3C
:100A3E001E2DA90B1E2DAA0B1E2D0A128A11F3258F
:100A4E000A128A11CD2CCD2C0A128A1100280A12F4
:100A5E008A11AB220A128A11831203132308F4009F
:100A6E002208F3002108F2002008F100FF30FB00FD
:100A7E007B08F50012300A128A112B240A128A11F1
:100A8E00542D0A128A110F230A128A1185300A1266
:100A9E008A11AB230A128A11542D83120313A6084E
:100AAE00031D5A2D5B2D482D5C2D56300A128A11CE
:100ABE00AB230A128A116A2D6A2D0A128A110F238C
:100ACE000A128A116A2D831203132608FE3A031D99
:100ADE00712D722D642D732DFC01FD017D08803A60
:100AEE00FF0082307F02031D7E2D00307C02031C2E
:100AFE00812D822D842DA72DA72D0A128A110F2349
:100B0E000A128A111B30FB00FB0B8B2D8312031371
:100B1E0026089B00260988000130FC070318FD0AF1
:100B2E000030FD077D08803AFF0082307F02031DF2
:100B3E00A22D00307C02031CA52DA62D842DA72DE1
:100B4E00FF300A128A11DE220A128A11FF300A12AF
:100B5E008A11DE220A128A1183120313091CB82D80
:100B6E00B92D6A2D2308F4002208F3002108F200A3
:100B7E002008F100FF30FB007B08F5000C300A1254
:100B8E008A112B240A128A110A128A110F230A12B1
:100B9E008A11D72D0A128A110F230A128A11D72D04
:100BAE0083120313A608031DDD2DDE2DD12DE62D98
:100BBE00E62D0A128A110F230A128A11E62D8312CC
:100BCE0003132608FF3A031DED2DEE2DE02DF22D19
:100BDE00F22D6A2D6A2D08000A128A11A7220A1216
:100BEE008A11831203132308F4002208F30021084C
:100BFE00F2002008F100FF30FB007B08F5001930F1
:100C0E000A128A112B240A128A11192E0A128A111B
:100C1E000F230A128A116E300A128A11AB230A129E
:100C2E008A11192E83120313A608031D1F2E202EC0
:100C3E000D2E212E62300A128A11AB230A128A114E
:100C4E00282EFF300A128A11DE220A128A11FF3074
:100C5E000A128A11DE220A128A11FC300A128A1135
:100C6E00DE220A128A11FC01FD017D08803AFF0086
:100C7E0082307F02031D452E00307C02031C482E5D
:100C8E00492E4B2E762E762E831203131F154F2EC2
:100C9E001F19522E532E4F2E542E831603131E0839
:100CAE000A128A11DE220A128A11831603131E09F2
:100CBE008312031388000130FC070318FD0A00306D
:100CCE00FD077D08803AFF0082307F02031D712EE2
:100CDE0000307C02031C742E752E4B2E762EFF30A8
:100CEE000A128A11DE220A128A11FF300A128A11A2
:100CFE00DE220A128A110A128A110F230A128A118F
:100D0E008E2E0A128A110F230A128A118E2E831228
:100D1E00031326081F39053A031D962E972E882E8B
:100D2E009F2E9F2E0A128A110F230A128A119F2EAE
:100D3E00831203132608FF3A031DA62EA72E992E03
:100D4E00091CAA2EAB2E282EFF300A128A11DE2283
:100D5E000A128A11FF300A128A11DE220A128A1131
:100D6E00FD300A128A11DE220A128A110A128A1123
:100D7E000F230A128A110A128A110F230A128A11DC
:100D8E00CE2E0A128A110F230A128A11CE2E831228
:100D9E0003132608FF3A031DD52ED62EC82EDA2EA3
:100DAE00DA2E282E282E0800831203130715A7010A
:100DBE0032302702031CE42EE52EE72EF92EF92EF3
:100DCE00FF300A128A11DE220A128A110130FB004C
:100DDE007B0883120313A70732302702031CF82E59
:100DEE00F92EE72E07110730FC007D30FB00FB0BC0
:100DFE00FE2EFC0BFE2E0030F4000030F30000300F
:100E0E00F2000030F1009530FB007B08F500003059
:100E1E000A128A112B240A128A1183120313A401B7
:100E2E00A501272F0A128A110F230A128A110130E7
:100E3E0083120313A4070318A50A0030A507272F52
:100E4E002608013A03192C2F2D2F382F0330250297
:100E5E00E83003192402031C352F362F192F382F93
:100E6E00382F03302502E83003192402031C402FCB
:100E7E00412F4A2F01300A128A11AB230A128A110E
:100E8E00482F482F4A2F0030F4000030F300003076
:100E9E00F2000030F100FF30FB007B08F50001305E
:100EAE000A128A112B240A128A1183120313A40127
:100EBE00A501812F0030F4000030F3000030F20065
:100ECE000030F100FF30FB007B08F50001300A1204
:100EDE008A112B240A128A110A128A110F230A125E
:100EEE008A11013083120313A4070318A50A0030D8
:100EFE00A507812F2608031D852F902F033025026D
:100F0E00E83003192402031C8D2F8E2F612F902F92
:100F1E00902F03302502E83003192402031C982F6A
:100F2E00992FA22F12300A128A11AB230A128A119C
:100F3E00A02FA02FA22F0030F4000030F3000230BB
:100F4E00F2000030F100FF30FB007B08F50010309E
:100F5E000A128A112B240A128A1183120313A40176
:100F6E00A501C72F0A128A110F230A128A11013006
:100F7E0083120313A4070318A50A0030A507C72F71
:100F8E002608031DCB2FD62F03302502E830031978
:100F9E002402031CD32FD42FB92FD62FD62F0330D4
:100FAE002502E83003192402031CDE2FDF2FE82F61
:100FBE0034300A128A11AB230A128A11E62FE62F59
:100FCE00E82F23300A128A11AB230A128A111A3023
:100FDE00FD004530FC007E30FB00FB0BF42FFC0BBC
:100FEE00F42FFD0BF42F831203131408FD39940014
:020FFE000800E9
:02400E003A3F37
:00000001FF

72 comments :

  1. Thanks for sharing friend.. You very good.. I dont understand at all.. hehe but I will try to understand soon...

    superb!!

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

    ReplyDelete
  3. Nice and good project... Congrats..

    ReplyDelete
  4. Best ,its can understand easly,
    nice project,Thanks for sharing

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

    ReplyDelete
  6. Please hex:(?
    up :(
    up :(
    up :(
    up :(

    ReplyDelete
  7. Okay Mr Sharkds, the hex file is ready for U..
    If any trouble, just post it here...:-)

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

    ReplyDelete
  9. hi I'm from Brazil I'm studying electronic still do not know programming in c only in asm.
    I found your project very well and I am studying ele.muito thanks for sharing:):):) ...
    (google translator)

    ReplyDelete
  10. Hi Vinod, this is superb!! I saw the youtube video also for your recorder. I arrived here looking for some help in 8051+microSD card interfacing without file system. I am experiencing great problems in initialising the card.
    Can you please guide me with some sample code or otherwise. rajeshbij@gmail.com Jaipur 0 9413382222.
    Thanks

    ReplyDelete
  11. @ Jigyasu Computronix :
    Try my initialization function in above source code - void mmc_init()

    ReplyDelete
  12. Hi I'm Luther Strike (www.lutherstrike.com).I like your post.i understand how mmc stores data from pic..please post another codes for mmc data logging using csv files..

    ReplyDelete
  13. dude can u just show ckt diagram of how u made mmc card holder into mmc IC with pins.
    plz ....

    ReplyDelete
  14. dude can u plz give c code for 8051.
    waitin for your reply.
    plzz.....

    ReplyDelete
  15. just have an image search for "mmc pinout" @nitin.

    I am really sorry :-), I didn;t wrote any any code for 8051.

    ReplyDelete
  16. Hi Vinod, this is a great, innovative and amazing piece, I commend you immensely.

    I am endeavoring to replicate using the PIC16F88 (18 Pin) but I am having some difficulties which I was hoping you may aid me with (My head has been hurting for way too long – I am in desperate need of assistance)

    Firstly, my code appears to enter an infinite loop in mmc_init at
    while ((readdata & 0b00011111) != 0x05)

    from reading your notes initializing the mmc was a problem you also experienced. Can you provide any recommendations here or explain a little more on what this while loop is trying to detect?

    Secondly are you aware of any ‘road blocks’ with the 16F88 or see any issues here that may inhibit such conversion.

    Thirdly, are you able to comment or breakdown the fuses your config word has specified for the 16F877A?

    Using the 16F88 I have
    A) re-allocated pins based on the different layout
    B) swapped register CCP2ON to CCP1ON
    C) removed the USRT and LCD routines in exchange for a simple flashing LED function
    D) altered config word from __CONFIG(0x3F3A) to __CONFIG(0x3F2A) = 1. HS Oscillator 2. WDT Disabled 3. PWRT disabled 4. RA5 is MCLR 5. BOR disabled 6. LVP disabled 7. CPD off 8.Write protection off 9.CCP1 on RB0 10.CP off
    E) Compiled code for 16F88 is on Hi-Tech Compiler V9.83

    I very much appreciative any help you might be able to share.

    ReplyDelete
  17. SD card will not work with my initialization function. It need a few modifications. Any way, SD will show successfull initialization if we try to do it with MMC initialization function. But it is not initialized in real! That is why you got stuck inside the
    while ((readdata & 0b00011111) != 0x05) loop...
    So either try it with MMC card (for example, those seen on nokia 6600, N70, N72, 6230i etc etc) or read the SD card specs and try to mode the code of initialization to adapt it for SD also...
    I am little busy nowadaya so that I couldn't experiment on these stuff :(....When I get enough time, I will include the SD initialization with in the MMC_init function in my code....

    ReplyDelete
  18. SIR I NEED HELP IN MAKING PROJECT FOR READING MMC THROUGH PIC18F4520 AND DISPLAY IT ON 16X2 LCD PLEASE REPLY

    ReplyDelete
  19. is anybody get the zip file ?

    ReplyDelete
  20. Hi,

    If I modify the codes above and writing the data into the SD card, is it possible to read the data stored in the SD card using PC? Or I have to create a txt.file to store the data into SD card so that I can read the data using PC?

    Hope to hear for you guys. I need it badly.Thanks

    ReplyDelete
  21. Actually the above code doesn't checks for any file system in the MMC. It just start its work from the first sector to the last....

    If you need to read the recorded data using a PC, then the MMC should have a proper file system and the data is to be recorded as a file which have atleast its file name, attribute and cluster starting address to be stored in the root directory or any directory... Also, the successive cluster address of the file should be stored in the linked list called FAT (in case of FAT file system). Then you can read the data as a file using PC..

    But there will be some 'ugly' ways to read the data using PC ie using hex editors etc, but any way, those are not proper way to read a file...

    Note:
    NEVER USE ANY MMC card which have some important files, because my voice recorder doesn't care it and it will start recording from the BOOT RECORD sector and thus every thing will be WASHED OUTTT.....:-)

    ReplyDelete
    Replies
    1. You have the better option so that you also share it

      Delete
  22. Hi Sir,

    Thanks for the reply. I appreciate it. =)

    Btw, can you give me some guides or websites on how to create a txt.file and write data into a sd card? I am lost as I found most of the sample codes and commands for SD card are for PIC18F.

    ps: I am using PIC16F877A. Hope to hear from you soon. Thanks. =)

    ReplyDelete
  23. did you checked my blogpost on "MMC WAV PLAYER " ? There I implemented reading wav file from a FAT16 filesystem. If you understood the reading process, then you can easily guess how to write to a file.. The code may be ugly to see, because I did all those before learning proper C language... I mean before reading the k&r - the bible of C programming...
    Any way, try to use PIC18F or AVR for accessing MMC/SD,,.,That will be much easier since you can use fat libraries like petits FAT etc....
    Also if you want, you can also check the source code of the above mentioned FAT library........

    ReplyDelete
  24. Hello Vinod,
    Is a very interesting design, and I would like to use it for my scool project, but with an pic18f4620. What you sugest I have to change?
    Thanks.
    Jeny

    ReplyDelete
  25. To make this project, no need of a pic18f4620.
    But if you want to record the sound to a filesystem, ie for eg: an MMC with FAT16 or 32, then it is better to go for pic18f or AVR...

    ReplyDelete
  26. thanks brother, simple and clear very amazing documenting :)

    ReplyDelete
  27. dear Mr.vinod

    i tried to make a prototype of this Electronic circuit by connecting the input direct to the speaker amplifying signal using PIC18F452, but i faced a problem in the quality of the voice and tried to make a feedback and it works but not as better as i want

    so here is my question: who can i enhance the quality of the voice ??

    thanks in advance :)

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

    ReplyDelete
  29. PIC16F877A can work at 3.3v disabling Watchdog Timer and Brown-out Reset and You can save 6 resistor

    ReplyDelete
  30. that's a good information... thanks...

    ReplyDelete
  31. hi my name is shabeeb
    i know you from pramods sir
    nice job, your blog is very useful for beginners like me
    i am from pookayil

    ReplyDelete
  32. hi vinod,

    thnax for al the tutorials, can you please make a tutorial on gprs modem, i had done gsm modem interfacing, but i am trying to use a gprs, but i cant get so much information on net...Hope this for the next tutorial...

    thanx again a lot...

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

    ReplyDelete
  34. i could not open the zip file

    ReplyDelete
  35. hi vinod. i seen ur resume ur great ECE student iam also ECE final year

    friend i want to make usb to usb data transfer or like ur project MMC to MMC transfer without using any computer please help me im doing lot of hard work but i didnt get sucess.
    my problem is how to write code to read r write from pendrive what exact hardware required
    one point i want just transfer at any speed, without file system, and without display
    i hope u will help me!
    im waiting 4 reply
    thanks in advance...

    ReplyDelete
  36. hey vinod can you help me a little?
    I am sure you also have used atmega avr series mcu like atmega8. Can you please load a code (especially for the MMC part) for atmega8. I think many people like me are waiting for that. Its a very humble request to you plese.

    ReplyDelete
  37. I have already done SD card projects on AVR...
    U can check my blog posts.......

    ReplyDelete
  38. hey vinod
    I have not used PIC microcontroller but only AVR. I have successfully made a project on interfacing a micro SD card with atmega16. I want to play a wav or mp3 file with that. Also i want to make a sound recorder type of thing which can played back. This post is based on PIC so i can't understand most of the things. Please tell me after recording a sound as adc values. What modification i have to do with PWM. How would the frequency and duty cycle would depend on ADC values. Also the amplifier circuit with condenser mic which you have posted can not amplify the sound to a significant level. The ADC value can only go up to 80 in 10 bit ADC mode where it can go up to 1023. So changes i need to make in the circuit.
    Finally please give me some link of how can we read a wav file and can implement it with my micro SD with atmega16 project. Please give me something from scratch.

    ReplyDelete
  39. hi,
    i am doing a project where i record my voice and then controlled wheelchair with my voice...i used ur code...and simulate in proteus..but i think there happened some problem and i can't see or listen the output....can u help me...plzzz

    ReplyDelete
  40. Really an amazing post.It has helped me and my friends in many ways.

    Thanks,

    http://pccardsdirect.com/

    ReplyDelete
  41. i aam finding it difficult to compile the code.. cade you put me through? better still, can i ve the hex file while we resolve the compiling issue. i am anxious to seethe project work.

    ReplyDelete
  42. i got these error while compiling the code:


    (1273) Omniscient Code Generation not available in Lite mode (warning)
    Error [500] ; 0. undefined symbols:
    _cmd(test.obj) _lcd_init(test.obj) _string(test.obj) _usrt_init(test.obj)

    ReplyDelete
  43. wonderul...u r really a "DOERS"...thnx alot dear frnd...
    i hav been searching for a project like this,....

    ReplyDelete
  44. Great Project Bro ;)

    Me too I have a PIC16F877a-Based Project, in wich I need to play an effect (5 seconds wav file, I mean without a memory card...), but it was really hard on me :(

    I suppose I should convert the Wav file to Hex or Bin and play it manually through the main program. Unfortunatly I can't find a way to do it!!!

    So Plz, any help would be greatly appreciated ;)

    ReplyDelete
  45. Jamel

    http://www.ikein.net/index.php/electronica/tutoriales/62-pwmingles

    I think you can make use of the MATLAB function in this page

    ReplyDelete
  46. Vinod.S

    Hi, I want you to refer me to the kind of audio amplifier to be used with this circuit

    because i can't imagine how the +ve only o/p of the Filter will be turned into +ve/-ve that drives the speaker

    thanks in advance

    ReplyDelete
  47. Use any standard audio amplifier... I suggest the UTC820 (8 pin audio amp IC) based amplifier... Also connect a 1uF caps in between to remove DC... I am not drawing caps here because I am assuming some caps will be there in an amplifier......

    ReplyDelete
  48. hi all may i connect TFT screen in stead of Glcd ???

    ReplyDelete
  49. Thanks for sharing this. I really do appriciate this. Thanks for this.

    Thanks,
    Apple service center in Delhi

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

    ReplyDelete
  51. Hi
    I downloaded the zip file but I cant extract it.
    It says that the file isnt valid.
    Please Help

    ReplyDelete
  52. Hi,

    Thank you for sharing. such a good project. I have some problems on downloading the zip file. Could you please check it.

    Thanks

    ReplyDelete
  53. The article SIP recording software make sure of the best call logging facelifts which can help you to overcome and deal with the digital call logger common problems that will help every individual to overcome that use of call tracking. This can be done once you are digital voice logger confident and using that ranges of items that panasonic call recording are available in the market.

    ReplyDelete
  54. The article SIP recording software make sure of the best call logging facelifts which can help you to overcome and deal with the digital call logger common problems that will help every individual to overcome that use of call tracking. This can be done once you are digital voice logger confident and using that ranges of items that panasonic call recording are available in the market.

    ReplyDelete
  55. Good day Sir!
    Nice project!
    Can you send me the full details of this project and the zip files.
    I needed badly.
    Thank you very much.

    this is my gmail account.

    skyweak0024@gmail.com

    ReplyDelete
  56. hi thanks for share.
    cau u help me? ı created circuit with printed circuit. ı can't run:S Can you send me the full details of this project and the zip files.contact me : huseyin035harran@gmail.com
    I bought the circuit

    ReplyDelete
  57. Very good! The program and data space used is quite small compared to what the circuit is meant to do. Does the Proteus MMC respond only to CMD1 for initialization? i've been using ACMD41, but it's not working? I cant even get CMD0 to work. All it returns is 0x00...

    ReplyDelete
  58. Sir,zip file is not available overhere.Please provide the zip file.I need to make this project and thats very important to me.

    ReplyDelete
  59. Hello,
    just wondering:
    in void mmc_init()
    you send only 50 dummy commands to init mmc.
    but the mmc specification says it has to be precisely 74 dummy ones.
    Does it still work with 50 pulses?

    ReplyDelete
    Replies
    1. I was wondering about the same thing,if you got the answer please reply to my comment.Thank you in advance

      Delete
  60. Hello
    Can we measure a negative voltage from analog input using pic ?
    Please be kind enough to answer.

    ReplyDelete
  61. Ok i had just come up with that.

    Another doubt


    do we have to make any changes to configuration bits?

    ReplyDelete
  62. i have got config error what did i do

    ReplyDelete
  63. My Weather Measuring Instruments & station I-pad is modified with micro weather stations which I use in finding clues about criminals. A powerful and fast GPS is also placed inside it. So it's very advantageous for my job.

    ReplyDelete
  64. Hi...!!!
    Very Good information on this blog can you help me where is Buy 16GB Memory Card

    ReplyDelete
  65. Hi...!!!

    Nice information on this blog. This winter buy Latest mobile price list on comparemunafa with lowest price and earn extra double munafa points like (cashbacka)

    ReplyDelete
  66. ow about if i use sd card with adapter

    ReplyDelete
  67. Nice to see a non-Arduino project. :-) Thanks a lot for sharing this awesome post dude! :-)

    ReplyDelete