کار با کارت SD اتصال به میکروکنترلر. قسمت 1. اتصال کارت SD به میکروکنترلر اتصال کارت های sd mmc به میکروکنترلر

روز همگی بخیر! امروز در مورد آن صحبت خواهیم کرد اتصال کارت حافظه SDبه میکروکنترلر STM32.

به نظر می رسد که کنترلرهای STM32F10x حافظه زیادی دارند، چرا بیشتر وجود دارد، اما این تصور فریبنده است) به عنوان مثال، ما باید چند عدد را نمایش دهیم. تصاویر مختلف– فرمت 320*240 – یعنی 76800 پیکسل که هر کدام معادل 2 بایت است. بنابراین ما حدود 150 کیلوبایت در هر تصویر دریافت می کنیم. و این با استانداردهای یک میکروکنترلر بسیار زیاد است، و این یک واقعیت نیست که بتوان دو تصویر مختلف را در حافظه فلش آن قرار داد. یا اینکه برای مثال نیاز به ذخیره حجم زیادی از اطلاعات، داده های برخی از سنسورها داریم. علاوه بر این، به طوری که این داده ها حتی پس از خاموش شدن برق در دسترس هستند. اینجاست که برای ما مفید خواهد بود حافظه خارجی. و یک راه حل عالی خواهد بود کارت حافظه SDیا MMC. به هر حال، در این مقاله آزمایشاتی را در مورد انجام خواهیم داد کارت میکرو SD.

ابتدا چند کلمه در مورد خود کارت حافظه یا به طور دقیق تر در مورد pinout آن. کل ماجرا به این شکل است:

بنابراین ما اینجا چی داریم؟ خوب، بلافاصله مشخص می شود که هشت پین دارد. تخصیص پین ها به شرح زیر است (از چپ به راست):


ستون SPI Mode به ما اشاره می کند که با استفاده از رابط SPI با میکروکنترلر تعامل دارد. ولی! ما مسیر متفاوتی را در پیش خواهیم گرفت 😉 نکته اینجاست که STM32 یک ماژول جانبی آماده برای کار با کارت های حافظه روی خود دارد که SDIO نام دارد.

به طور کلی، تعامل با کارت های حافظه شامل ارسال دستورات خاصی است. برخی از دستورات نیاز به استدلال دارند، برخی نه. دستورات را می توان در اسناد رسمی برای یک کارت خاص یافت. بنابراین، ماژول داخلی SDIO این امکان را به شما می دهد که فرآیند انتقال دستورات و در واقع فرآیند کار با کارت های خارجیحافظه به عنوان مثال، اینجا ثبت نام است SDIO_CMD- در آنجا به سادگی کد دستوری را که می خواهیم به کارت منتقل کنیم، یادداشت می کنیم. یا اینجا ثبت وضعیت است SDIO_STA- برای هر عطسه 24 پرچم وجود دارد، یعنی برای تعداد زیادی رویداد.

به هر حال، STM همچنین از مستندات خوب در مورد این موضوع خشنود است. در اینجا، برای مثال، توصیف همراه با جزئیاتمقداردهی اولیه برای کارت حافظه SD (همه چیز به طور مشابه برای انواع دیگر کارت ها توضیح داده شده است):

خوب، در واقع، زمان آن رسیده که به یک مثال عملی برویم. بیایید کتابخانه محیطی استاندارد را بررسی کنیم.

در پرونده stm32f10x_sdio.hبه طور سنتی، ساختارهایی را برای انواع تنظیمات پیدا می کنیم - یعنی برای انتخاب منبع سیگنال ساعت، فرکانس کنترل کننده SDIO و تنظیم تعداد بایت های منتقل شده. همه چیز در آنجا آنقدر سخاوتمندانه در مورد آن نظر داده شده است که من حتی نمی خواهم آن را جداگانه تکرار کنم)) فقط نگاه کنید:

ساختار typedef (uint32_t SDIO_ClockEdge; /* انتقال ساعتی را مشخص می کند که بر روی آن ضبط بیت انجام می شود. این پارامتر می تواند مقدار @ref SDIO_Clock_Edge */ باشد uint32_t SDIO_ClockBypass. /* مشخص می کند که آیا دور زدن تقسیم کننده ساعت SDIO فعال یا غیرفعال باشد. این پارامتر می تواند مقدار @ref SDIO_Clock_Bypass */ باشد uint32_t SDIO_ClockPowerSave. /* مشخص می کند که خروجی SDIO Clock زمانی که گذرگاه بیکار است فعال یا غیرفعال شود. این پارامتر می تواند مقدار @ref SDIO_Clock_Power_Save */ باشد uint32_t SDIO_BusWide; /* عرض گذرگاه SDIO را مشخص می کند. این پارامتر می تواند مقدار @ref SDIO_Bus_Wide */ باشد uint32_t SDIO_HardwareFlowControl; /* مشخص می کند که آیا کنترل جریان سخت افزاری SDIO فعال یا غیرفعال باشد. این پارامتر می تواند مقدار @ref SDIO_Hardware_Flow_Control */ باشد uint8_t SDIO_ClockDiv; /* فرکانس ساعت کنترلر SDIO را مشخص می کند. این پارامتر می تواند مقداری بین 0x00 و 0xFF باشد. */) SDIO_InitTypeDef; ساختار typedef (uint32_t SDIO_Argument; /* آرگومان فرمان SDIO را مشخص می کند که به عنوان بخشی از پیام فرمان به کارت ارسال می شود. اگر دستوری حاوی آرگومان باشد، باید قبل از نوشتن دستور در ثبات فرمان در این ثبات بارگذاری شود */ uint32_t SDIO_CmdIndex; /* نمایه فرمان SDIO را مشخص می کند. باید کمتر از 0x40 باشد. */ uint32_t SDIO_Response. /* نوع پاسخ SDIO را مشخص می کند. این پارامتر می تواند مقدار @ref SDIO_Response_Type */ باشد uint32_t SDIO_Wait; /* مشخص می کند که درخواست انتظار برای وقفه SDIO فعال یا غیرفعال باشد. این پارامتر می تواند مقدار @ref SDIO_Wait_Interrupt_State */ باشد uint32_t SDIO_CPSM; /* مشخص می کند که دستگاه وضعیت مسیر فرمان SDIO (CPSM) فعال یا غیرفعال باشد. این پارامتر می تواند مقدار @ref SDIO_CPSM_State */ باشد) SDIO_CmdInitTypeDef; ساختار typedef (uint32_t SDIO_DataTimeOut; /* مدت زمان پایان داده را در دوره های ساعت اتوبوس کارت مشخص می کند. */ uint32_t SDIO_DataLength; /* تعداد بایت های داده ای که باید منتقل شوند را مشخص می کند. */ uint32_t SDIO_DataBlockSize; /* اندازه بلوک داده را برای انتقال بلوک مشخص می کند. این پارامتر می تواند مقدار @ref SDIO_Data_Block_Size */ باشد uint32_t SDIO_TransferDir; /* جهت انتقال داده را مشخص می کند، خواه این انتقال خواندن یا نوشتن باشد. این پارامتر می تواند مقدار @ref SDIO_Transfer_Direction */ باشد uint32_t SDIO_TransferMode. /* مشخص می کند که انتقال داده در حالت استریم یا بلوک باشد. این پارامتر می تواند مقدار @ref SDIO_Transfer_Type */ باشد uint32_t SDIO_DPSM; /* مشخص می کند که دستگاه وضعیت مسیر داده SDIO (DPSM) فعال یا غیرفعال باشد. این پارامتر می تواند مقدار @ref SDIO_DPSM_State */ باشد) SDIO_DataInitTypeDef;

بیایید توجه کنیم که SPL چگونه انتقال دستورات را به کارت حافظه اجرا می کند. ساختار جداگانه ای برای این اهداف اختصاص داده شده است. SDIO_CmdInitTypeDef.در زمینه SDIO_CmdIndexکد دستوری را در فیلد وارد کنید SDIO_Argument– آرگومان فرمان، فیلدهای باقیمانده را نیز پر کنید. تنها چیزی که باقی می ماند این است که به نحوی این داده ها را در خود جای دهیم کارت میکرو SD 😉 و برای این یک تابع برای ما آماده کردند:

SDIO_SendCommand (SDIO_CmdInitTypeDef *SDIO_CmdInitStruct)

به عنوان یک استدلال، ساختاری که ایجاد کردیم به آن منتقل می کنیم. برای ثبت داده ها یک تابع وجود دارد - SDIO_WriteData(Uint32_t Data). پس از فراخوانی این تابع، داده ها در یک ثبات که مخصوص این منظور طراحی شده است قرار می گیرند - SDIO_FIFO.

این نحوه کار با ماژول SDIO در STM32F10x است)

حالا بیایید در نهایت به سراغ تمرین برویم. من دوباره با آن کار خواهم کرد مینی برد STM32، زیرا چینی های خوب با نصب یک اسلات برای کارت حافظه micro SD روی آن متحیر شدند. در اینجا یک نمودار از اتصال کانکتور کارت به میکروکنترلر آمده است:

برای نوشتن برنامه ای که استفاده خواهیم کرد نمونه آمادهبرای Keil - بیایید دو فایل از آنجا بگیریم که در آنها چیزی شبیه درایور کار با کارت ها پیاده سازی شده است - اینها فایل ها هستند sdcard.cو sdcard.h.ما ایجاد می کنیم پروژه جدیداین فایل ها را در آنجا ضمیمه می کنیم و البته علاوه بر آن فایل های CMSIS و SPL. در اینجا پروژه تمام شده است که در آن همه چیز قبلاً اضافه شده است - تنها چیزی که باقی می ماند نوشتن کد برای تابع main () است.

فایل sdcard.c انواع توابع را برای کار با کارت حافظه پیاده سازی می کند، اکنون تنها کاری که باید انجام دهیم این است که از آنها استفاده کنیم 😉 بیایید کد را بنویسیم! به عنوان مثال، بیایید 512 بایت داده آزمایشی را در micro SD بنویسیم و سپس سعی کنیم آنها را بخوانیم:

// فایل های لازم را پیوند دهید#include "stm32f10x.h" #include "sdcard.h" /*******************************************************************/ // آرایه های داده های ورودی و خروجی و متغیری برای ذخیره داده ها// درباره کارت ما uint8_t writeBuffer[ 512 ] ; uint8_t readBuffer[ 512] ; SD_CardInfo SDCardInfo; /*******************************************************************/ int main() ( // داده ها را برای نوشتن آزمایش کنیدبرای (uint16_t i = 0 ; i< 512 ; i++ ) { writeBuffer[ i] = i % 256 ; readBuffer[ i] = 0 ; } // نقشه را مقدار دهی اولیه کنید SD_Init(); // اطلاعات مربوط به کارت را دریافت کنید SD_GetCardInfo(& SDCardInfo) ; // انتخاب کارت و تنظیم حالت کار SD_SelectDeselect((uint32_t ) (SDCardInfo.RCA<< 16 ) ) ; SD_SetDeviceMode(SD_POLLING_MODE) ; // و بالاخره نوشتن و خواندن SD_WriteBlock(0x00، writeBuffer، 512); SD_ReadBlock(0x00، readBuffer، 512); در حالی که (1) ( ) /*******************************************************************/

لطفاً توجه داشته باشید که کارت SD از ضبط در بلوک های 512 بایتی پشتیبانی می کند.

اگر برنامه را تحت دیباگر اجرا کنیم، می بینیم که داده های خوانده شده با داده های نوشته شده مطابقت دارد =) بنابراین می توانیم آزمایش را موفقیت آمیز بدانیم. برای امروز تمام شد، به زودی می بینمت!

  • آندریاس می گوید:

    اگر هدف پین های عملکردی یک کارت حافظه خاص را بدانید، مونتاژ یک آداپتور Memory Stick با دستان خود دشوار نیست. معمولاً پین اوت کارت حافظه یا مثلاً ریزمدار، تراشه و غیره نامیده می شود. به طور کلی، تکنولوژی ساده است. طرح کارت حافظه MMC (کارت چند رسانه ای) از PCB بریده شده است. 7 آهنگ روی تخته نان بریده شده است (MMC دارای 7 پین است). سپس مطابق با پین‌آوت که در شکل زیر نشان داده شده است، تراک‌ها به پین‌های کارت حافظه SD (دارای 9 پایه که 2 پایه آن استفاده نمی‌شود)، میکرو اس‌دی (دارای 8 پایه، که 2 پایه آن نیز نیست، لحیم می‌شوند. استفاده شده است، اما توجه داشته باشید که حافظه کارت حافظه microSD خروجی Vcc ندارد) یا microM2 (پینوت microM2 در مبحث مرتبط Memory Stick Micro M2 Adapter). همین. آداپتور Memory Stick آماده است.

    P.S. ما کارت حافظه 1 و 2 گیگابایتی MMC را در انبار داریم. هزینه به ترتیب 285 و 360 روبل است. تحویل در قیمت درج شده است.

    همچنین می توانید کارت های حافظه در اندازه های زیر را ارزان خریداری کنید:
    - Memory Stick و Memory Stick M2;
    - دیجیتال امن (SD)؛
    - Mini SD؛
    - میکرو SD (TF)؛
    - فلش فشرده؛
    -XD؛
    - درایوهای فلش USB با طرح ها و ظرفیت های مختلف.
    مثلاً اینها:

  • اسلاوا می گوید:

    اتفاقا من در این نوشته ها خیلی واضح نیستم. نمی‌توانید آهنگ‌ها را از MicroCD به MMC در آن صفحه دریافت کنید، بسیار سپاسگزار خواهم بود.

  • آندریاس می گوید:

    آداپتور microSD به MMC اینگونه خواهد بود:

  • اسلاوا می گوید:
  • همانطور که از شکل مشخص است، پس از ارسال فریم فرمان، لازم است خواندن بایت ها (Ncr) از microSD تا دریافت پاسخ (R1) ادامه یابد، در حالی که سطح CS باید "0" فعال باشد.

    بسته به شاخص فرمان، پاسخ ممکن است نه تنها باشد R1(به مجموعه دستورات اساسی مراجعه کنید) در پاسخ CMD58 R3(R1 و مقدار OCR پایانی 32 بیتی)، و برخی از دستورات به زمان NCR بیشتری نیاز دارند و پاسخ خواهند داد. R1b. این پاسخ R1 است و به دنبال آن یک پرچم مشغول است (سیگنال روی خط "DO" در حالی که فرآیند داخلی ادامه دارد توسط کارت پایین نگه داشته می شود). کنترل‌کننده میزبان باید صبر کند تا فرآیند تکمیل شود تا زمانی که "DO" بالا برود (یعنی منتظر 0xFF باشد). و همچنین R2 هنگام درخواست وضعیت ثبت STATUS.

    پاسخ R1 شامل 1 بایت است که ساختار آن در جدول زیر قابل مشاهده است. پاسخ R2 از دو بایت تشکیل شده است، بایت اول R1 و دومی R2 است (جدول ساختار R2 را ببینید). و پاسخ R3 به ترتیب 5 بایت است.


    پاسخ R1 با مقدار 0x00یعنی دستور با موفقیت انجام شد، در غیر این صورت پرچم مربوطه تنظیم می شود.

    ساختار پاسخ R1.


    ساختار پاسخ R2


    مقداردهی اولیه در حالت SPI.

    پس از تنظیم مجدد و منبع تغذیه، کارت به طور پیش فرض با استفاده از پروتکل MMC (رابط محیطی سریال) روی حالت کار تنظیم می شود؛ برای تغییر به حالت SPI، باید موارد زیر را انجام دهید:

    1. پس از رسیدن به 2.2 ولت، حداقل یک میلی ثانیه صبر کنید، خطوط DI و CS را بالا تنظیم کنید و حدود 80 پالس به پین ​​CLK صادر کنید. پس از این رویه، کارت آماده پذیرش تیم میزبان خواهد بود.
    2. دستور CMD0 (نرم بازنشانی) را ارسال کنید. کارت باید (R1) با تنظیم بیت انتظار (0x01) پاسخ دهد.
    3. دستور CMD1 را ارسال کنید (برای شروع اولیه کارت). منتظر پاسخ 0x00 برای تایید تکمیل فرآیند باشیدمقداردهی اولیه.

    به شما یادآوری می کنم که دستور CMD0 باید حاوی فیلد CRC صحیح باشد. محاسبه هیچ فایده ای ندارد، زیرا هیچ آرگومانی در این دستور وجود ندارد، بنابراین ثابت است و مقدار آن 0x95 است. هنگامی که کارت وارد حالت SPI می شود، عملکرد CRC غیرفعال می شود و بررسی نمی شود. گزینه CRC را می توان با CMD59 دوباره فعال کرد.

    در نتیجه، دستور CMD0 به این شکل خواهد بود: 0x40.0x00.0x00.0x00.0x00.0x95.

    • شاخص تیم - 0x40.
    • آرگومان - 0x00.0x00.0x00.0x00.
    • CRC-0x95.

    در مورد 80 پالس، می توان آنها را با انتقال مقدار 0xFF از طریق SPI تولید کرد.10 بار متوالیدر سطوح بالا تنظیم شده بر روی خطوط DI و CS.

    کارت حافظه پس از بیش از 5 میلی ثانیه بیکار ماندن، به حالت صرفه جویی در مصرف انرژی می رود و تنها قادر به پذیرش دستورات CMD0، CMD1 و CMD58 است. بنابراین، فرآیند اولیه سازی (CMD1) باید تقریباً هر بار در هنگام خواندن/نوشتن بلوک داده یا بررسی وضعیت کارت تکرار شود.

    برای کارت های SDC اگر دستور رد شودCMD1 برای استفاده از دستور ACMD41 توصیه می شود.

    فرآیند اولیه سازی خود می تواند زمان نسبتاً طولانی (بسته به اندازه کارت) طول بکشد و به صدها میلی ثانیه برسد.

    خواندن و نوشتن یک بلوک داده

    به طور پیش فرض، در حالت SPI، تبادل بین میکروکنترلر و کارت در بلوک های 512 بایتی انجام می شود، بنابراین برای نوشتن حتی یک بایت، ابتدا باید کل بلوک را بخوانید و با تغییر بایت، آن را دوباره بنویسید. اندازه بلوک را می توان در رجیستر CSD کارت حافظه تغییر داد.

    برای جلوگیری از آدرس دهی خطا هنگام اجرای دستورات خواندن/نوشتن، لازم است که آدرس به وضوح در ابتدای بخش مشخص شود. برای انجام این کار، می توانید بیت "0" 3 بایت آدرس بخش را بازنشانی کنید. آن را یکنواخت کنید، و فرعی باید همیشه مقدار 0x00 را داشته باشد.

    خواندن بلوک داده

    الگوریتم خواندن بلوک داده به شرح زیر است:

    • پس از تایید مقداردهی اولیه، دستور CMD17 (پاسخ R1) را با آدرس سکتور مورد نیاز ارسال می کنیم.
    • ما 0xFF را قبل از دریافت بایت شروع 0xFE ارسال می کنیم.
    • ما یک بلوک داده (512 بایت به طور پیش فرض) و 2 بایت CRC را می پذیریم.

    مقدار CRC مورد نیاز نیست، اما روش پذیرش (انتقال 0xFF از MK) ضروری است.

    بلوک خواندن


    یک بلوک از داده بنویسید.

    الگوریتم نوشتن بلوک داده به صورت زیر است:

    • اگر کارت بیش از 5 میلی ثانیه بیکار بود، دستور CMD1 را ارسال کنید (پاسخ R1).
    • پس از تایید مقداردهی اولیه، دستور CMD24 (پاسخ R1) را با آدرس سکتور مورد نیاز ارسال می کنیم.
    • ما بایت شروع را 0xFE ارسال می کنیم.
    • ما یک بلوک داده (512 بایت به طور پیش فرض) و 2 بایت CRC را ارسال می کنیم.
    • ما بایت تایید نوشتن را دریافت می کنیم.
    • ما منتظر پایان ضبط هستیم (تغییر بایت 0x00).

    هنگام تغییر طول بلوک با دستور CMD16، بلوک داده می تواند کوچکتر از 512 بایت باشد.

    مقدار CRC مورد نیاز نیست، اما روند عبور هر مقدار لازم است.

    شما نمی توانید ارزیابی زمان خرابی را به صورت برنامه ای انجام دهید، اما بلافاصله یک دستور اولیه را صادر کنید. در حین اجرای نرم افزار با یک ضبط نادرست مواجه شدم، به دلایلی همه بایت ها در یک بخش به سمت چپ نوشته شدند. مشکل فقط با دوبار ارسال بیت شروع (0xFE) حل شد.

    ضبط را مسدود کنید.


    بایت تایید هنگام نوشتن یک بلوک داده.


    چندین بلوک را پشت سر هم بنویسید/بخوانید.

    با استفاده از دستورات CMD18, CMD25شما می توانید چندین بلوک را پشت سر هم بخوانید یا بنویسید یا به اصطلاح خواندن/نوشتن چند بلوکی. اگر تعداد بلوک‌ها مشخص نشده باشد، می‌توان فرآیند خواندن/نوشتن را با استفاده از دستورات CMD12 در حین خواندن و همچنین با عبور از " متوقف کرد. ترن را متوقف کنید" هنگام ضبط بر این اساس.

    استفاده عملی.

    کاربرد عملی کارت های حافظه بسیار گسترده است. او در آخرین طراحی خود، از microSD برای ضبط قرائت از سنسورهای مختلف (دما، زنگ هشدار) در طول روز در هر ساعت استفاده کرد. داده ها به صورت زیر ذخیره می شوند:

    • سال از دو رقم آخر گرفته شده است - این با بایت اول (اصلی) آدرس بخش کارت حافظه مطابقت دارد.
    • ماه، دو رقم - این مربوط به دومین و مهم ترین بایت آدرس بخش کارت حافظه است.
    • روز، دو رقم در 2 ضرب می شوند (برای جلوگیری از برخورد به خارج از مرز بخش) - این سومین بایت وسط آدرس بخش کارت حافظه است.
    • بایت چهارم مرتبه پایین همیشه "0" است.

    در نتیجه، جستجوی داده ها بر اساس تاریخ ساده شده است؛ فقط باید درخواست را به آدرس بخش ترجمه کنید و از کارت بخوانید. با این روش می توان داده ها را برای چندین سال ذخیره کرد. درست است، معایبی نیز وجود دارد؛ فضای استفاده نشده زیادی باقی مانده است. اگر چه، در صورت تمایل، می توانید از آن برای کارهای دیگر استفاده کنید.

    چه کسی به آن نیاز دارد، من یک قطعه کد در اسمبلر برای 18 پیک برای شما ارسال می کنم.

    سوالات را می توان در ..

    تا زمانی که یادم می آید، همیشه عاشق خواندن بوده ام، اما این قرن بیست و یکم است و گاهی اوقات ادبیات لازم را فقط در اینترنت می توان یافت. بله، و شما می توانید کتاب های الکترونیکی را روی یک دستگاه الکترونیکی مانند تبلت، رایانه یا کتابخوان الکترونیکی بخوانید. نتیجه یک دستگاه کوچک است که می تواند فایل های متنی را از کارت SD یا microSD بخواند و محتویات آنها را روی صفحه نمایش دهد.

    مغز دستگاه میکروکنترلر Atmega32 است که در فرکانس 8 مگاهرتز کار می کند. MK از یک کوارتز خارجی در 8 مگاهرتز کلاک می شود؛ من از یک نشانگر LCD کوچک WH1604A روی کنترلر HD44780 با وضوح 4 خط هر کدام 16 کاراکتر به عنوان صفحه نمایش دستگاه استفاده کردم. من از دکمه های ساعت معمولی استفاده کردم؛ در مورد کارت SD، برای اتصال آن به میکروکنترلر، از تقسیم کننده های مقاومت برای مطابقت با سطوح منطقی استفاده کردم.

    نمودار شماتیک دستگاه:

    پین اوت در نمودار فقط برای کارت SD یا آداپتور SD درست است؛ برای اتصال کارت های دیگر، از پین اوت آنها استفاده کنید!

    این دستگاه از کارت های حافظه SD، miniSD و microSD تا 4 گیگابایت فرمت شده در سیستم فایل FAT، FAT16 پشتیبانی می کند. لازم به یادآوری است که دستگاه از دایرکتوری ها پشتیبانی نمی کند، بنابراین تمام فایل ها باید فقط در ریشه درایو فلش نوشته شوند. فایل های متنی باید با فرمت txt معمولی و بدون قالب بندی باشند، نام فایل ها نباید بیشتر از 8 کاراکتر باشد (بدون احتساب پسوند).

    هنگامی که دستگاه را روشن می‌کنید، یک صفحه نمایش بر روی صفحه نمایش ظاهر می‌شود:

    اگر کارت SD در دستگاه نصب نشده باشد، به اشتباه وصل شده باشد یا چیز دیگری، پیام زیر ظاهر می شود:

    اگر همه چیز مرتب باشد، منوی اصلی ظاهر می شود:

    با استفاده از دکمه‌ها، می‌توانید آیتم «مرور فایل‌ها» را وارد کنید، جایی که می‌توانید فایل مورد نیاز برای خواندن را انتخاب کنید.

    در مورد "تنظیمات" می توانید انتخاب کنید کدام پسوند فایل ها در "مرورگر فایل" نمایش داده شود.

    و در پاراگراف آخر "درباره سیستم ..." می توانید اطلاعات مربوط به دستگاه، نویسنده آن و غیره را بخوانید.

    من سیستم عامل دستگاه را در محیط BASCOM-AVR با استفاده از کتابخانه AVRDOS نوشتم، سیستم عامل تنها 30 درصد از حافظه برنامه میکروکنترلر را اشغال می کند، بنابراین جایی برای خلاقیت وجود دارد. در داخل، دستگاه بر روی دو تخته مدار چاپی مونتاژ شده است: در یکی MK با کیت بدنه وجود دارد، در دیگری یک رابط برای کارت SD و زنجیره های مطابق با سطوح منطقی وجود دارد.

    این هم عکسی از داخل دستگاه:

    برای منبع تغذیه از یک باتری 4.8 ولت و 600 میلی آمپر ساعت Ni-Cd استفاده کردم. پس از فلش کردن میکروکنترلر، باید فیوز بیت های زیر را تنظیم کنید:

    فهرست عناصر رادیویی

    تعیین تایپ کنید فرقه تعداد توجه داشته باشیدخرید کنیددفترچه یادداشت من
    U1 MK AVR 8 بیتی

    ATmega32

    1 به دفترچه یادداشت
    D1، D2 دیود یکسو کننده

    1N4001

    2 به دفترچه یادداشت
    C1، C2 خازن22 pF2 به دفترچه یادداشت
    C3 خازن الکترولیتی100μF1 به دفترچه یادداشت
    C4 خازن100 nF1 به دفترچه یادداشت
    R1 مقاومت

    10 کیلو اهم

    1 به دفترچه یادداشت
    R2-R4 مقاومت

    4.7 کیلو اهم

    3 به دفترچه یادداشت
    R5-R7 مقاومت

    1 کیلو اهم

    3 به دفترچه یادداشت
    LCD1 صفحه نمایش ال سی دیLM014L1 به دفترچه یادداشت
    X1 کوارتز8 مگاهرتز1 به دفترچه یادداشت
    دکمه 4 به دفترچه یادداشت
    تعویض 1

    به روز رسانی 12/18/15. سلام به همه. امروز ما توسعه کنترل کننده جمع آوری داده ها را ادامه خواهیم داد، یعنی اطلاعات را مستقیماً در آن ذخیره می کنیم کارت SD . در مقاله آخر، عملکرد دماسنج مشخص شد. اکنون این اطلاعات به موقع هنگام اتصال Vساعت واقعی بیشتر (مقاله شماره 29، آن را روی کارت حافظه قرار می دهیم و نوعی پایگاه داده به دست می آوریم. و همچنین در آینده این اطلاعات را از طریق یک برنامه کوچک در جاوا (مقاله شماره 44) به رایانه شخصی (مقاله شماره 42) به پایگاه داده ای که MySQL را اجرا می کند (مقاله شماره 48) منتقل خواهیم کرد. اما ابتدا بیایید بفهمیم که کارت SD چیست و چگونه با آن کار کنیم.بیایید با یک تاریخچه مختصر شروع کنیم. سلف حافظه های فلش یکی از انواع حافظه های غیر فرار است, نوع، که خود را ثابت کرده و در میکروکنترلرها استفاده می شود. حافظه فلش از نیاز به افزایش ظرفیت و تغییرات در فناوری پاک کردن (در مورد حافظه EPROM) ناشی شد. بنابراین، در سال 1984، مهندس توشیبا، فوجیو ماسوئوکوی، فناوری پاک کردن را تغییر داد که به نوبه خود کاستی های پیشینیان حافظه فلش را برطرف کرد. من می خواهم اضافه کنم که بیشتر این حافظه با توجه به دستگاه داخلی برای اتصال سلول ها به یک آرایه و الگوریتم های خواندن و نوشتن تقسیم می شود - این فناوری NOR و NAND است. و همچنین تفاوت در تعداد بیت های ذخیره شده در یک سلول ابتدایی. اینها دستگاه های SLC (تک سطحی)، یعنی. سلول های تک بیتی تنها دو سطح شارژ را در دروازه شناور تشخیص می دهند. و دستگاه های MLC (سلول های چند سطحی) - سلول های چند بیتی سطوح شارژ بیشتری را تشخیص می دهند. دستگاه نوع دوم ارزان تر و ظرفیت بیشتری نسبت به دستگاه های SLC دارد، اما با زمان دسترسی طولانی تر و حداکثر تعداد رونویسی کمتر (حدود 10 هزار و 100 هزار برای SLC).

    به طور کلی، دستگاه های فناوری NOR یک ماتریس دو بعدی از هادی ها هستند که امکان دسترسی سریع تر به هر سلول حافظه را فراهم می کند، اما مساحت سلول بزرگ در نظر گرفته می شود، بنابراین از این فناوری برای حافظه برنامه های ریزپردازنده و برای ذخیره داده های کمکی کوچک و تخصصی استفاده می شود. تراشه های بوت کامپیوتر را نیز می توان در اینجا گنجاند
    (POST و BIOS)، پردازنده های DSP و منطق قابل برنامه ریزی حجم های معمولی - از 1 کیلوبایت تا 1 مگابایت.
    نوع دوم دستگاه، فناوری NAND است - یک آرایه سه بعدی دارای یک منطقه سلول کوچک است، اما دسترسی نسبتا طولانی به گروه بزرگی از سلول ها در آن واحد دارد. برای حجم زیاد حافظه استفاده می شود.این حافظه ای است که با آن کار خواهیم کرد.
    اما قبل از آن می خواهم در مورد یک اشکال صحبت کنم. همانطور که هر چیزی تاریخ انقضای خاص خود را دارد، حافظه نیز منبع ساییدگی دارد. تولیدکنندگان در رقابت برای ظرفیت و رهبری بازار، همیشه شاخصی مانند کیفیت را از دست می دهند، زیرا ... با قیمت بالا سازگار نیست بنابراین، با بازگشت به فرسودگی، می خواهم توجه داشته باشم که عمر ذخیره سازی اطلاعات هنگام استفاده از دستگاه های MLC تقریباً 5 سال است که با تجمع تغییرات برگشت ناپذیر هنگام تغییر شارژ همراه است. اگر حافظه NAND را از دستگاه‌های SLC بگیریم، آن‌ها کیفیت بالاتری دارند و بنابراین گران‌تر هستند. شایان ذکر است که عمر ذخیره سازی اطلاعات تا حد زیادی به دما، تابش گاما و ذرات پر انرژی بستگی دارد.
    در بالا گفته شد که نقطه ضعف کارت تعداد محدود چرخه های بازنویسی است. هنگامی که از یک سیستم فایل برای مدیریت فایل ها استفاده می کنیم، باید بدانیم که چنین سیستم هایی داده ها را در یک مکان می نویسند و طبیعتاً منابع منطقه اختصاص داده شده را مصرف می کنند و در نهایت آن را غیرقابل استفاده می کنند و در نتیجه ظرفیت را کاهش می دهند. این نوع حافظه از یک کنترلر NAND استفاده می کند که باید سایش را به طور مساوی توزیع کند. اما برای کاهش هزینه دستگاه ها، ممکن است از کنترلر استفاده نشود و کار آن توسط یک نرم افزار درایور NAND در سیستم عامل انجام شود. پس از این کشف، بسیاری از شرکت ها شروع به توسعه استانداردهای خود برای کارت های قابل حمل کردند.

    در ادامه به بررسی نقشه می رویم.
    کارت حافظه دیجیتال امن (SD) یک فرمت کارت حافظه است که برای استفاده در دستگاه های قابل حمل طراحی شده است. برای درک عملکرد آن، از مشخصاتی استفاده می کنیم که این استاندارد را توصیف می کند و SD Specifications ver3.01 نامیده می شود.
    اولین چیزی که نیاز داریم این است که نحوه کار با این کارت، نحوه اتصال آن و غیره را بفهمیم. ابتدا بیایید یک کارت را انتخاب کنیم. برای آزمایش، یک میکرو اس دی 2 گیگابایتی، استاندارد ظرفیت SDSC گرفتم. گذرگاه کارت می تواند با استفاده از دو پروتکل کار کند: SD و SPI. لازم به ذکر است که این کارت نوعی اصلاح کارت MMC است که در آن (در کارت SD) توجه اصلی به سیستم امنیتی بود. بنابراین الگوریتم عملیاتی پروتکل SPI یکسان است و البته با یک طرفه سازگاری دارند. یعنی می توانیم MMC را در اسلات کارت SD وارد کنیم، اما برعکس نه.

    شکل زیر نمودار اتصال را نشان می دهد کارت های SD پروتکل SPI .
    این رابط به شما اجازه می دهد تا با استفاده از حداقل تعداد پایه های میکروکنترلر که مجهز به یک ماژول SPI هستند، داده ها را با سرعت بالا مبادله کنید. از این به بعد ما شروع به استفاده از مشخصات خواهیم کرد. اولین چیزی که ما را مورد توجه قرار می دهد، انتخاب حالت است. بیایید به نکات ظریف در شکل نگاه کنیم. در زیر از بخش 6.4.1.1 نمودار ولتاژ تغذیه و ترتیب ارسال فرمان آمده است. در اینجا به وضوح می توانید ببینید که پس از روشن کردن کارت، باید چند میلی ثانیه (1ms + از 0.1 تا 35 میلی ثانیه (بالا رفتن)) برای تثبیت صبر کنید. در طول این مدت، 1 باید به خط CS، MOSI اعمال شود.بعد، زمانی که 74 پالس (چرخه) به ورودی CLK اعمال می شود، تاخیر اولیه حداکثر 1 میلی ثانیه رخ می دهد، پس از آن دستور CMD0 باید دنبال شود. بیایید به فصل 7 برویم، جایی که توالی اقدامات به وضوح توضیح داده شده است.

    نمودار ولتاژ منبع تغذیه

    پروتکل SPI پس از روشن شدن پاور و صدور دستور CMD0 reset انتخاب می شود. کارت SD خود در حالت SD کار می کند. این حالت در صورتی وارد می شود که هنگام صدور فرمان CMD0 سیگنال SC 0 باشد. هنگام تغییر به حالت SPI، کارت به فرمت R1 پاسخ می دهد (شکل زیر). قالب پاسخ یک بایت است (بسته به دستور، جدول 7.3 را در مشخصات ببینید) با پرچم هایی که وضعیت کارت را تعیین می کند. پاسخ های صحیح برای ما 1 (در مورد دستور CMD0) و 0 در بقیه موارد خواهد بود.
    بیت 1 - حالت آماده به کار
    2- خطا را پاک کنید
    سوم - تیم ناشناس
    4- خطای تیم
    پنجم - خطا در دنباله پاک کردن
    ششم - خطای آدرس
    هفتم - خطای آرگومان

    در طی فرآیند تنظیم مجدد، کارت باید با 0x01 پاسخ دهد که مربوط به بیت اول است.

    توالی مشخصی در مشخصات وجود دارد مقداردهی اولیه برای SPI چرا از دستور CMD8 برای بررسی وضعیت کار کارت استفاده می شود، جایی که یک الگوریتم تأیید نسبتاً پیچیده انجام می شود. دستور CMD58 برای تعیین نوع کارت SDSD یا SDHC و SDXC است. و همچنین دستور CMD41 برای اجرا و بررسی مقداردهی اولیه. این یک فرآیند اولیه سازی نسبتاً پیچیده با بررسی است، اما من فکر می کنم که برای ثبت داده های ساده می توان از یک فرآیند ساده تر استفاده کرد. در بخش 7.2.7. گفته می شود در حالت آماده به کار تنها دستورات معتبر برای کارت عبارتند از CMD41، CMD8، CMD58، CMD59 و همچنین برای کارت های حافظه SD (ضخامت 2.1 میلی متر) CMD1 که مشابه دستور CMD41 است. در استاندارد، این دستور برای مقداردهی اولیه ممنوع تلقی می شود و منحصراً برای تشخیص کارت های 1.4 میلی متری و 2.1 میلی متری استفاده می شود.
    بیایید یک مسیر ساده تر را انتخاب کنیم و از دستور CMD1 استفاده کنیم. ما همه چیزهایی که در بالا توضیح داده شد را در کد در تابع مقداردهی اولیه نمایش خواهیم داد، اما قبل از آن فرمت دستور را در نظر خواهیم گرفت. هر دستورالعمل یا بلوک داده شامل هشت بیت بیت است که با سیگنال CLK تراز می شوند. آن ها هر دستورالعمل بر روی مرز 8 سیکل ساعت تراز شده است. پیام های SPI شامل فرمان، پاسخ و داده است. تمام ارتباطات توسط یک میکروکنترلر کنترل می شود. تمام دستورات 6 بایت هستند. انتقال با اولین بیت سمت چپ شروع می شود.

    شکل زیر فرمت فرمان را نشان می دهد.


    کمی شروع - هر دستوری از 0 شروع می شود.بیت ارسالی نیز همیشه برابر با 1 است.
    فهرست مطالب - دستور مستقیم ارسال شده
    بحث و جدل- برای هر دستور، آرگومان در جدول مشخصات فهرست شده است.
    CRC بررسی افزونگی کد به طور پیش فرض، در حالت SPI غیرفعال است. بنابراین از آن فقط برای دستور CMD0 استفاده می کنیم که قبل از ورود به حالت ارسال می شود و مقدار CRC آن 0x95 است.
    کمی توقف - پایان فرمان ارسالی
    پس بیایید شروع به نوشتن کد کنیم.
    بیایید با 2 عملکرد ضروری شروع کنیم: ارسال و دریافت بایت.
    1. بایت را به کارت منتقل کنید.
    void trans_byte_sd (داده نویسه بدون امضا) // آرایه ای از بیت ها را ارسال کنید
    {
    برای (char i=0;i بدون علامت<8;i++) //تکرار از طریق بایت
    {
    اگر ((داده&0×80)==0×00)//اگر مهم ترین بیت = 0 باشد
    PORTB&=~_BV (PB3);// MOSI (DI) -0 را تنظیم کنید
    دیگر
    PORTB|=_BV (PB3);//1
    داده = داده<<1; // сдвиг влево
    PORTB|=_BV (PB5); //نبض یا بارق
    asm ("نه"); //مکث 1 ضربی
    PORTB&=~_BV (PB5);
    }
    }
    2. دریافت بایت توسط میکروکنترلر.
    نویسه بدون امضا receive_byte_sd (باطل) // پاسخ را برگردانید
    {
    داده کاراکتر بدون علامت = 0; // آرایه را مقداردهی اولیه کنید
    برای (نویسه بدون علامت i=0; i<8; i++)
    {
    PORTB|=_BV (PB5); //لبه پالس
    داده = داده<<1; // شیفت به چپ
    اگر ((PINB&_BV (PB4))!=0×00) // اگر حالت پین 1 باشد
    data=data|0×01;
    PORTB&=~_BV (PB5); //0
    asm ("نه");
    }
    برگرداندن داده ها؛ // پاسخ را برگردانید
    }

    از توابع اساسی که در بالا توضیح داده شد، ما شروع به نوشتن کدهای بیشتر خواهیم کرد. سپس تابع انتقال فرمان را می نویسیم. در اینجا می خواهم توجه شما را به این واقعیت جلب کنم که می توانید هر 5 آرگومان را ارسال کنید: مستقیماً خود فرمان و 4 آرگومان مسئول آدرس سلول های حافظه خود کارت. در مورد بایت 6، پس CRC هنگام ورود به حالت SPI غیرفعال است (به طور پیش فرض) و مقدار به طور دائم روی 0x95 تنظیم می شود که فقط برای CMD0 زمانی که کارت در حالت نیست استفاده می شود. با استفاده از دستور CMD58 می توانید بررسی کد را فعال کنید. برای آزمایش من دو آرگومان را ارائه می کنم.

    3. انتقال فرماندهی
    char بدون امضا comand_sd (char CMD، char arg) /*فرمان و آدرسی را که به آن دسترسی داریم ارسال کنید و پاسخ را برگردانید*/
    {
    long int i=0; // متغیر برای شمارنده
    char بدون امضا r1; // پاسخ کارت
    trans_byte_sd (CMD)؛ // تیم
    trans_byte_sd (0×00);
    trans_byte_sd (0×00);
    trans_byte_sd(arg); // انتقال آدرس
    trans_byte_sd (0×00);
    trans_byte_sd (0×95); // انتقال CRC
    /* پس از ارسال دستور منتظر پاسخ با فرمت R1 هستیم هر دستور پاسخ مخصوص به خود را دارد */
    /* حلقه منتظر شدن برای پاسخ در مدت زمان معین */
    انجام دادن
    {
    r1=receive_byte_sd();
    i++;
    )در حالی که (((r1&0×80)!=0×00)&&(i<0xffff)); /* تا زمانی که مهم ترین بیت بایت 0 نباشد و i از 65535 سیکل ساعت تجاوز نکند */
    بازگشت r1; // پاسخ را برگردانید
    }
    4. و مقداردهی اولیه کارت.

    اکنون می توانیم نقشه را مقداردهی اولیه کنیم. این برنامه به طور خلاصه به شرح زیر است: اولین کاری که باید انجام دهید این است که کارت را به حالت SPI تغییر دهید. هنگامی که برق اعمال می شود، کارت روی حالت SD تنظیم می شود. برای انتخاب حالت SPI، یک 0 منطقی به ورودی CS اعمال می شود، همزمان دستور Reset CMD0 و مقداردهی اولیه CMD1 به ورودی کارت MOSI ارسال می شود. لطفاً توجه داشته باشید که دستور با 0x40 هگزادسیمال شروع می شود که باید شماره دستور CMD را به صورت هگزادسیمال به آن اضافه کنید.

    char بدون امضا spi_card_init (باطل)// تابع پاسخ را برمی گرداند
    {
    char بدون امضا r1; // متغیر برای دریافت پاسخ
    long int i =0; // متغیر برای شمارنده
    _delay_ms(10); // یک تاخیر کوچک برای تثبیت ولتاژ.
    PORTB|=_BV (PB1); //CS، هنگام ارسال چرخه های ساعت روی 1 تنظیم شده است
    PORTB|=_BV (PB3); //خط فرمان - 1 MOSI (DI)
    برای (نویسه بدون علامت i=0; i<80;i++) // ارسال بیش از 74 پالس
    {
    PORTB|=_BV (PB5); //CLK - 1
    asm ("نه"); //یک ساعت تاخیر
    PORTB&=~_BV (PB5); //CLK - 0
    }
    PORTB&=~_BV (PB1); شرط /* برای ورود به خط CS حالت SPI باید برابر با 0 */
    r1=comand_sd (0×40.0×00); // CMD0=0×40، آدرس مهم نیست
    اگر (r1!=0×01) 4 را برگرداند;//شما می توانید هر کد خطا را تنظیم کنید
    trans_byte_sd(0xff); /* ارسال بارق، نوعی مکث قبل از دریافت پاسخ */
    انجام دادن // چرخه دریافت پاسخ از کارت
    {
    r1=comand_sd (0×41.0×00); /* دستور اولیه را ارسال کنید */
    trans_byte_sd(0xff); // مکث
    i++; // پیشخوان
    )در حالی که ((r1!= 0)&&(i<65535)); /*تا زمانی که یک پاسخ 0 دریافت شود و تعداد چرخه ها از 0xffff تجاوز نکند */
    اگر (i>=0xffff) 5 را برگرداند. /* اگر زمان نظرسنجی بیشتر شده باشد، خطا را برگرداند */
    بازگشت 0; //در صورت موفقیت آمیز بودن مقداردهی اولیه، 0 را برگردانید
    }

    نکته مهم بعدی این است که در مشخصات ذکر شده است که اطلاعات در بلوک های 512 بیتی منتقل می شود و اگر کارت SDSC مانند مورد ما باشد، می توان طول بلوک را با استفاده از دستور CMD16 از 1 تا 512 بیت تنظیم کرد. پیش فرض 512 بیت است. در ادامه، دو عملکرد برای دریافت و انتقال بلوک ها را شرح می دهیم. مشخصات شامل نمودارهای بلوکی است که بر اساس آنها کد را می نویسیم.

    انتقال بلوک اطلاعات به کارت

    دستور CMD24 وظیفه انتقال بلوک ONLY را بر عهده دارد. پس از صدور فرمان منتظر پاسخ می مانیم و به دنبال آن یک بایت شروع می آید که کنترل کننده کارت را برای دریافت اطلاعات آماده می کند؛ در پایان کارت با یک بایت در مورد وضعیت ارسال پاسخ می دهد که در فصل 7.3 توضیح داده شده است. 3.1. آن ها پاسخ صحیح باید = 5 باشد. همچنین منتظر می مانیم تا اتوبوس برای انتقال بیشتر آزاد شود.

    انتقال بایت بازخورد وضعیت.

    بخش 7.3.3.2 فرمت بلوک ارسالی را شرح می دهد
    char بدون امضا receive_block_sd (char* block، char arg)/* آرایه را برای ضبط داده ها و آدرسی که به آن دسترسی داریم ارسال کنید */
    {
    long int i = 0;
    char بدون امضا r1;
    r1=comand_sd(0X51,arg);//CMD17
    اگر (r1!=0×00) 5 را برگرداند;//اگر پاسخ 0×00 نیست از آن خارج شوید
    trans_byte_sd(0xff);
    انجام دادن // منتظر بمانید تا بسته داده شروع شود
    {
    r1=receive_byte_sd();
    i++;
    )در حالی که ((r1!= 0xfe)&&(i<65535));
    اگر (i>=0xffff) 5 را برگرداند.
    برای (int i=0;i<512;i=i+1) //دریافت داده
    block[i] = receive_byte_sd();
    receive_byte_sd(); //بایت CRC
    receive_byte_sd(); //بایت CRC
    بازگشت 0;
    }

    قبل از استفاده از برنامه، بیایید به سخت افزار نگاه کنیم. همانطور که در بالا گفتیم، کارت در حالت SPI با میکروکنترلر سازگار است. اجازه دهید به نکات ظریف زیر در کار با نقشه توجه کنیم:
    1. جفت کردن سطوح منطقی برای ولتاژهای مختلف تغذیه کارت SD و میکروکنترلر AVR ضروری است. می توانید از یک تقسیم کننده ولتاژ مقاومتی استفاده کنید که خطی است، یعنی. ولتاژ خروجی به ولتاژ ورودی بستگی دارد. یا می توانید یک تثبیت کننده ولتاژ پارامتریک موازی روی دیود زنر داشته باشید، مانند گزینه اول، فقط در بازوی پایینی از دیود زنر استفاده شده است که یک تقسیم کننده غیر خطی است و به دلیل خواص آن، ولتاژ مرجع را هنگام ورودی کنترل می کند. ولتاژ افزایش می یابد، مقاومت داخلی را کاهش می دهد و بالعکس.
    من از گزینه دوم استفاده کردم در مدار زیر، در خط سیگنال، مقاومت ها بالاست هستند (محدود کننده جریان)، ولتاژ 4.5 - 5 ولت به ورودی تقسیم کننده عرضه می شود و خروجی از بازوی پایین تقسیم کننده حذف می شود.محدود کننده های جریان برای محافظت از کارت و سایر لوازم جانبی در صورت خرابی میکروکنترلر ضروری هستند. با دستگاهی که به خوبی کار می کند، آنها ضروری نیستند.

    توجه داشته باشید که خط MISO نیازی به مذاکره ندارد زیرا فقط در یک جهت از کارت تا میکروکنترلر کار می کند.
    2. نکته دوم، من از در دسترس بودن کارت استفاده نمی کنم و چک های حفاظتی می نویسم. برخی از افراد این مخاطبین را در اسلات دارند، برخی دیگر ندارند.
    3. نکته آخر تغذیه است. یا به کل مدار از جمله میکروکنترلر 3.3 ولت می دهید یا در ورودی مدار یک تقسیم کننده قرار می دهید که چندان قابل اعتماد نیست. یا یک تثبیت کننده 3.3 ولت، همانطور که روی تراشه انجام دادم LP2980 . نکته مهم در اینجا خازن الکترولیتی (تانتالوم) است که از میکروکنترلر در برابر تنظیم مجدد در هنگام کاهش ولتاژ محافظت می کند.
    در زیر برنامه و نتیجه آن آمده است.مثل همیشه سعی می کنم از یک برنامه استفاده کنم و مدام آن را تغییر دهم. این کد برگرفته از مقاله شماره 5 (نشانگر هفت قسمتی) می باشد.

    #عبارتند از
    #عبارتند از
    #عبارتند از
    #عبارتند از
    //ماکروها برای کار با نشانگر
    #128 را تعریف کنید
    #تعریف b 32
    #تعریف از 8
    #define d 2
    #define e 1
    #تعریف f 64
    #define g 16
    #تعریف dp 4

    // متغیرها

    بلوک کاراکتر =();//بافر برای نوشتن/خواندن داده ها روی کارت
    کوتاه بدون علامت int j، k = 0; //در ماکرو وقفه
    اسلات کاراکتر بدون امضا; // آرایه ای از اعداد برای نمایش روی نشانگر

    //اعلان توابع

    void trans_byte_sd (داده های کاراکتر بدون امضا)؛// تابع انتقال بایت
    char امضا نشده receive_byte_sd (void); // تابع دریافت بایت
    char بدون امضاء Comand_sd (char,char); // تابع انتقال فرمان
    char بدون امضا spi_card_init (void); //عملکرد مقداردهی اولیه کارت حافظه
    char بدون امضا receive_block_sd (char* block، char arg); //عملکرد دریافت را مسدود کنید
    char unsigned trans_block_sd (char* block، char arg); //عملکرد انتقال بلوک
    // مقدار دهی اولیه نشانگر
    void Slot_init()
    {…………………….};
    // متغیرهایی برای نمایش اعداد
    char Elem1, Elem2, Elem3;
    // خروجی به نشانگر
    نمایشگر خالی (float i)
    { …………………………... }
    int main (void) //پایه برنامه را شروع کنید
    {
    DDRB = 0x2A; //0010 1010 – PB1, PB3, PB5
    DDRD = 0xff; //همه پین ​​های پورت خروجی هستند
    PORTD = 0×00; // روی 0 تنظیم کنید
    PORTB |= 0×db; //1101 1011 (PB0,1,3,4,6,7)
    slot_init();
    sei(); // یا SREG |= (1<< 7); разрешить общее прерывание
    //تایمر T0 را آغاز کنید
    TIMSK = (1</*فعال کردن پرچم برای سرریز تایمر شمارنده T0*/
    TCCR0 = (0< //1000000/8 = 125000
    دمای کاراکتر بدون علامت
    int i;
    برای (i=0;i<512;i=i+1)
    block[i]= i; //نوشتن در بافر
    spi_card_init(); //مقداردهی اولیه
    trans_block_sd(block,0×04); //ارسال داده به کارت
    //بافر را به صفر برگردانید
    برای (int i=0;i<512;i=i+1)
    block[i]=0;
    // داده ها را از کارت بخوانید
    receive_block_sd (block, 0×04); ;// تابع دریافت بایت
    برای (int i=0;i<512;i=i+1)
    {
    char otv;
    otv = بلوک[i];
    نمایشگر (otv);
    _delay_ms(100);
    }
    //نوشتن در آدرس حافظه 0
    برای (int i=0;i<512;i=i+1)
    block[i]=0;
    کاراکتر بدون علامت Comand_sd (char,0×00); //تابع انتقال فرمان
    trans_block_sd(block,0×04); //ارسال داده به کارت
    }
    //خروجی به نشانگر
    ISR (TIMER0_OVF_vect)
    { ……………. }

    نکته مهم تایم اوت است. نظارت بر زمان لازم برای خواندن یک رکورد و پاک کردن کارت بسیار مهم است، زیرا ممکن است میکروکنترلر در حالی که منتظر پاسخ کارت است منجمد شود. مشخصات به وضوح وقفه های کارت را توصیف می کند. کارت به مدت 5 میلی ثانیه بیکار است و پس از آن به حالت صرفه جویی در مصرف انرژی می رود که در آن دستورات زیر معتبر هستند: CMD0، CMD1، CMD41 و CMD58. بنابراین، هنگامی که از حد بیکاری فراتر رفت، CMD1، پاسخ را ارسال می کنیم و به کار با کارت ادامه می دهیم.
    در زیر دو اسکرین شات از این برنامه را مشاهده می کنید WinHex، که با آن می توانیم محتویات سلول های حافظه را مشاهده کنیم. این برنامه به صورت زیر عمل می کند: ما داده ها را در بافر می نویسیم، آنها را به کارت می فرستیم، بافر را تنظیم مجدد می کنیم، داده ها را از کارت در بافر می خوانیم و روی نمایشگر نمایش می دهیم، در نتیجه مطمئن می شویم که داده ها به کارت منتقل می شوند. . محتویات کارت را نگاه می کنیم، بافر را ریست می کنیم، 0 را روی کارت می نویسیم و دوباره محتویات کارت را باز می کنیم و از این طریق مطمئن می شویم که برنامه و مدار کار می کنند. مثل همیشه، چیزهای کوچکی را فراموش نکنید، مانند عدم استفاده از لحیم کاری کافی، نداشتن ترک های بزرگ در مسیرها و غیره، که می توانند سهم زیادی از زمان را به خود اختصاص دهند. بنابراین، اگر یک اسیلوسکوپ در دسترس دارید، حتما از آن برای راه اندازی استفاده کنید. که درماده 24من یک مثال کوچک از عیب یابی یک کارت در تمام مراحل عملکرد آن زدم.می بینمتسنسور رطوبت و دماDHT11. پس از آن شروع به ثبت داده ها (دما و رطوبت) در یک فایل متنی، نوعی پایگاه داده می کنیم. فعلاً همین است. خداحافظ همه