ลำดับคำสั่งที่ถูกต้องสำหรับการเริ่มต้นการ์ด microSD ใน SPI คืออะไร


18

ฉันกำลังพยายามเชื่อมต่อการ์ด microSD (2 GB, Kingston, Sandisk) กับคอนโทรลเลอร์Silicon Labs C8051F931

ฉันสับสนมากเกี่ยวกับลำดับที่ฉันต้องปฏิบัติตามเพื่อเริ่มต้น ในหนังสือโครงการ SD Card โดยใช้ PIC Microcontrollerหน้า 135 กล่าวถึง:

ขั้นตอนในการเปลี่ยนการ์ด SD เป็นโหมด SPI จึงควรเป็นดังนี้:
เปิดเครื่อง
•ส่งสัญญาณนาฬิกาอย่างน้อย 74 ครั้งไปยังการ์ดที่มี CS และ Data Outlines ตั้งค่าเป็นลอจิก“ 1. ”
•ตั้งค่าสาย CD ต่ำ
•ส่งคำสั่ง CMD0 6 ไบต์“ 40 00 00 00 95 95” เพื่อวางการ์ดในโหมด SPI
•ตรวจสอบการตอบสนอง R1 เพื่อให้แน่ใจว่าไม่มีการตั้งค่าบิตข้อผิดพลาด
•ส่งคำสั่ง CMD1 ซ้ำ ๆ จนกระทั่งบิต“ in-idle-state” ในการตอบสนอง R1 ถูกตั้งค่าเป็น“ 0,”
•และไม่มีการตั้งค่าบิตข้อผิดพลาด ขณะนี้การ์ดพร้อมสำหรับการอ่าน / เขียน

ฉันลองสิ่งนี้ แต่ฉันได้รับ 01 แม้กระทั่งสำหรับ CDM1 00 คาดว่า

นอกจากนี้ที่นี่ฉันเห็นลำดับคำสั่งที่แตกต่างกันซึ่งเขาส่ง CMD8 หลังจาก CMD0 แต่หนังสือบอกว่าฉันต้องส่ง CMD1

ลำดับที่ถูกต้องคืออะไร?

คำตอบ:


34

ที่จริงแล้วข้อมูล / รหัสส่วนใหญ่ที่คุณอาจพบในการกำหนดค่าเริ่มต้นของ SD เป็นแบบลงวันที่หรือไม่มีความคมชัด กระบวนการนี้มีความซับซ้อนมากขึ้นทุกวันนี้เนื่องจากมันบังคับให้คุณต้องจัดการกับฮาร์ดแวร์เก่าด้วยวิธีที่เข้ากันได้แบบย้อนหลัง

ประการแรกตามที่ผู้อื่นกล่าวถึงให้เลือกอัตราสัญญาณนาฬิกาเริ่มต้นต่ำ (โดยทั่วไปอยู่ในช่วง 100 kHz - 400 kHz ใช้ 400 kHz หากเป็นไปได้); คุณจะสามารถเปลี่ยนเป็นนาฬิกาที่สูงขึ้นในภายหลังได้หากอุปกรณ์อนุญาต ในขณะที่การ์ดใหม่สามารถทนต่อการตอกบัตรแบบ MHz-ish ได้อย่างปลอดภัยผู้สูงอายุจะบ่น (เช่นไม่สื่อสารหรือคืนขยะ)

สิ่งต่อไปคือคุณไม่ควรใช้CMD1เพื่อเริ่มต้นการ์ด SD / SDHC / SDXC เว้นแต่ว่าการ์ดของคุณไม่รู้จักCMD55/ ACMD41; ตามที่ระบุในข้อกำหนดของการ์ด SD:

ไม่แนะนำให้ใช้ CMD1 ในกรณีใด ๆ เนื่องจากอาจเป็นเรื่องยากสำหรับโฮสต์ที่จะแยกแยะระหว่างการ์ดหน่วยความจำ MultiMediaCard และ SD

คอนโทรลเลอร์บางตัว (ส่วนใหญ่และใหม่กว่าการ์ดความจุสูง) จะอยู่ใน IDLE หากคุณออกการ์ดCMD1เหล่านั้น แรกที่คุณควรออกCMD8 0x1AAหลังจากที่การตั้งค่า ( CMD0) CMD55 + ACMD41แล้วพยายามที่จะใช้ และถ้าหากCMD1ที่ล้มเหลวในการใช้งาน

tl; drเพื่อเริ่มต้นการ์ดในโหมด SPI คุณควร:

  1. CMD0arg:, 0x0CRC: 0x95(response:) 0x01- โปรดทราบว่าในกรณีของ0xFFการตอบสนองหรืออ่านไม่ออกคุณควรทำซ้ำขั้นตอนนี้; ดูด้านล่างสำหรับข้อมูลเพิ่มเติม

  2. CMD8ARG:, 0x000001AACRC: 0x87(การตอบสนอง: 0x01ตามด้วย echo of arg ในกรณีนี้0x000001AA) - ในขณะที่มันอาจดูเหมือนว่าคำสั่งนี้เป็นทางเลือก แต่เป็นข้อบังคับสำหรับการ์ดรุ่นใหม่ทั้งหมด ในขณะที่0x1AAเป็นค่าหาเรื่องทั่วไปที่นี่คุณอาจส่งผ่านค่าอื่น ๆ เช่นกัน; โปรดดู "ตารางที่ 7-5: การทำงานของการ์ดสำหรับ CMD8 ในโหมด SPI", หน้า 108 ในสเป็คเพื่อดูรายละเอียด

    3a CMD55หาเรื่อง: 0x0ซีอาร์ซี: ใด ๆ0x65จริง (การตอบสนอง: 0x01; CMD55เป็นคำนำหน้าไปทุก ACMDถ้าตอบเป็น0x05คุณได้มีบัตรเก่า - ซ้ำCMD1กับหาเรื่อง0x0[CRC 0xF9] แทนCMD55/ ACMD41)

    3b ACMD41, arg:, 0x40000000CRC: any, 0x77อันที่จริง (โปรดสังเกตว่าอาร์กิวเมนต์นี้ถือว่าการ์ดเป็นหนึ่งใน HCS ซึ่งมักจะเป็นกรณีนั้นใช้0x0arg [CRC 0xE5] สำหรับการ์ดรุ่นเก่า) หากการตอบสนองคือ0x0คุณตกลง ถ้าเป็น0x01เช่นนั้นไป 3a; หากเป็น0x05เช่นนั้นให้ดูหมายเหตุด้านบน (ใน 3a.) ถ้าไม่ใช่ก็มีบางอย่างผิดปกติ (ดูด้านล่าง)

การ์ดส่วนใหญ่ต้องการขั้นตอน 3a / 3b (หรือCMD1การ์ดเก่า) ที่จะทำซ้ำโดยปกติอย่างน้อยหนึ่งครั้งแม้ว่าคุณจะรอสักครู่ระหว่างพวกเขาก็ตาม นั่นคือลำดับที่แท้จริงคือCMD0/ CMD8/ CMD55/ ACMD41/ CMD55/ ACMD41(หรือCMD0/ CMD8/ CMD1/ CMD1) - เพื่อให้แน่ใจว่าลองCMD55/ ACMD41(หรือCMD1ถ้าคุณได้รับ0x05จากพวกเขา)ครั้ง (เลือกภายในเหตุผลของคุณมันเป็นเรื่องธรรมดาที่จะต้องรอ สองสามร้อย ms หากอุปกรณ์เพิ่งเปิดเครื่องดังนั้นให้ตั้งเป้าหมายไว้) โดยมีความล่าช้าเล็กน้อยระหว่างการลองหากคุณต้องการและถือว่าล้มเหลวหากตอบสนองnn0ไม่ปรากฏขึ้น (เช่นหากอุปกรณ์อยู่ในโหมด IDLE ด้วยเหตุผลบางประการ) นอกจากนี้การได้รับ0xFFจากCMD0เป็นเรื่องปกติถ้าอุปกรณ์อยู่ในสถานะ "แปลก" บางอย่างก่อนหน้านี้ (เช่นวางสายรับ S̲S̲ deasserted [สูง], มี - / undervoltage บนพินเป็นต้น) - ให้เวลาซักล้างและทำซ้ำครั้ง การตอบสนองที่อ่านไม่ออกจะค่อนข้างตกลงบางครั้ง - ถ้าคุณส่งมาสองสามครั้งและการตอบสนองยังคงเป็นค่ามิได้พยายามที่จะก้าวไปข้างหน้าด้วย ถ้ามันใช้ได้ - คุณสบายดี ถ้ามันไม่ได้ - มันอาจจะเสียnCMD00xFF0x01CMD8

โปรดทราบว่าการตอบสนองที่มีการตั้งค่า MSB แต่0xFFโดยปกติแล้วจะไม่แนะนำให้ SPI ของคุณมีการเปลี่ยนแปลงการตอกบัตร (ซึ่งเป็นผลมาจากการปล่อย Vcc เช่นซึ่งเกิดขึ้นเป็นประจำเมื่อคุณทำ SD hotplugs) ในการแก้ไขปัญหาคุณสามารถลองรีเซ็ตอุปกรณ์ได้อย่างสมบูรณ์ (เปิด / ปิด, ยืนยัน / ยืนยัน S̲S̲ ฯลฯ ); มันใช้งานได้ปกติ

นอกจากนี้สเป็คบอกว่า

หลังจากการทำธุรกรรมบัสการ์ดหน่วยความจำ SD ครั้งสุดท้ายจำเป็นต้องมีโฮสต์เพื่อให้วงจรนาฬิกา 8 (แปด) ครั้งสำหรับการ์ดเพื่อให้การดำเนินการเสร็จสมบูรณ์ก่อนที่จะปิดนาฬิกา

มันสามารถทำงานได้โดยปราศจากมัน แต่ตั้งแต่ 8 รอบ = 1 ไบต์ SPI เอาท์พุทมันจะไม่เจ็บมากและเป็นการดีที่มี

โปรดทราบว่าคุณควรยืนยัน S̲S̲ (aka CS) ต่ำอย่างน้อยก่อนและหลังแต่ละอันCMD- มันเป็นข้อบังคับอย่างสมบูรณ์ในกรณีที่CMD0(อุปกรณ์จะไม่เปิดโดยไม่มี) และในความเป็นจริงจำเป็นสำหรับคนอื่น ๆ ทุกคนCMDหากคุณมีมาตรฐาน - รองรับการ์ด SD อาจดูเหมือนการเชื่อมต่อ S̲S̲ ของการ์ดกับ GND อย่างถาวรจะเป็นความคิดที่ดีถ้าการ์ดเป็นไคลเอนต์ SPI เดียวที่โฮสต์ของคุณจะเชื่อมต่อเพราะจะช่วยให้คุณทั้งขาออกของ uC และจำเป็นต้องจัดการมันด้วยรหัสเลยและเพราะการ์ดควรถือว่ามันเลือกทั้งหมด ของเวลา ในความเป็นจริงการ์ดบางใบ (ถ้าไม่ใช่ส่วนใหญ่) คาดว่าจะมีความลาดชันสูง - ต่ำ - จะเปิดแทนการตรวจจับที่ต่ำและทำให้โกรธถ้าคุณไม่สลับบิต S̲S̲ เลย นาฬิกาหรือน้ำลายขยะ การ์ดบางอัน (โดยปกติใหม่กว่า) ควรใช้งานได้บางการ์ด (เก่ากว่า) อาจไม่ทำงาน YMMV (ยังอีกครั้ง) อย่างไรก็ตามสำหรับการกำหนดค่า SPI ที่มีประสิทธิภาพยิ่งขึ้น (> อุปกรณ์ทาส 1) โปรดจำไว้ว่าต้องพินต่ำก่อนที่จะทำธุรกรรมจริงด้วยการ์ด SD ที่กำหนด

นอกจากนี้ในขณะที่สเป็คบอกว่ามีเพียงCMD0และCMD8ควรมี CRC ในโหมด SPI การ์ด SD บางอัน (เช่น Transcend)จะต้องใช้ CRC ที่เหมาะสมสำหรับCMD55/ ACMD41- หากคุณต้องการอยู่ในด้านที่ปลอดภัยเพียงแค่ใช้ค่าที่ประเมินไว้ล่วงหน้าสำหรับพวกเขา

นอกจากนี้ในขณะที่ SPI ไม่ต้องการ pullups / down ด้วยตัวเองการโยน pullup 47k บน MISO อาจเป็นความคิดที่ดี อุปกรณ์บางอย่างปล่อยให้ทำ pin high-Z ของพวกเขาภายใต้สถานการณ์ที่เฉพาะเจาะจง (ไม่ได้เริ่มต้นเช่น) และหมุดลอยสามารถเป็นแหล่งที่มาของปัญหาที่แปลก หาก uC ของคุณมี 3.3 Vcc คุณสามารถใช้ pullups ภายในได้ ถ้าเป็น 5V อย่าทำอย่างนั้นเว้นแต่ว่าสาย MISO ของคุณจะมีการแปลเชิงตรรกะที่เหมาะสม 5-> 3.3V แล้ว

อ่านเพิ่มเติม:

วิธีการใช้ MMC / SDC

ข้อมูลจำเพาะของ SD ส่วนที่ 1 ข้อมูลจำเพาะแบบง่ายของเลเยอร์ทางกายภาพแบบง่าย - ส่วนที่สำคัญที่สุด6.4.1 การเปิดปิดและการเลือกโหมด7.2.1และการกำหนดค่าเริ่มต้นด้วยรูปที่ 7-1 : แผนภาพสถานะการ์ดหน่วยความจำ SD (โหมด SPI)


4

รายละเอียดสำหรับ SD การ์ดที่มีอยู่บนsdcard.org เวอร์ชั่นที่เรียบง่ายออกมาจากรายละเอียดบางอย่าง แต่คุณควรดูตัวอย่างที่รูปที่ 7-2 ในส่วนที่ 1 ซึ่งมีการอธิบายลำดับการเริ่มต้นสำหรับการ์ด SDHC และ SD

การ์ด MicroSD <= 2 GB สามารถทำงานได้เช่นบัตรเก่าเพื่อให้พวกเขาควรให้0x00ส่งผลสำหรับในที่สุดCMD1 อาจต้องลองใหม่มากกว่าสองสามครั้งเนื่องจากการ์ดสามารถใช้นาฬิกาภายนอกจากบัส SPI เพื่อขับเคลื่อนการประมวลผลภายใน


2

การเพิ่มคำตอบที่ยอดเยี่ยม @vaxquis ฉันต้องการอ้างอิงแผนภูมิที่สอดคล้องกันจาก " Physical Layer Simplified Specification Version 4.10 , ©ลิขสิทธิ์ 2001-2013 กลุ่ม SD (Panasonic, SanDisk, Toshiba) และ SD Card Association" (รูปที่ 7-2 : ขั้นตอนการเริ่มต้นโหมด SPI):

ลำดับ SD SPI เริ่มต้นของการ์ด SD

ที่นี่คุณสามารถดูคำสั่งที่จะส่งลำดับและคำตอบที่บอกเราเกี่ยวกับประเภทของการ์ด ฉันคิดว่ามันเป็นที่พึงปรารถนาที่อุปกรณ์รองรับการ์ดได้มากที่สุด และตราบใดที่การดำเนินการพื้นฐานของการอ่านและการเขียนบล็อกมีขนาด 512 ไบต์นั้นควรจะทำได้อย่างน้อยการ์ด V1.x และ V2.0 SD และ HC ทั้งหมด


2

ฉันเสนอสิ่งนี้ให้เป็นไปได้อีกอย่าง .. ในโหมด SPI, Samsung MicroSD EVO 32GB ต้องการรหัสคำสั่งทั้งหมดเพื่อให้มีรหัส CRC ที่ถูกต้อง ฉันเดิมพันพวกเขาไม่ใช่คนเดียว ฉันอ่านความคิดเห็นที่บุคคลนั้นเชื่อว่าการ์ดทั้งหมดที่สูงกว่า 32GB อาจเป็นเช่นนั้น ฉันได้ทำการแก้ไขข้อบกพร่องมานานกว่าหนึ่งสัปดาห์แล้ว รหัสของฉันจะไม่ทำงานจนกว่ารหัสทั้งหมดที่ส่งไปยังการ์ดจะมีรหัส CRC ที่ถูกต้อง ฉันใช้สิ่งนี้เพื่อคำนวณรหัส CRC ทั้งหมด https://github.com/hazelnusse/crc7/blob/master/crc7.cc ฉันได้ลองใช้คำสั่ง 59 เพื่อปิดรหัส CRC ไม่ใช่ ฉันหวังว่านี่จะช่วยคนอื่นประหยัดเวลาและความพยายาม

รหัสการเริ่มต้นของฉันด้วยค่า CRC ..

Power On..
Clock card at least 74 (I use 80) cycles with cs high
CMD0 0, crc=0x95
CMD8 0x01aa, crc=0x87
CMD58 0, crc=0xfd
CMD55 0, crc=0x65
CMD41 0x40000000, crc=0x77
CMD9 0, crc=0xaf
CMD16, 512, crc=0x81 (If you want block length of 512)

Some random other commands..
CMD17 0, crc=0x3b (Read one block)
CMD18 0, crc=0x57 (Read multiple blocks)
CMD24 0, crc=0x6f (set write address for single block)
CMD25 0, crc=0x03 (set write address for first block)

-2

คุณแน่ใจหรือว่าบัส SPI ของคุณอยู่ที่ 400 kHz? การเริ่มต้นจะต้องเกิดขึ้นกับบัส SPI ที่ทำงานที่ 400 kHz จนกว่า SD การ์ดจะรายงานว่าอยู่ในสถานะไม่ได้ใช้งานซึ่งอัตรานาฬิกาบัส SPI อาจเพิ่มขึ้น (ค่าสูงสุดที่แน่นอนดูเหมือนจะแตกต่างจากผู้ผลิตถึงผู้ผลิต แต่ดูเหมือนว่า 12 MHz เป็นเดิมพันที่ปลอดภัยสำหรับการ์ดส่วนใหญ่)

นอกจากนี้ตามนี้: http://elm-chan.org/docs/mmc/mmc_e.html CMD1 คือการเริ่มต้นที่เหมาะสม CMD8 นั้นจำเป็นสำหรับการค้นหาช่วงแรงดันไฟฟ้าเท่านั้นซึ่งไม่น่าจะมีปัญหากับการ์ดที่ไม่ใช่ SDHC (<= 2GB)


ที่จริงแล้วการ์ด SD จำนวนมาก (ส่วนใหญ่เป็นรุ่นที่ใหม่กว่า, Sony SR-32C4 32GB ของฉันเป็นการ์ดเดียว) จะไม่เริ่มเลยถ้าไม่CMD8ได้ออกมาก่อน นอกจากนี้นาฬิกามักไม่เป็นปัญหาตราบใดที่ยังอยู่ในระยะที่เหมาะสม
vaxquis

-3

อาจจะสายเกินไป แต่การตอบสนองจากการ์ดก็โอเค! หลังจาก CMD0 การตอบสนองต้องเป็น 0x01 ซึ่งหมายความว่าการ์ดนั้นอยู่ในสถานะ IDLE และพร้อมสำหรับการทำงาน หากคุณมีบางอย่างเช่น 0b00000101 อันดับ 1 ในตำแหน่งที่ 2 บอกว่านี่เป็นคำสั่งที่ผิดกฎหมายและที่ 1 ในตำแหน่ง 0 บอกว่า sard IS ยังอยู่ในสถานะ IDLE และพร้อมสำหรับการทำงาน หากการตอบสนองเป็น 0x00 หมายความว่าการ์ดนั้นไม่ได้อยู่ในสถานะ IDLE และคุณต้องส่งคำสั่ง RESET อีกอัน


คุณอ่านคำถามทั้งหมดหรือไม่ OP กล่าวอย่างชัดเจนI tried this, but I am getting 01 even for CDM1- รับ IDLE ในการตอบสนองCMD1ในไม่ตกลง คุณไม่ได้ระบุปัญหาที่แท้จริงของเขาด้วย "คำตอบ" ของคุณ
vaxquis
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.