ที่จริงแล้วข้อมูล / รหัสส่วนใหญ่ที่คุณอาจพบในการกำหนดค่าเริ่มต้นของ 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 คุณควร:
CMD0arg:, 0x0CRC: 0x95(response:) 0x01- โปรดทราบว่าในกรณีของ0xFFการตอบสนองหรืออ่านไม่ออกคุณควรทำซ้ำขั้นตอนนี้; ดูด้านล่างสำหรับข้อมูลเพิ่มเติม
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)
CMD8ได้ออกมาก่อน นอกจากนี้นาฬิกามักไม่เป็นปัญหาตราบใดที่ยังอยู่ในระยะที่เหมาะสม