PIC Vietnam

Go Back   PIC Vietnam > Truyền thông > Giao tiếp USB, CAN, I2C, SPI, USART...

Tài trợ cho PIC Vietnam
Trang chủ Đăng Kí Hỏi/Ðáp Thành Viên Lịch Bài Trong Ngày Vi điều khiển

Giao tiếp USB, CAN, I2C, SPI, USART... Những giao tiếp được tích hợp trên PIC

Trả lời
 
Ðiều Chỉnh Xếp Bài
Old 22-06-2007, 09:46 AM   #1
doianhve
Đệ tử 2 túi
 
Tham gia ngày: Feb 2006
Bài gửi: 44
:
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.
doianhve vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 22-06-2007, 11:40 AM   #2
falleaf
PIC Bang chủ
 
falleaf's Avatar
 
Tham gia ngày: May 2005
Bài gửi: 2,631
:
Send a message via Yahoo to falleaf
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
falleaf vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 22-06-2007, 12:59 PM   #3
doianhve
Đệ tử 2 túi
 
Tham gia ngày: Feb 2006
Bài gửi: 44
:
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 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 22-06-2007, 12:45 PM   #4
doianhve
Đệ tử 2 túi
 
Tham gia ngày: Feb 2006
Bài gửi: 44
:
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 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 22-06-2007, 01:00 PM   #5
doianhve
Đệ tử 2 túi
 
Tham gia ngày: Feb 2006
Bài gửi: 44
:
-----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);
   }

}

thay đổi nội dung bởi: bien_van_khat, 09-07-2007 lúc 12:11 AM.
doianhve vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 22-06-2007, 01:01 PM   #6
doianhve
Đệ tử 2 túi
 
Tham gia ngày: Feb 2006
Bài gửi: 44
:
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);
}

thay đổi nội dung bởi: bien_van_khat, 09-07-2007 lúc 12:10 AM.
doianhve vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 22-06-2007, 01:02 PM   #7
doianhve
Đệ tử 2 túi
 
Tham gia ngày: Feb 2006
Bài gửi: 44
:
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
}

thay đổi nội dung bởi: bien_van_khat, 09-07-2007 lúc 12:09 AM.
doianhve vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 30-08-2007, 05:25 PM   #8
quyenemic
Đệ tử 1 túi
 
Tham gia ngày: Aug 2007
Bài gửi: 19
:
Bài viết hay đó, cảm ơn bạn.
__________________
Trừu đao đoạn thủy, thủy cánh lưu
Cử bôi tiêu sầu, sầu cánh sầu...
quyenemic vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 23-06-2007, 11:52 AM   #9
doianhve
Đệ tử 2 túi
 
Tham gia ngày: Feb 2006
Bài gửi: 44
:
alo.Ko ai nói j à.Chán ghê.
doianhve vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 08-11-2014, 05:16 PM   #10
huuhao1993
Nhập môn đệ tử
 
Tham gia ngày: Nov 2014
Bài gửi: 3
:
Trích:
Nguyên văn bởi doianhve View Post
alo.Ko ai nói j à.Chán ghê.
a ơi e đang làm giao tiếp MMC mà chả biết gì, có cái file tìm được trên mạng mà ko hiểu, a xem rồi giải thích code hộ e được ko ạ?
File Kèm Theo
File Type: rar MmcSd.rar (177.0 KB, 0 lần tải)
huuhao1993 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 05-07-2007, 11:22 AM   #11
bien_van_khat
...Damned...
 
bien_van_khat's Avatar
 
Tham gia ngày: Apr 2006
Nơi Cư Ngụ: Hồ Chí Minh
Bài gửi: 522
:
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.

thay đổi nội dung bởi: bien_van_khat, 09-07-2007 lúc 12:14 AM.
bien_van_khat vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 16-07-2007, 10:04 AM   #12
bluepine
Đệ tử 3 túi
 
Tham gia ngày: Jun 2006
Bài gửi: 53
:
Trích:
Nguyên văn bởi doianhve View Post
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.
bluepine vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 28-08-2007, 11:08 AM   #13
batinh
Nhập môn đệ tử
 
Tham gia ngày: May 2006
Bài gửi: 7
:
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.
batinh vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 01-12-2007, 12:38 PM   #14
byte
Nhập môn đệ tử
 
Tham gia ngày: Nov 2007
Bài gửi: 5
:
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.
byte vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 01-12-2007, 04:56 PM   #15
namqn
Trưởng lão PIC bang
 
Tham gia ngày: Feb 2006
Nơi Cư Ngụ: Tp. HCM, Việt Nam
Bài gửi: 3,025
:
Send a message via Yahoo to namqn
Trích:
Nguyên văn bởi byte View Post
...
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,
__________________
Biển học mênh mông, sức người có hạn.

Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau:
http://www.picvietnam.com/forum/showthread.php?t=1263
namqn vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Trả lời


Quyền Sử Dụng Ở Diễn Ðàn
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is Mở
Smilies đang Mở
[IMG] đang Mở
HTML đang Tắt

Chuyển đến


Múi giờ GMT. Hiện tại là 06:57 AM.


Được sáng lập bởi Đoàn Hiệp
Powered by vBulletin®
Page copy protected against web site content infringement by Copyscape
Copyright © PIC Vietnam