PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   Giao tiếp USB, CAN, I2C, SPI, USART... (http://www.picvietnam.com/forum/forumdisplay.php?f=45)
-   -   Giao tiếp card MMC ? (http://www.picvietnam.com/forum/showthread.php?t=1212)

doianhve 22-06-2007 09:46 AM

Giao tiếp card MMC ?
 
Xin chào các cao thủ.Tôi đang nghiên cứu giao tiếp card MMC thông qua chuẩn truyền SPI mà thấy khó ghê.Ai có tài liệu hay kinh nghiệm gì share tôi với.Thanks.

falleaf 22-06-2007 11:40 AM

Card đó tên tuổi là gì? SPI thì cơ bản phải xem nó mắc dây như thế nào, và nó cho phép chuẩn như thế nào. Còn mọi thứ thì oki thôi, nên phải có cái datasheet về cái card thì mới biết được.

Chúc vui

doianhve 22-06-2007 12:45 PM

Xin chào mội người.Tôi dùng thẻ MMC64MB của Samung.Giao Tiếp SPI.Data Sheet thi tìm trên mạng .Nhiều lắm.

doianhve 22-06-2007 12:59 PM

code tham khảo
 
Để cho việc thảo luận sôi nổi tôi xin đưa ra kết quả sơ bộ cho mọ người tham khảo.Đây là mã code tôi dùng để xử lý Card.Xin nói qua là code dùng một phần thư viện có sẵn LCD.c của CCS để kiểm tra dữ liệu.Tôi dùng Proteus nhưng chưa mô phỏng được.bạn cần mạch thật.
Cần chú ý:
+LCD sử dụng bit:
// D0 enable
// D1 rs
// D2 rw
// D4 D4
// D5 D5
// D6 D6
// D7 D7
+MMC nối dúng chuẩn SPI có sẵn trên PIC và chon Pin_C2 làm chân CE
Mọi nguoi Down ve và cho ý kiến nhé.Tôi dùng code của Microchip và đã sửa lỗi chạy thử.

doianhve 22-06-2007 01:00 PM

-----file chinh-----------
Code:

#include <E:\Read_Card\16F877.h> // da doi thu tu PortD de phu hop mach in
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_A3, rcv=PIN_A2)  // Jumpers: 11 to 17, 12 to 18
#include <E:\Read_Card\lcd_driver.c>
#include <E:\Read_Card\spi.c>
void main() {
  int Kiem_Tra;
  kiem_tra=1;
  lcd_init();
  //setup_spi(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_16);
  //F la khoi xoa man hinh va ghi tu dong 1
  //n la xuong dong
  while(true)
  {
      kiem_tra=mmc_init();
      lcd_putc("\fChan doi qua 456\n");
      if (!kiem_tra)
      {
            lcd_putc("Wait...\n");
            mmc_write_block(100);
            mmc_read_block(100);
      }

      delay_ms(2000);
  }

}


doianhve 22-06-2007 01:01 PM

Code:

-----------------------lcd_driver.c---------------

// As defined in the following structure the pin connection is as follows:
//    D0  enable
//    D1  rs
//    D2  rw
//    D4  D4
//    D5  D5
//    D6  D6
//    D7  D7
//
//  LCD pins D0-D3 are not used and PIC D3 is not used.

// Un-comment the following define to use port B
// #define use_portb_lcd TRUE
struct lcd_pin_map {                // This structure is overlayed
          BOOLEAN enable;          // on to an I/O port to gain
          BOOLEAN rs;              // access to the LCD pins.
          BOOLEAN rw;              // The bits are allocated from
          BOOLEAN unused;          // low order up.  ENABLE will
          int    data : 4;        // be pin B0.
        } lcd;


#if defined(__PCH__)
#if defined use_portb_lcd
  #byte lcd = 0xF81                  // This puts the entire structure
#else
  #byte lcd = 0xF83                  // This puts the entire structure
#endif
#else
#if defined use_portb_lcd
  #byte lcd = 6                  // on to port B (at address 6)
#else
  #byte lcd = 8                // on to port D (at address 8)
#endif
#endif

#if defined use_portb_lcd
  #define set_tris_lcd(x) set_tris_b(x)
#else
  #define set_tris_lcd(x) set_tris_d(x)
#endif


#define lcd_type 2          // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40    // LCD RAM address for the second line


BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
                            // These bytes need to be sent to the LCD
                            // to start it up.


                            // The following are used for setting
                            // the I/O port direction register.

struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in



BYTE lcd_read_byte() {
      BYTE low,high;
      set_tris_lcd(LCD_READ);
      lcd.rw = 1;
      delay_cycles(1);
      lcd.enable = 1;
      delay_cycles(1);
      high = lcd.data;
      lcd.enable = 0;
      delay_cycles(1);
      lcd.enable = 1;
      delay_us(1);
      low = lcd.data;
      lcd.enable = 0;
      set_tris_lcd(LCD_WRITE);
      return( (high<<4) | low);
}


void lcd_send_nibble( BYTE n ) {
      lcd.data = n;
      delay_cycles(1);
      lcd.enable = 1;
      delay_us(2);
      lcd.enable = 0;
}


void lcd_send_byte( BYTE address, BYTE n ) {

      lcd.rs = 0;
      while ( bit_test(lcd_read_byte(),7) ) ;
      lcd.rs = address;
      delay_cycles(1);
      lcd.rw = 0;
      delay_cycles(1);
      lcd.enable = 0;
      lcd_send_nibble(n >> 4);
      lcd_send_nibble(n & 0xf);
}


void lcd_init() {
    BYTE i;
    set_tris_lcd(LCD_WRITE);
    lcd.rs = 0;
    lcd.rw = 0;
    lcd.enable = 0;
    delay_ms(15);
    for(i=1;i<=3;++i) {
      lcd_send_nibble(3);
      delay_ms(5);
    }
    lcd_send_nibble(2);
    for(i=0;i<=3;++i)
      lcd_send_byte(0,LCD_INIT_STRING[i]);
}


void lcd_gotoxy( BYTE x, BYTE y) {
  BYTE address;

  if(y!=1)
    address=lcd_line_two;
  else
    address=0;
  address+=x-1;
  lcd_send_byte(0,0x80|address);
}

void lcd_putc( char c) {
  switch (c) {
    case '\f'  : lcd_send_byte(0,1);
                  delay_ms(2);
                                          break;
    case '\n'  : lcd_gotoxy(1,2);        break;
    case '\b'  : lcd_send_byte(0,0x10);  break;
    default    : lcd_send_byte(1,c);    break;
  }
}

char lcd_getc( BYTE x, BYTE y) {
  char value;

    lcd_gotoxy(x,y);
    while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
    lcd.rs=1;
    value = lcd_read_byte();
    lcd.rs=0;
    return(value);
}


doianhve 22-06-2007 01:02 PM

Code:

-------------------------------SPI.c-------------------------
// for the original source, and hundreds more examples of PIC C code, see:
// http://www.microchipc.com/sourcecode/#mmc
int8 Nhay_dong;
char str[80];
int mmc_init();
int mmc_response(unsigned char response);
int mmc_read_block(unsigned long block_number);
int mmc_write_block(unsigned long block_number);
int mmc_get_status();


/************************** MMC Init **************************************/
/* Initialises the MMC into SPI mode and sets block size, returns 0 on success */

int mmc_init()
{
int i;

SETUP_SPI(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_4 | SPI_SS_DISABLED);

*0x94 |= 0x40;                          // set CKE = 1 - clock idle low
*0x14 &= 0xEF;                          // set CKP = 0 - data valid on rising edge

OUTPUT_HIGH(PIN_C2);                    // set SS = 1 (off)

for(i=0;i<10;i++)                      // initialise the MMC card into SPI mode by sending clks on
{
        SPI_WRITE(0xFF);
}

OUTPUT_LOW(PIN_C2);                    // set SS = 0 (on) tells card to go to spi mode when it receives reset

SPI_WRITE(0x40);                        // send reset command
SPI_WRITE(0x00);                        // all the arguments are 0x00 for the reset command
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x95);                        // precalculated checksum as we are still in MMC mode

lcd_putc("\fSent go to SPI\n\r");

if(mmc_response(0x01)==1) return 1;    // if = 1 then there was a timeout waiting for 0x01 from the mmc

lcd_putc("Got response from MMC\n\r");

i = 0;

while((i < 255) && (mmc_response(0x00)==1))    // must keep sending command if response
{
        SPI_WRITE(0x41);                // send mmc command one to bring out of idle state
        SPI_WRITE(0x00);                // all the arguments are 0x00 for command one
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF
        i++;
}
if(i >= 254) return 1;                  // if >= 254 then there was a timeout waiting for 0x00 from the mmc

lcd_putc("\fGot out of idle response from MMC\n\r");

OUTPUT_HIGH(PIN_C2);                    // set SS = 1 (off)

SPI_WRITE(0xFF);                        // extra clocks to allow mmc to finish off what it is doing

OUTPUT_LOW(PIN_C2);                    // set SS = 0 (on)

        SPI_WRITE(0x50);                // send mmc command one to bring out of idle state
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0x02);                // high block length bits - 512 bytes
        SPI_WRITE(0x00);                // low block length bits
        SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF

if((mmc_response(0x00))==1) return 1;
OUTPUT_HIGH(PIN_C2);            // set SS = 1 (off)
lcd_putc("\fGot set block length response from MMC\n\r");
return 0;
}

/************************** MMC Get Status **************************************/
/* Get the status register of the MMC, for debugging purposes */

int mmc_get_status()
{

OUTPUT_LOW(PIN_C2);                    // set SS = 0 (on)

        SPI_WRITE(0x58);                // send mmc command one to bring out of idle state
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);                //
        SPI_WRITE(0x00);                // always zero as mulitples of 512
        SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF

OUTPUT_HIGH(PIN_C2);                    // set SS = 1 (off)
return 0;
}

/************************** MMC Write Block **************************************/
int mmc_write_block(unsigned long block_number)
{
unsigned long i;
unsigned long varh,varl;

varl=((block_number&0x003F)<<9);
varh=((block_number&0xFFC0)>>7);

puts("Write block\n\r");                // block size has been set in mmc_init()

OUTPUT_LOW(PIN_C2);                    // set SS = 0 (on)

        SPI_WRITE(0x58);                // send mmc write block
        /*
        SPI_WRITE(HIGH(varh));
        SPI_WRITE(LOW(varh));
        SPI_WRITE(HIGH(varl));
        */
        SPI_WRITE(0x1001);      // arguments are address
        SPI_WRITE(0x1011);
        SPI_WRITE(0x100);
        SPI_WRITE(0x00);                // always zero as mulitples of 512
        SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF

if((mmc_response(0x00))==1) return 1;
puts("Got response to write block\n\r");

SPI_WRITE(0xFE);                        // send data token
//----------------Ghi du lieu vao MMC-----------------
      strcpy(str,"Nguyen Duc Hung_Dl1_K47_DHBKHN");  ///Ghi vao the nho
      nhay_dong=0;
      for(i=0;i<512;i++)
      {
            ++nhay_dong;
            SPI_WRITE(str[Nhay_Dong]);    // send data
            if (nhay_dong>=32)
            {
              nhay_dong=0;
            }
      }

SPI_WRITE(0xFF);                        // dummy CRC
SPI_WRITE(0xFF);

if((SPI_READ(0xFF)&0x0F)!=0x05) return 1;

puts("Got data response to write block\n\r");

OUTPUT_HIGH(PIN_C2);                    // set SS = 1 (off)
return 0;
}



/************************** MMC Read Block **************************************/
/**** Reads a 512 Byte block from the MMC and outputs each byte to RS232 ****/
int mmc_read_block(unsigned long block_number)
{
unsigned long i;
unsigned long varh,varl;

varl=((block_number&0x003F)<<9);
varh=((block_number&0xFFC0)>>7);

OUTPUT_LOW(PIN_C2);                    // set SS = 0 (on)

        SPI_WRITE(0x51);                // send mmc read single block command
        SPI_WRITE(0x1001);      // arguments are address
        SPI_WRITE(0x1011);
        SPI_WRITE(0x100);
        SPI_WRITE(0x00);
        SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF

if((mmc_response(0x00))==1) return 1;  // if mmc_response returns 1 then we failed to get a 0x00 response (affirmative)

lcd_putc("Got response to read block command\n\r");

if((mmc_response(0xFE))==1) return 1;  // wait for data token

//---------------------------------------doc tu the len-------------------
        nhay_dong=0;
        lcd_putc("\fGot data token\n\r");
        lcd_putc("\f");  //Xoa Man Hinh
        for(i=0;i<512;i++)
        {
                ++nhay_dong;
                lcd_putc(SPI_READ(0xFF));              // we should now receive 512 bytes

                if (nhay_dong==16)
                {
                      lcd_putc("\n");
                      lcd_putc(SPI_READ(0xFF));              // we should now receive 512 bytes
                }
                    if (nhay_dong>=31)
                {
                      lcd_putc("\n");
                      nhay_dong=0;
                      lcd_putc("\f");
                }
                delay_ms(100);
        }

SPI_READ(0xFF);                // CRC bytes that are not needed
SPI_READ(0xFF);

OUTPUT_HIGH(PIN_C2);            // set SS = 1 (off)
SPI_WRITE(0xFF);                // give mmc the clocks it needs to finish off

lcd_putc("End of read block");

return 0;
}

/************************** MMC get response **************************************/
/**** Repeatedly reads the MMC until we get the response we want or timeout ****/

int mmc_response(unsigned char response)
{
        unsigned long count = 0xFFFF;          // 16bit repeat, it may be possible to shrink this to 8 bit but there is not much point

        while(SPI_READ(0xFF) != response && --count > 0);

        if(count==0) return 1;                  // loop was exited due to timeout
        else return 0;                          // loop was exited before timeout
}


doianhve 23-06-2007 11:52 AM

alo.Ko ai nói j à.Chán ghê.

bien_van_khat 05-07-2007 11:22 AM

Các bạn post code thì nên bỏ vào trong thẻ [code] để vậy đọc ko nổi. Lần này mình sửa dùm bạn, nhưng ko có lần sau nhé.

Chính xác vấn đề mà bạn gặp phải là gì, mình cũng đã làm MMC ở mode SPI rồi, có gì mình có thể giúp bạn. Vấn đề lớn nhất mà mình gặp phải là cái connector, vì đồ chế nên tiếp xúc ko tốt lúc chạy lúc ko, đành phải hi sinh 1 cái đầu đọc thẻ để tháo mỗi cái connector.

bluepine 16-07-2007 10:04 AM

Trích:

Nguyên văn bởi doianhve (Post 9520)
Xin chào các cao thủ.Tôi đang nghiên cứu giao tiếp card MMC thông qua chuẩn truyền SPI mà thấy khó ghê.Ai có tài liệu hay kinh nghiệm gì share tôi với.Thanks.

Chào bạn,
tôi gửi bạn một số tài liệu tham khảo rất có ích cho bạn khi bắt đầu nghiên cứu MMC card qua giao tiếp SPI. Tôi cũng đang tịm hiểu về MMC card, chúng ta có thể trao đổi thêm.
http://elm-chan.org/docs/mmc/mmc_e.html
http://www.hcilab.org/projects/parti...ticles-mmc.htm
http://forum.microchip.com/tm.aspx?m=58980&mpage=3
Thân.

batinh 28-08-2007 11:08 AM

tôi sử dụng 18F4550 thì khai báo có gì khác không mà sao làm mấy ngày rồi không đc. SD card với LCD.

quyenemic 30-08-2007 05:25 PM

Bài viết hay đó, cảm ơn bạn.

byte 01-12-2007 12:38 PM

tui chơi quả AVR giao tiếp với thẻ nhớ. Chạy ngon, file đọc được ngon nhưng chẳng biết làm gì với nó cả. trừ file text cho hiển thị lcd. Nói chung viết với Vdk nào thì cũng vậy thôi, có điều là mình làm thế nào thì nó mới đưa cho mình dữ liệu (giải thuật). Để ghi dữ liệu vào hay đọc dữ liệu ra theo một sector thì đơn giản hơn những gì bạn tưởng. Chỉ đến khi nào bạn muốn làm việc với file thì lúc đó vấn đề mới thực sự bắt đầu. Tôi lằng nhằng mãi với cái đống FAT, rdet, sdet, bootsector...mãi mới ra, giờ thì cũng thông rồi. Các bạn cứ làm đi, có gì tôi biết tôi có thể chỉ cho các bạn.
Bạn chú ý khi mắc phần cứng, tay MMC làm việc với điện áp 3.3v cho nên bạn đấu cẩn thận. Nguồn 5V cho qua 2 thằng diode mới được đưa vào thẻ nhớ. (5-0.7*2 = 3.4 ~3.3). Mức 1 ở VDK là 5V, khi đưa mức 1 này vào thẻ cũng cần qua cầu phân áp cho nó còn khoảng 3.3 v mới dc. Tôi chưa thử phi 5V vào nên chẳng biết là sẽ có chuyện gì sảy ra. Nhưng nói chung là không nên. Hì hì
Bạn đừng hỏi nhiều quá, bắt tay vào làm từ ABC, đến đâu không biết bắt đầu mới hỏi. Như vậy thì mình mới hiểu sâu vấn đề dc.

namqn 01-12-2007 04:56 PM

Trích:

Nguyên văn bởi byte (Post 13189)
...
Nguồn 5V cho qua 2 thằng diode mới được đưa vào thẻ nhớ. (5-0.7*2 = 3.4 ~3.3). ...

5 - 0.7*2 = 3.6 chứ. Các giải pháp rẻ tiền tạo nguồn 3.3 V từ nguồn 5 V tôi đã nói ở post #21 trong luồng sau:

http://www.picvietnam.com/forum/show...p?t=401&page=2

Thân,

byte 01-12-2007 05:01 PM

hì, quên. Nếu chơi sang làm hẳn con IC gì gì đó về tạo nguồn 3.3V , cái đó tui cũng chưa biết, trước tới giờ toàn chơi 2 chú 1n4007. Hì hì

minhtienbk 17-01-2008 12:24 AM

cái này tui nghĩ nó có thể thay thế com ROM rất ok , 1 mạch thu thập dữ liệu , lưu vào đó , sau 1 thời gian , lấy thẻ ra , cắm vào máy tính hay DTDD , rồi đọc dữ liệu đó , hình ảnh , hay âm thanh , hay biểu đồ , có lẽ vậy là ứng dụng dc vài thế mạnh của nó ... , còn ai siêu thì lưu mp3 vô hát ( mắc hơn đi mua máy mp3)
còn tạo ra 3.3v , thì chỉ cần 1 con zenner 3.3v , hé hé , cái này học trc khi học BJT

PIC_Phan 17-01-2008 03:28 PM

Ổn áp 3V3 cho MMC card nên dùng con BA033T cho ổn định, nếu dùng zenner ghim áp lỡ "giữa đường đứt gánh" thì toi cái thẻ!!

bogu 24-11-2008 11:36 PM

Code:

#include<16f877a.h>
#include<def_877a.h>
// Speihersutz121345=aus,Debug11=aus,ProgrammFlash9=an,EEpromRead8=an,NiendervoltProgr7=aus
// NiederVoltReset6=an,EinschaltTimer3=an,WachDogTimer2=aus,Oszilator01=XC
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232 (baud=4800 , parity = N , xmit=pin_C6 , rcv=pin_C7 )


#bit CS = PORTC.2    //Ausgang für Chip Select
#bit SCK = PORTC.3    //Ausgang Clock
#bit SDO = PORTC.5    //Ausgang Daten Output
#bit SDI = PORTC.4    //Eingang Daten Input
#byte temp = 0x31
#bit temp_7 = temp.7
#byte temp1 = 0x32
#bit temp1_0 = temp1.0
#define bls 20
int mmc_init();

int mmc_response(unsigned char response);

int mmc_read_block(int32 add,int result); 

int1 mmc_write_block(int32 add,int tem);

int mmc_get_status();
#INT_RDA // Ham xu ly ngat noi tiep
void Receive_isr()
{
  int c;
  c = fgetc();
  printf("%d",c);
 
}

/*-------------------------------------------------------------------------*/
int1 command(int8 bef,long adrh,long adrl,int8 bes)
{spi_write(0xff);
 spi_write(bef);
 spi_write(make8(adrh,1));
 spi_write(make8(adrh,0));
 spi_write(make8(adrl,1));
 spi_write(make8(adrh,0));
 spi_write(bes);
 spi_write(0xff);
return (spi_read(0xff));
}

/************************** MMC Init **************************************/
/*
 Initialises the MMC into SPI mode and sets block size, returns 0 on success */


int mmc_init()
{
long i;

SETUP_SPI(SPI_MASTER | SPI_l_TO_h | SPI_CLK_DIV_16);

*0x94 |= 0x40;            // set CKE = 1 - clock idle low
*0x14 &= 0xEF;            // set CKP = 0 - data valid on rising edge

cs=1;        // set SS = 1 (off)


for(i=0;i<1000;i++)  // initialise the MMC card into SPI mode by sending clks on
{
     
 SPI_WRITE(0xff);
}


cs=0; ; 
 // set SS = 0 (on) tells card to go to spi mode when it receives reset

i=20;
while((command(0x40,0,0,0x95)!=1)&&(i>0)) { command(0x40,0,0,0x95);--i; }
 if(i==0) return 1;
 // precalculated checksum as we are still in MMC mode

puts("Sent go to SPI\n\r");

 
// if = 1 then there was a timeout waiting for 0x01 from the mmc

puts("Got response from MMC\n\r");

i = 0;

while((i < 255) && (spi_read(0xff)==0))   
// must keep sending command if response
{
        SPI_WRITE(0x41);               
        // send mmc command one to bring out of idle state
        SPI_WRITE(0x00);             
        // all the arguments are 0x00 for command one
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0xFF);               
        // checksum is no longer required but we always send 0xFF
        i++;
}
if(i >= 254) return 1;                 
// if >= 254 then there was a timeout waiting for 0x00 from the mmc

puts("Got out of idle response from MMC\n\r");

OUTPUT_HIGH(PIN_C2);                   
// set SS = 1 (off)

SPI_WRITE(0xFF);                     
  // extra clocks to allow mmc to finish off what it is doing

OUTPUT_LOW(PIN_C2);                   
 // set SS = 0 (on)

        SPI_WRITE(0x50);             
        // send mmc command one to bring out of idle state
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);             
        // high block length bits - 512 bytes
        SPI_WRITE(0x14);             
        // low block length bits
        SPI_WRITE(0xFe);             
        // checksum is no longer required but we always send 0xFF

if((mmc_response(0x00))==1) return 1;
OUTPUT_HIGH(PIN_C2);            // set SS = 1 (off)
puts("Got set block length response from MMC\n\r");
return 0;
}

/************************** MMC Get Status **************************************/
/* Get the status register of the MMC, for debugging purposes */

int mmc_get_status()
{

OUTPUT_LOW(PIN_C2);                   
 // set SS = 0 (on)

        SPI_WRITE(0x58);               
        // send mmc command one to bring out of idle state
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);             
        //
        SPI_WRITE(0x00);             
        // always zero as mulitples of 512
        SPI_WRITE(0xFF);             
        // checksum is no longer required but we always send 0xFF

OUTPUT_HIGH(PIN_C2);                 
  // set SS = 1 (off)
return 0;
}

/*---------------------------------------------------------------------------*/
int1 mmc_write_sector(int32 add,int temp)
{int32 j;
 int8 val,tg;
 j=add;
      output_low(pin_c2);
      SPI_WRITE(0x58);               
      // send mmc write block
    SPI_WRITE(make8(j,3));
    SPI_WRITE(make8(j,2));
    SPI_WRITE(make8(j,1));
    SPI_WRITE(make8(j,0));
    SPI_WRITE(0x00); 
    SPI_WRITE(0xff);
    if(spi_read(0xff)!=0x05) return 1;
     
      SPI_WRITE(0xff);
      spi_write(0xfe);  //crc
      for(tg=20;tg>0;--tg) Spi_write(temp);
      spi_write(0xff);  //crc
      spi_write(0xff);  //crc
      if(!(mmc_response(0x00)&&0x1f)==0x05) return 1;
      printf("ok da 1 xong\n\r");
      output_high(pin_c2);
      return 0;
}

/*---------------------------------------------------------------------------*/

int mmc_read_block(int32 add,int result) 
{
  int32 i;
  int8 tg;
i=add;
  output_low(pin_c2);
  spi_write(0x51);
  SPI_WRITE(make8(i,3));
    SPI_WRITE(make8(i,2));
    SPI_WRITE(make8(i,1));
    SPI_WRITE(make8(i,0));
    SPI_WRITE(0x00); 
    SPI_WRITE(0xff);
    if(spi_read(0xff)!=0) return 1;
    printf("da doc\n\r");
    for(tg=20;tg>0;--tg) result=spi_read(0xff);             
  spi_write(0xff);  //crc
  spi_write(0xff);  //crc
  Output_high(Pin_c2);   
    spi_write(0xff);
    return result;
    }

/************************** MMC get response **************************************/
/**** Repeatedly reads the MMC until we get the response we want or timeout ****/

int mmc_response(unsigned char response)
{
        unsigned long count = 0xFFFF;         
        // 16bit repeat, it may be possible to shrink this to 8 bit but there is not much point

        while(SPI_READ(0xFF) != response && --count > 0);

        if(count==0) return 1;                  // loop was exited due to timeout
        else return 0;                          // loop was exited before timeout
}



void main()
{

int add,hi,m;
char i,temp;
  TRISC=0xc3;
  trisb=0x00;
  portc=0x00;
  i=2;
  add=1024;
  enable_interrupts(int_rda);
  enable_interrupts(GLOBAL);
  mmc_init();
  if(mmc_init()==0)  printf("Hello PIC Viet Nam!\n\r ");
  else
  printf("chan qua! ");
}



cho em hỏi code của em sai tại đâu mà không thể khởi tạo được MMC. Tức phản hồi R1 của MMC luôn #0x01

bogu 28-11-2008 11:42 PM

chán quá
Hem ai quan tâm tới vẫn đề này nữa sao??????????????

bien_van_khat 29-11-2008 11:12 AM

- Sơ đồ mạch của bạn như thế nào? Trước tiên phải chắc chắn mạch của bạn đúng.
- Bắt đầu từ command nào, thẻ ko phản hồi, hoặc phản hồi sai?

debugger 30-11-2008 12:08 AM

Trích:

Nguyên văn bởi bogu (Post 20913)
chán quá
Hem ai quan tâm tới vẫn đề này nữa sao??????????????

chào bạn bogu, hình như bạn copy đoạn code này của một thằng Tây nào đúng không. Code của nó không chạy là vì thế này: để đợi cái Respond 0x01 thì biến đếm i=20 là quá nhỏ, bạn cho to lên cỡ vài nghìn, hoặc vài chục nghìn là chạy ngay (trừ khi phần cứng của bạn có vấn đề). Nhớ là là phải dùng kiểu int16 nhá. Chúc bạn may mắn. À quên, mình có viết một thư viện đọc/ghi/liệt kê/tạo mới/xóa file và thư mục trên thẻ nhớ theo định dạng fat32, tốc độ rất nhanh và chắc chắn dễ dùng hơn của mấy ông Tây kia nhiều... bạn cần thì cứ cho ý kiến nhá.

bogu 30-11-2008 01:39 AM

1 Attachment(s)
Em thử mô phỏng trên Proteus7.2
Ngay từ command 1 nó đã không nhận rồi
Em kiẻm tra Response R1 nó đã khác 1
làm đi làm lại mãi rùi, mà kể cả cho "i=5000" luôn, như lời debugger cũng hem được nữa
Nản quá! Đại ca nào giúp em với! :((

bogu 30-11-2008 01:51 AM

1 Attachment(s)
À wên em gởi lun theo đây file mô phỏng của anh Yankazaz post lên
Mong các anh hồi âm mau mau nhé

bogu 30-11-2008 02:05 AM

bạn Deugger ơi, còn Onl không
Bạn có thể cho send cho mình cái thư viện đó mau mau được hem, tại thứ 3 tới là phải gặp thầy lần nữa rùi !!!
Cảm ơn bạn trước nhá :D

debugger 30-11-2008 08:11 AM

Thư viện của mình mới dùng được cho họ MCS-51 và ARM thôi, mình đang port nó sang PIC. Nhưng vấn đề là thư viện của mình sử dụng cache khoảng 2K, trong khi, như bạn biết đấy, RAM của mấy con PIC16 ít quá, lại bị xé lẻ thành nhiều bank. Có lẽ mình sẽ port nó sang thằng PIC24 hoặc 32 thôi.
Để cho nhanh bạn send cho mình cái project của bạn cùng với source code và mô phỏng, mình xem và sửa cho. Mà cái file MMC_PC lúc nãy bạn gửi thiếu file hex và file image

debugger 30-11-2008 08:57 AM

Code:

i=20;
while((command(0x40,0,0,0x95)!=1)&&(i>0)) { command(0x40,0,0,0x95);--i; }
if(i==0) return 1;

Mình xem lại code của bạn rồi, cái vòng while là không ổn. thường thì sau khi nhận lệnh 0x40 trong vòng khoảng 64 chu kì đồng hồ là nó respond lại 0x01 rồi. Bên trong vòng while của bạn lại một command nữa với rất nhiều clock bắn vào mà không kiểm tra từng byte nó bắn ra. Khi đó cái respond 0x01 ra lúc nào mà bạn không biết. Bạn thử sửa lại thế này xem nhá:

Code:

command(0x40,0,0,0x95);
i=100;
while(spi_read(0xFF)!= 0x01)
{
    if(i== 0) return 1;
    i--;
}

Đồng thời sửa lại hàm command sang kiểu void thế này
void command(int8 bef,long adrh,long adrl,int8 bes)
Code:

{
spi_write(bef);
spi_write(make8(adrh,1));
spi_write(make8(adrh,0));
spi_write(make8(adrl,1));
spi_write(make8(adrh,0));
spi_write(bes);
}


bogu 01-12-2008 02:21 PM

1 Attachment(s)
Debugger ơi, chán quá thử lại rùi mà vẫn không được:(
Hay đã giúp thì giúp cho chót, mình đã post mạch với code rồi đó
bạn có thể sửa code xong mô phỏng luôn xem chạy chưa
Trời ơi, điên đầu với con MMC này gần 5 tuần rồi!!:(
À t đưa luôn file hex với image của anh Yankazza

debugger 01-12-2008 03:16 PM

Cái file MMC_PC bạn bogu gửi lên làm gì có code, cũng không có file hex và file image của mmc nữa, có mỗi 1 cái file proteus thì làm sao mình chạy được. bạn gửi lại đi

bogu 02-12-2008 08:31 PM

1 Attachment(s)
Uh, mình quên.Tại gửi file cardimage sẵn trong file của anh Yankazza, nên mình thui
Mình đã gởi kèm luôn cả project MMC và mạch mô phỏng đó. À mình đọc trên diễn đàn thấy
nói khi khởi tạo MMC phải giữ tốc độ <400K/s sau khi khởi tạo xong mới được tăng lên
cũng chả rõ nữa, nhưng thử luôn rồi mà cũng chẳng xong...hết thuốc cứu???:(

bogu 02-12-2008 08:36 PM

À lại quên nữa mình dùng CCS4.03 lập trình cho PIC. Debugger có chưa, nếu chưa bạn download ở đây nè
http://rs111.rapidshare.com/files/32...CWH_v4.033.rar
Cảm ơn bạn Debugger nhiệt tình giúp mình nha:)

debugger 03-12-2008 11:35 AM

Help Bogu
 
1 Attachment(s)
Mình sửa cho bạn rồi đấy. Lỗi chính là bạn đấu sai chân và cách đợi time-out. Bạn Xem rồi cho ý kiến nhá. Good luck!

bogu 05-12-2008 12:42 AM

Phải nói thật tình là rất cảm ơn debugger.
Không có bạn chắc tiêu quá:) Tuy vậy...hì hì. Sau nè chắc còn phải làm phiền debugger nhiều nhiều nữa...

quocloc.pham 11-12-2008 10:08 AM

Chuyển mức áp giao tiếp 5v-->3.3V!!!!!!
 
Mình đang làm giao tiếp giữa micro SD card và 876A, nhưng mình gặp vấn đề giao tiếp 5v và 3.3V giữa SD và PIC, mình định sử dụng 74HC07 hoặc 74HC125 nhưng tìm cả chợ Nhật Tảo mà không thấy dòng HC. Ai biết có chổ nào bán thì chỉ giúp mình với
hay bạn nào có giải pháp nào hay có thể chia sẽ, mình cũng đã thử phân áp nhưng không khả thi
Thân!

debugger 11-06-2009 11:41 PM

Module giao tiếp thẻ nhớ MMC/SD FAT32
 
2 Attachment(s)
Giới thiệu mọi người một module giao tiếp thẻ nhớ MMC/SD hỗ trợ FAT32 đã hoàn chỉnh của tôi. Module này hỗ trợ hầu hết các chức năng về đọc, ghi, xóa, tạo mới,... với tệp và thư mục lưu trong thẻ nhớ định dạng FAT32.
Đặc biệt module này làm việc với dải điện áp rộng, nuôi bằng 3.3V hoặc 5V đều được nên có thể đầu nối trực tiếp với VĐK chạy 3.3V hoặc 5V mà không cần thông qua bất kì một mạch chuyển đổi điện áp nào cả.

Bạn có thể tham khảo và so sánh với các sản phẩm cùng loại của các hãng khác như
- uMMC của Rogue Robotics (Canada)
- uALFAT của GhiElectronics (USA)
- Serial MMC/SD của Cubloc (Korea)
-----------------------------------------------------------------------------------------------
Mọi chi tiết về sản phẩm xin liên hệ theo email: bvhoang42@yahoo.com

haquang 03-07-2009 12:48 PM

Thắc mắc về thẻ MMC
 
Em có cái thắc mắc về thẻ MMC, các bác giải đáp giúp em với!

Em có trong tay 1 thẻ MMC Mobile, e muốn làm giao tiếp với nó!Em đang thắc mắc là cái thẻ của em có 13 chân còn các thẻ trong các schematic hướng dẫn chỉ có 7 chân? Không biết có gì khác biệt mà....... chương trình của em mô phỏng thì chạy được nhưng chạy thật thì không init được gì cả!

Các bác giải thích hộ em cái!

Thanks các bác!

debugger 03-07-2009 11:04 PM

Trích:

Nguyên văn bởi haquang (Post 27358)
Em có cái thắc mắc về thẻ MMC, các bác giải đáp giúp em với!

Em có trong tay 1 thẻ MMC Mobile, e muốn làm giao tiếp với nó!Em đang thắc mắc là cái thẻ của em có 13 chân còn các thẻ trong các schematic hướng dẫn chỉ có 7 chân? Không biết có gì khác biệt mà....... chương trình của em mô phỏng thì chạy được nhưng chạy thật thì không init được gì cả!

Các bác giải thích hộ em cái!

Thanks các bác!

MMC Mobile thực chất rất giống với MMC. Bạn có thể lên google tìm và tra, rất rõ ràng và chi tiết. Tốt nhất khi bắt đầu bạn nên dùng các loại thẻ phổ biến như MMC, SD. Giá của mấy loại này cũng ko đắt và socket cắm thì cũng sẵn ở chợ. Còn việc bạn Init ko được có nhiều nguyên nhân. Về phần mềm thì bạn có thể down chương trình của mình post ở các bài trươc. Về phần cứng bạn cũng cần chú ý mức điện áp giao tiếp vì các loại thẻ này chạy 3.3V.

haquang 04-07-2009 12:00 PM

Em vừa lượn 1 vòng chợ trời mà không tìm được cái thẻ MMC 7 chân nào hết! :((

Có 1 vấn đề, e nhận thấy điện áp 2 chân 3 và 4 trên áo của thẻ MMC là 3.3V trước khi cắm thẻ vào nhưng...... khi cắm thẻ thì điện áp lên đến hơn 4V? Đây có phải là nguyên nhân không và làm sao để khắc phục? Các bác giúp em với!

PS: Em dùng IC 1117-33G để tạo điện áp 3.3V. Con này e dùng vài ứng dụng rồi, thấy chạy bình thường:(

nguyenhung1811 08-08-2009 12:32 PM

lam the nao de tu con pic minh co the tao file text trong the MMC ha cac ban. Cac ban co the huong dan cho minh duoc ko vay. Thanx

debugger 08-08-2009 05:20 PM

Trích:

Nguyên văn bởi nguyenhung1811 (Post 28462)
lam the nao de tu con pic minh co the tao file text trong the MMC ha cac ban. Cac ban co the huong dan cho minh duoc ko vay. Thanx

Cách nhanh nhất là bạn dùng FMC32. Nối chân RxD của FMC32 với chân TX của con Pic. Viết đoạn chương trình sau sẽ tạo file txt có tên là newfile.txt trong thẻ nhớ MMC:


void main()
{
delay_ms(1000); // đợi FMC32 khởi động xong
printf("o,rwc,/newfile.txt\r"); // Gửi lệnh tạo file
while(1); // Kết thúc chương trình
}

nguyenhung1811 11-08-2009 09:54 AM

thế mình có thể viết trực tiếp mà không cần dùng FMC32, pic giao tiếp SPI với MMC card kia`, nếu bạn nào biết xin hướng dẫn giúp mình với. Mình định làm thử một bộ đo nhiệt độ rồi cứ 1 giây nó ghi thời gian và nhiệt độ lên thé, sau đó mình lấy thẻ đem bỏ vào máy tính để xem thông số...


Múi giờ GMT. Hiện tại là 03:00 PM.

Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam