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 23-05-2009, 10:51 PM   #1
trachao
Nhập môn đệ tử
 
Tham gia ngày: Apr 2009
Bài gửi: 2
:
giao tiep voi sd card

Minh dang lam giao tiep voi sd card de doc du lieu file mp3 trong the nho' de phat ra am thanh.co' ai biet lam,hoac co' tai lieu ve mon' nay` ko chi giup minh voi'.
trachao vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 24-05-2009, 10:56 AM   #2
lcd_amptech
Đệ tử 2 túi
 
lcd_amptech's Avatar
 
Tham gia ngày: Feb 2008
Bài gửi: 35
:
@trachao
Bạn xem ở đây nè, code viet cho atmega8. Sơ đồ kết nối chân như trong định nghĩa trong code nên mình không post sơ đồ mạch lên.
Tài liệu thì có đầy trên mạng, bạn lên google kiếm.
http://my.opera.com/lcdamptech/blog/...d-bang-atmega8
__________________
http://my.opera.com/lcdamptech
lcd_amptech vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 20-11-2009, 03:52 PM   #3
tahi
Đệ tử 4 túi
 
Tham gia ngày: Mar 2009
Bài gửi: 64
:
em đang dính bệnh rất lạ , gửi cmd0 để reset thẻ thì ok, cmd1 để chuyển sang trạng thái data transfer mode cũng ok, nhưng đến lúc gửi lệnh đọc single block (cụ thể là sector 0)thì luôn response về mã lỗi 0x20, là address error. Gửi lệnh đọc các sector khác cũng bị tình trạng tương tự. Không biết bác nào bị bệnh này chưa, cho em hỏi với...
tahi vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 20-11-2009, 05:35 PM   #4
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
:
code bạn tự viết hay dùng thư viện. Thư viện và code mẫu cho SD card rất nhiều trên Net, bạn có thể tham khảo thư viện MDD của microchip.

http://www.microchip.com/stellent/id...cName=en537044
__________________
- Xin đọc trước khi post bài

Xin đặt code trong thẻ [ code ] [ /code ]
bien_van_khat vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 23-11-2009, 12:01 PM   #5
tahi
Đệ tử 4 túi
 
Tham gia ngày: Mar 2009
Bài gửi: 64
:
code tham khảo của bác falleaf (dùng cho chú dsPIC30F4013).Cụ thể là trong thread này:
http://www.picvietnam.com/forum/showthread.php?t=1663

Code:
#define BLOCK_SIZE 512
unsigned char SD_ReadBlock(unsigned long addr, unsigned char *buf)
{
	unsigned int i;
	unsigned char status;
	unsigned char CMD17_READ_SINGLE_BLOCK[] = {17,0x00,0x00,0x0,0x00,0xFF};
	CMD17_READ_SINGLE_BLOCK[1] = ((addr & 0xFF000000) >> 24);
	CMD17_READ_SINGLE_BLOCK[2] = ((addr & 0x00FF0000) >> 16);
	CMD17_READ_SINGLE_BLOCK[3] = ((addr & 0x0000FF00) >> 8);
	CMD17_READ_SINGLE_BLOCK[4] = ((addr & 0x000000FF));
	SD_Enable();
	i=0;
	do
	{	
		status = SD_WriteCommand(CMD17_READ_SINGLE_BLOCK);
		send_hex(status,"CMD17:");	
		if(i++ > 50)
		{	
			putsUART1((unsigned int*)"Read sector failed\n\r");
			break;
		}
	}
	while(status != 0x00);
	//Waif
	Delay_Us(150);
	// Send the read command
	if(status != 0)
	{
		// ABORT: invalid response for read single command
		return 1;
	}
	// Now wait for the "Start Block" token	(0xFE)
	// (see SanDisk SD Card Product Manual v1.9 section 5.2.4. Data Tokens)
	do
	{
		status = SPIRead();
		send_hex(status,"waitf token:");
	} while(status != 0xFE);
	// Read off all the bytes in the block
	for(i = 0; i < BLOCK_SIZE; ++i)
	{
		status = SPIRead();
		*buf = status;
		buf++;
	}	
	// Read CRC bytes
	status = SPIRead();
	status = SPIRead();
	SD_Disable();
	// Following a read transaction, the SD Card needs 8 clocks after the end 
	// bit of the last data block to finish up its work.
	// (from SanDisk SD Card Product Manual v1.9 section 5.1.8)
	SPIWrite(0xFF); 
	return 0;
}
trong main
status = SD_ReadBlock(0, buffer);
Hàm SD_WriteCommand vẫn giữ nguyên. Hàm read đã có write dummy data (write FF)
Còn lệnh nào có response R1 mà test đuợc không nhỉ. Tốc độ giao tiếp phụ thuộc thế nào với các loại thẻ khác nhau.
Khởi tạo thẻ nhớ với tốc độ 150k, gửi lệnh cmd0 để reset thẻ, R1 = 0x01 (ok..đã in idle state). Sau đó gửi lệnh cmd1 để vào data transfer mode. Chuyển tốc độ lên 1.25MHz. R1 = 0x00 (đã vào mode transfer)
Sau đó gửi lệnh CMD17 để đọc single block thì toàn response 0x20
Ở đây em chỉ đọc 512 byte bắt đầu từ địa chỉ 0x00, không biết đó có phải sector 0 hay ko. (em đã quét cả dải địa chỉ mà vẫn báo về như thế...)
CRC có chú ý gì ko?
tahi vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 23-11-2009, 02:00 PM   #6
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
:
Trích:
Nguyên văn bởi tahi View Post
code tham khảo của bác falleaf (dùng cho chú dsPIC30F4013).Cụ thể là trong thread này:
http://www.picvietnam.com/forum/showthread.php?t=1663

Code:
#define BLOCK_SIZE 512
unsigned char SD_ReadBlock(unsigned long addr, unsigned char *buf)
{
	unsigned int i;
	unsigned char status;
	unsigned char CMD17_READ_SINGLE_BLOCK[] = {17,0x00,0x00,0x0,0x00,0xFF};
	CMD17_READ_SINGLE_BLOCK[1] = ((addr & 0xFF000000) >> 24);
	CMD17_READ_SINGLE_BLOCK[2] = ((addr & 0x00FF0000) >> 16);
	CMD17_READ_SINGLE_BLOCK[3] = ((addr & 0x0000FF00) >> 8);
	CMD17_READ_SINGLE_BLOCK[4] = ((addr & 0x000000FF));
	SD_Enable();
	i=0;
	do
	{	
		status = SD_WriteCommand(CMD17_READ_SINGLE_BLOCK);
		send_hex(status,"CMD17:");	
		if(i++ > 50)
		{	
			putsUART1((unsigned int*)"Read sector failed\n\r");
			break;
		}
	}
	while(status != 0x00);
	//Waif
	Delay_Us(150);
	// Send the read command
	if(status != 0)
	{
		// ABORT: invalid response for read single command
		return 1;
	}
	// Now wait for the "Start Block" token	(0xFE)
	// (see SanDisk SD Card Product Manual v1.9 section 5.2.4. Data Tokens)
	do
	{
		status = SPIRead();
		send_hex(status,"waitf token:");
	} while(status != 0xFE);
	// Read off all the bytes in the block
	for(i = 0; i < BLOCK_SIZE; ++i)
	{
		status = SPIRead();
		*buf = status;
		buf++;
	}	
	// Read CRC bytes
	status = SPIRead();
	status = SPIRead();
	SD_Disable();
	// Following a read transaction, the SD Card needs 8 clocks after the end 
	// bit of the last data block to finish up its work.
	// (from SanDisk SD Card Product Manual v1.9 section 5.1.8)
	SPIWrite(0xFF); 
	return 0;
}
trong main
status = SD_ReadBlock(0, buffer);
Hàm SD_WriteCommand vẫn giữ nguyên. Hàm read đã có write dummy data (write FF)
Còn lệnh nào có response R1 mà test đuợc không nhỉ. Tốc độ giao tiếp phụ thuộc thế nào với các loại thẻ khác nhau.
Khởi tạo thẻ nhớ với tốc độ 150k, gửi lệnh cmd0 để reset thẻ, R1 = 0x01 (ok..đã in idle state). Sau đó gửi lệnh cmd1 để vào data transfer mode. Chuyển tốc độ lên 1.25MHz. R1 = 0x00 (đã vào mode transfer)
Sau đó gửi lệnh CMD17 để đọc single block thì toàn response 0x20
Ở đây em chỉ đọc 512 byte bắt đầu từ địa chỉ 0x00, không biết đó có phải sector 0 hay ko. (em đã quét cả dải địa chỉ mà vẫn báo về như thế...)
CRC có chú ý gì ko?
Bạn sử dụng trình dịch gì?
__________________
- Xin đọc trước khi post bài

Xin đặt code trong thẻ [ code ] [ /code ]
bien_van_khat vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 24-11-2009, 05:22 PM   #7
tahi
Đệ tử 4 túi
 
Tham gia ngày: Mar 2009
Bài gửi: 64
:
MPLAB IDE 8.36 với C30 version 3.20

Loại thẻ nào có thể ăn với lệnh CMD55+ACMD41...Em gửi lệnh này sau khi đã reset thẻ thì nó báo về
R1 = 0x05 (illegal command + in idle state)
tahi vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 24-11-2009, 08:37 PM   #8
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
:
Trích:
Nguyên văn bởi tahi View Post
MPLAB IDE 8.36 với C30 version 3.20

Loại thẻ nào có thể ăn với lệnh CMD55+ACMD41...Em gửi lệnh này sau khi đã reset thẻ thì nó báo về
R1 = 0x05 (illegal command + in idle state)
Chỉ có SD card mới trả lời CMD55. MMC ko trả lời CMD55.
Bạn phải chờ tới khi card trả lời CMD55 hoặc timeout rồi mới gửi ACMD41

Bạn thử gửi ACMD41 với các tham số
Code:
unsigned char ACMD41_SD_SEND_OP_COND[] = {41,0x40,0x00,0x00,0x00,0xFF};
Đoạn code bạn sử dụng vốn chỉ là đoạn code mẫu, để tránh mất thời gian debug vô ích mình khuyên bạn nên dùng MDD.
__________________
- Xin đọc trước khi post bài

Xin đặt code trong thẻ [ code ] [ /code ]
bien_van_khat vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 26-11-2009, 10:04 AM   #9
tahi
Đệ tử 4 túi
 
Tham gia ngày: Mar 2009
Bài gửi: 64
:
Code:
    // Send CMD55, required to precede all "application specific" commands
	unsigned char CMD55_APP_CMD[] = {55,0x00,0x00,0x00,0x00,0x00};
	status = SD_WriteCommand(CMD55_APP_CMD); // Do not check response here	
	send_hex(status,"CMD55:");	
	
	// Send the ACMD41 command to initialize SD Card mode (not supported by MMC cards)
	i = 0;
	unsigned char ACMD41_SD_SEND_OP_COND[] = {41,0x40,0x00,0x00,0x00,0xFF};
	do
	{
		status = SD_WriteCommand(ACMD41_SD_SEND_OP_COND);
		// Might return 0x04 for Invalid Command if MMC card is connected
		send_hex(status,"ACMD41:");
		if(i++ > 50)
		{
			return 3;
		}
	} while( (status & R1_IN_IDLE_STATE) != 0 );
Gửi CMD55 trả về 0x01 , in idle state
Gửi ACMD41 trả về 0x05, in idle state and illegal command
có phải lệnh CMD1 và CMD55+ACMD41 là tương đương nhau ?

Bản MDD 1.2.1 down về, ko thấy support dòng dsPIC33, cũng ko thấy chỗ nào gán thanh ghi cho dspic33, mặc dù tiêu đề ghi là có hỗ trợ. Đương nhiên là có thể sửa từ PIC24,

Hay là phần cứng có vấn đề gì (e chỉ nối MOSI, MISO, SS, CLK). Thằng này có tính năng remappable, nhưng em chỉ remap cho thằng MOSI, MISO, CLK, còn SS thì define cho 1 pin khác.
tahi vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 26-11-2009, 10:56 AM   #10
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
:
Trích:
Nguyên văn bởi tahi View Post
Code:
    // Send CMD55, required to precede all "application specific" commands
	unsigned char CMD55_APP_CMD[] = {55,0x00,0x00,0x00,0x00,0x00};
	status = SD_WriteCommand(CMD55_APP_CMD); // Do not check response here	
	send_hex(status,"CMD55:");	
	
	// Send the ACMD41 command to initialize SD Card mode (not supported by MMC cards)
	i = 0;
	unsigned char ACMD41_SD_SEND_OP_COND[] = {41,0x40,0x00,0x00,0x00,0xFF};
	do
	{
		status = SD_WriteCommand(ACMD41_SD_SEND_OP_COND);
		// Might return 0x04 for Invalid Command if MMC card is connected
		send_hex(status,"ACMD41:");
		if(i++ > 50)
		{
			return 3;
		}
	} while( (status & R1_IN_IDLE_STATE) != 0 );
Gửi CMD55 trả về 0x01 , in idle state
=> card bạn dùng là SD card
Trích:
Gửi ACMD41 trả về 0x05, in idle state and illegal command
Đáng lẽ card phải trả lời 0x01, sau đó bạn tiếp tục gửi CMD55 + ACMD41 cho tới khi card trả lời 0x00
Trích:
có phải lệnh CMD1 và CMD55+ACMD41 là tương đương nhau ?
CMD1 là chuyển từ IDLE sang hoạt động và dùng cho thẻ SD/MMC
CMD55+ACMD41 để chuyển từ IDLE sang hoạt động và chỉ dùng cho thẻ SD

Tuy nhiên vì thẻ SD tương thích với thẻ MMC nên mình nghĩ bạn có thể bỏ qua CMD55+ACMD41 và gửi lệnh SET_BLOCK_LEN = 512 (command 16), sau đó kết thúc phần init bằng 8 lần ghi 0xff.

Đoạn code mẫu của anh Hiệp thiếu lệnh SET_BLOCK_LEN, có lẽ đây là lý do làm bạn nhận về mã lỗi địa chỉ sai.

Trích:
Hay là phần cứng có vấn đề gì (e chỉ nối MOSI, MISO, SS, CLK). Thằng này có tính năng remappable, nhưng em chỉ remap cho thằng MOSI, MISO, CLK, còn SS thì define cho 1 pin khác.
Bạn ko nên dùng chân SS của SPI, dùng 1 chân IO bình thường để nối tới chân CS của card (hình như bạn đang làm như vậy, bạn nói chưa rõ).

Khi khởi động, card ở chế độ SD, do đó chân SDO của card là opendrain, bạn cần 1 con điện trở pull-up ở chân này, từ 10k-50k.
__________________
- Xin đọc trước khi post bài

Xin đặt code trong thẻ [ code ] [ /code ]
bien_van_khat vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 30-11-2009, 02:34 PM   #11
tahi
Đệ tử 4 túi
 
Tham gia ngày: Mar 2009
Bài gửi: 64
:
Cảm ơn bác đã giúp. Đoạn gửi ACMD41 đúng là em hơi sơ xuất, em chỉ loop mỗi gửi ACMD41, đáng nhẽ phải loop cả CMD55 và ACMD41
Trích:
Bạn ko nên dùng chân SS của SPI, dùng 1 chân IO bình thường để nối tới chân CS của card (hình như bạn đang làm như vậy, bạn nói chưa rõ).
Em gán cho 1 thằng I/O bình thường
Trích:
Khi khởi động, card ở chế độ SD, do đó chân SDO của card là opendrain, bạn cần 1 con điện trở pull-up ở chân này, từ 10k-50k.
Em ko có con trở pull-up nào. Đồng thời dính hiến tượng, cắm thẻ thì reset (sụt áp)

Khi send 6 byte lệnh, có delay giữa các byte hay ko hay là gửi liên tiếp,
Code:
unsigned char SD_WriteCommand(unsigned char* cmd)
{
	unsigned int i;
	unsigned char response;
	unsigned char savedSD_CS = SD_CS;	
	// SD Card Command Format
	// (from Section 5.2.1 of SanDisk SD Card Product Manual v1.9).
	// Frame 7 = 0
	// Frame 6 = 1
	// Command (6 bits)
	// Address (32 bits)
	// Frame 0 = 1

	// Set the framing bits correctly (never change)
	cmd[0] |= (1<<6);
	cmd[0] &= ~(1<<7);
	cmd[5] |= (1<<0);	
	// Send the 6 byte command
	SD_Enable();
	for(i = 0; i < 6; ++i)
	{
		SPIWrite(*cmd);
		Delay_Us(100);  //để 10 thì ăn, còn để 0 hoặc 100 là response về FF
		cmd++;
	}	
	// Wait for the response
	i = 0;
	do
	{
		response = SPIRead();
		if(i > 500) //If this value = 100, will recieved 0xFF with cmd17
		{
			break;
		}
		i++;
	} while(response == 0xFF);

	SD_Disable();

	// Following any command, the SD Card needs 8 clocks to finish up its work.
	// (from SanDisk SD Card Product Manual v1.9 section 5.1.8)
	SPIWrite(0xFF); 
	SD_CS = savedSD_CS;
	return(response);
}
tahi vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 30-11-2009, 03:28 PM   #12
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
:
Trích:
Nguyên văn bởi tahi View Post
Đồng thời dính hiến tượng, cắm thẻ thì reset (sụt áp)
Bạn phải kiểm tra chắc chắn là phần cứng đúng. Vì thẻ ngốn dòng nhiều nhất khi ghi, nhưng cũng không quá 100mA
Trích:
Khi send 6 byte lệnh, có delay giữa các byte hay ko hay là gửi liên tiếp,
Gửi liên tiếp ko delay, nhưng lần ghi sau cùng phải chờ tới khi module SPI xuất hết dữ liệu ra, tức là cờ ngắt bật thì mới được đưa chân CS về 1. Vì sau khi ghi vào thanh ghi SPIxBUF, cần tốn 1 thời gian tùy thuộc vào tốc độ baud thì dữ liệu mới ghi ra bus hết. Nếu bạn đưa chân CS về 1 ngay sau khi ghi SPIxBUF thì byte cuối cùng thẻ sẽ không nhận!


Và chú ý bạn phải gửi lệnh SET_BLOCK_LEN, đây là lệnh bắt buộc trong quá trình khởi tạo thẻ

Bạn muốn tự viết driver thẻ?
__________________
- Xin đọc trước khi post bài

Xin đặt code trong thẻ [ code ] [ /code ]

thay đổi nội dung bởi: bien_van_khat, 30-11-2009 lúc 05:05 PM.
bien_van_khat vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 30-11-2009, 09:25 PM   #13
tahi
Đệ tử 4 túi
 
Tham gia ngày: Mar 2009
Bài gửi: 64
:
Trích:
Và chú ý bạn phải gửi lệnh SET_BLOCK_LEN, đây là lệnh bắt buộc trong quá trình khởi tạo thẻ
Em đọc tài liệu thấy bảo là, block length =512 là default mà .
Trích:
Bạn muốn tự viết driver thẻ?
Đương nhiên là không rồi, e chỉ viết các hàm init cơ bản để test thôi. Em đã down mấy cái example về sử dụng MDD của microchip ko thấy nó hỗ trợ cho dòng 33F...Có cái thì bọn nó viết lại gần hết SD-SPI.c, cũng chẳng theo gì MDD. Còn có mấy cái project cho 30F thì ok...Bác có cái template nào viết cho dòng 33F ko, post lên cho em tham khảo với.
tahi vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 30-11-2009, 11:23 PM   #14
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
:
Trích:
Nguyên văn bởi tahi View Post
Em đọc tài liệu thấy bảo là, block length =512 là default mà .
Mình chưa kiểm tra kỹ vụ này.

Trích:
Đương nhiên là không rồi, e chỉ viết các hàm init cơ bản để test thôi. Em đã down mấy cái example về sử dụng MDD của microchip ko thấy nó hỗ trợ cho dòng 33F...Có cái thì bọn nó viết lại gần hết SD-SPI.c, cũng chẳng theo gì MDD. Còn có mấy cái project cho 30F thì ok...Bác có cái template nào viết cho dòng 33F ko, post lên cho em tham khảo với.
port giữa pic24, PIC33 và PIC32 rất dễ, vì các thanh ghi ngoại vi 3 dòng này giống nhau.


Mình nghĩ bạn dùng PIC33FJxxGP8xx, nếu vậy có lẽ chỉ cần thay file header và điều chỉnh lại các chân remap của SPI là xong!
__________________
- Xin đọc trước khi post bài

Xin đặt code trong thẻ [ code ] [ /code ]

thay đổi nội dung bởi: bien_van_khat, 30-11-2009 lúc 11:29 PM.
bien_van_khat vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 14-12-2009, 11:08 AM   #15
tahi
Đệ tử 4 túi
 
Tham gia ngày: Mar 2009
Bài gửi: 64
:
Em đã đọc được single block, nhưng em chưa hiểu lắm. Khi format thẻ với định dạng khác nhau thì đọc MBR có giống nhau không ? (theo em là có nhưng thực tế là đọc lần nào cũng như lần nào)

Em soi lại cại MDD file system, trong khi đợi data token.. (của lệnh CMD17 sau khi response = 0 thì đợi data token..) không thấy bọn nó cho chân SD_CS = 0;

Không thấy bọn nó switch speed sau khi init thẻ xong.
tahi 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à 02:51 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