چیپ حافظه چیست و چگونه ریز مدارها را برنامه ریزی کنیم. نحوه پاک کردن EEPROM (حافظه غیر فرار) با استفاده از حافظه eeprom

آخرین بار، وقتی «پاسخ تفصیلی به سؤال» خود را در مورد نحوه پشتیبان‌گیری از سیستم‌افزار از مگا نوشتم، آنها مرا به خاطر عدم اشاره به بک آپ EEPROM سرزنش کردند. آن بار من آگاهانه این کار را نکردم، زیرا ... من به درستی قضاوت کردم که نیازی به پیچیده کردن همه چیز در مرحله اولیه "رویکرد به پرتابه" نیست. واقعیت این است که برای همه مشخص نیست که EEPROM هنگام کامپایل و آپلود سیستم عامل از فلش نمی شود. آردوینو IDE. یعنی زمانی که سیستم عامل از IDE آپلود می شود، مطلقاً هیچ چیزی در EEPROM آپلود نمی شود. و دستکاری با EEPROM (اگر اصلاً استفاده از آن در سیستم عامل فعال باشد) در سطح کاملاً متفاوتی انجام می شود. و بنابراین، برای پشتیبان گیری از سیستم عامل لخت بدون تنظیمات خوب، که احتمالاً (فقط شاید) می تواند در EEPROM ذخیره شود، برای ذخیره فقط سفت افزار خالی کافی بود. اما از آنجایی که این سوال مطرح شده است، چرا آن را "جویده" نکنیم. بیایید به ترتیب آن را مرور کنیم. EEPROM چیست و چرا در مورد آن صحبت می کنیم؟
EEPROM - (حافظه فقط خواندنی قابل برنامه ریزی با قابلیت پاک کردن الکتریکی) ناحیه ای از حافظه غیر فرار میکروکنترلر که اطلاعات را می توان در آن نوشت و خواند. اغلب برای ذخیره تنظیمات برنامه استفاده می شود که ممکن است در حین کار تغییر کند و باید در هنگام خاموش شدن برق ذخیره شود.

چگونه یک چاپگر سه بعدی از EEPROM استفاده می کند؟
بیایید به عنوان مثال به مارلین نگاه کنیم. در فریمور مارلین خارج از جعبه، EEPROM استفاده نمی شود. پارامترهای پیکربندی (Configuration.h) که شامل قابلیت استفاده از آن است، به طور پیش فرض توضیح داده می شوند.

#define EEPROM_SETTINGS
#تعریف EEPROM_CHITCHAT

اگر استفاده از EEPROM فعال باشد، چاپگر می تواند تنظیمات زیر را ذخیره و استفاده کند (مشخص شده از بورژوازی):

  • تعداد قدم ها در میلی متر
  • حداکثر/حداقل سرعت تغذیه [mm/s]
  • حداکثر شتاب [mm/s^2]
  • شتاب
  • شتاب در حین جمع شدن
  • تنظیمات PID
  • افست موقعیت خانه
  • حداقل سرعت تغذیه در حین حرکت [mm/s]
  • حداقل زمان بخش [ms]
  • حداکثر سرعت پرش محورهای X-Y[mm/s]
  • حداکثر سرعت پرش در محور Z [mm/s]
می توانید این تنظیمات را با استفاده از صفحه و کنترل های چاپگر ویرایش کنید. هنگامی که استفاده از EEPROM فعال است، منو باید موارد زیر را نمایش دهد:
  • ذخیره حافظه
  • بارگیری حافظه
  • Failsafe را بازیابی کنید
همچنین می توانید از GCode برای کار مستقیم (از طریق Pronterface) استفاده کنید.
  • M500 تنظیمات فعلی را در EEPROM تا راه اندازی بعدی یا دستور M501 ذخیره می کند.
  • M501 تنظیمات را از EEPROM می خواند.
  • M502 تنظیمات را به مقادیر پیش فرض مشخص شده در Configurations.h بازنشانی می کند. اگر M500 را بعد از آن اجرا کنید، مقادیر پیش فرض در EEPROM وارد می شود.
  • M503 تنظیمات فعلی را نمایش می دهد - ""آنهایی که در EEPROM ضبط شده اند."
شما می توانید در مورد EEPROM در سیستم عامل Repitier مطالعه کنید.

چگونه داده ها را در EEPROM بخوانیم و بنویسیم؟
مشابه روشی که در روش پشتیبان گیری سیستم عامل با استفاده از کلید توضیح داده شده است -U. فقط در این مورد، بعد از آن یک اشاره گر وجود خواهد داشت که نشان می دهد EEPROM باید خوانده شود.

avrdude.exe -p atmega2560 -c سیم کشی -PCOM5 -b115200 -Ueeprom:r:"printer_eeprom".eep:i

این دستور داده های EEPROM را در فایل "printer_eeprom.eep" می خواند.در صورت موفقیت آمیز بودن، چیزی شبیه به زیر را روی صفحه خواهید دید.

ضبط نیز پیچیده نیست و با دستور مشابهی انجام می شود که فقط در کلید متفاوت است -U"r" نیست، بلکه "w" است.

avrdude.exe -p atmega2560 -c سیم کشی -PCOM5 -b115200 -Ueeprom:w:"printer_eeprom".eep:i

در صورت موفقیت آمیز بودن، چیزی شبیه به پیام زیر را روی صفحه مشاهده خواهید کرد.

چگونه و چرا EEPROM را پاک کنیم؟
برای شروع، "چرا این کار را انجام دهیم؟" اگر سیستم عامل قبلی نیز از آن استفاده می کرد، باید EEPROM را پاک کنید و ممکن است زباله در حافظه باقی بماند. در جایی قبلاً با افرادی روبرو شده ام که با مشکلاتی روبرو شده ام که پس از جابجایی از یک سیستم عامل به سیستم عامل دیگر (از Marlin به Repitier EMNIP) ، چاپگر آنها به اصطلاح "خلاقانه" رفتار می کند. این به این دلیل است که سیستم عامل های مختلف داده های خود را در زیر ذخیره می کنند آدرس های مختلف. و وقتی سعی می کنید داده ها را از آدرس اشتباه بخوانید، هیاهو شروع می شود.
شما می توانید EEPROM را فقط به صورت برنامه نویسی از میان افزار پاک کنید، اما برای انجام این کار باید به طور موقت یک طرح خاص را در کنترلر آپلود کنید. می‌توانید در مستندات رسمی آردوینو بیشتر در این مورد مطالعه کنید.
اگر EEPROM پاک شود نه در برد آردوینوو در برخی از کنترلرهای انتزاعی، کد طرح باید با در نظر گرفتن اندازه EEPROM در یک کنترلر خاص روی برد تغییر کند. برای انجام این کار، باید شرایط پایان را در حلقه "For" تغییر دهید. به عنوان مثال، برای ATmega328 که دارای حافظه EEPROM 1 کیلوبایتی است، چرخه به این صورت خواهد بود:
نتیجه.
من مدت زیادی است که در حال جست و خیز بودم، اما این همه برای چیست؟ برای اینکه به این نتیجه برسیم که هنگام پشتیبان گیری از سیستم عامل، EEPROM نیز می تواند ذخیره شود، اما فقط در صورتی که به تنظیمات ذخیره شده در آن نیاز داشته باشید. اگر حاضرید آنها را قربانی کنید، آن را فراموش کنید. همچنین، اگر یک سفت‌افزار را به دیگری تغییر می‌دهید، یا از نسخه‌ای به نسخه دیگر سوئیچ می‌کنید، برای پاک کردن EEPROM قبل از آپلود تنبل نباشید. سیستم عامل جدید. خوب، در همان زمان ما چیزهای جدید زیادی یاد گرفتیم.

کنترل کننده کوره ما تقریباً آماده است - با این حال، در حال حاضر یک کنترل کننده "ماهی قرمز" است که تمام تنظیمات را تنها پنج دقیقه قبل از اولین خاموش شدن به خاطر می آورد. برای به خاطر سپردن تنظیمات ما، مقدار دمای تنظیم شده و نقاط کالیبراسیون حتی پس از خاموش کردن برق، باید از حافظه غیر فرار - EEPROM استفاده کنید.
دوستان ما در مورد کار با EEPROM بسیار خوب نوشته اند.

نکته اصلی که باید بدانیم این است حافظه EEPROMبهتر است آن را نه به عنوان "فقط حافظه" بلکه به عنوان یک دستگاه داخلی جداگانه در تراشه در نظر بگیرید.
EEPROM فضای آدرس جداگانه، که ربطی به فضای آدرس پردازنده (FLASH و SRAM) ندارد. برای دسترسی به داده ها در یک آدرس خاص در حافظه غیر فرار، باید اجرا کنید یک دنباله خاصاقدامات با استفاده از تعدادی رجیستر (رجیستر آدرس EEARH و EEARL، ثبت داده EEDR و ثبت کنترل EECR).
با توجه به دیتاشیت، برای نوشتن یک بایت به یک آدرس خاص در EEPROM، باید موارد زیر را انجام دهید:

  1. صبر کنید تا EEPROM برای نوشتن داده آماده شود (بیت EEPE رجیستر EECR بازنشانی می شود).
  2. منتظر پایان نوشتن در حافظه FLASH باشید (بازنشانی بیت SELFPRGEN رجیستر SPMCSR) - اگر بوت لودر در برنامه وجود داشته باشد، باید انجام شود.
  3. بنویس آدرس جدیدبه ثبت EEAR (در صورت لزوم)؛
  4. یک بایت داده در رجیستر EEDR بنویسید (در صورت لزوم).
  5. بیت EEMPE رجیستر EECR را روی یک تنظیم کنید.
  6. در طی چهار سیکل ساعت پس از تنظیم پرچم EEMPE، یک عدد منطقی در بیت EEPE ثبت EECR می نویسیم.

سپس پردازنده قبل از اجرای دستور بعدی، 2 سیکل ساعت را رد می کند.
نکته دوم باید در صورت وجود بوت لودر در برنامه انجام شود - واقعیت این است که نوشتن در EEPROM نمی تواند همزمان با نوشتن در حافظه FLASH انجام شود، بنابراین قبل از نوشتن در EEPROM باید مطمئن شوید که برنامه نویسی حافظه FLASH کامل شده است. اگر میکروکنترلر بوت لودر نداشته باشد، هرگز محتویات حافظه FLASH را تغییر نمی دهد (به یاد داشته باشید که avr معماری هاروارد دارد: حافظه برنامه (FLASH) و حافظه داده (SRAM) از هم جدا هستند).
مدت زمان چرخه ضبط به فرکانس نوسانگر داخلی RC تراشه، ولتاژ تغذیه و دما بستگی دارد. معمولاً برای مدل‌های ATmega48x/88x/168x این 3.4 میلی‌ثانیه (!) و برای برخی از مدل‌های قدیمی‌تر - 8.5 میلی‌ثانیه (!!!) است.
علاوه بر این، هنگام نوشتن در EEPROM، ممکن است مشکلاتی با وقفه های فراخوانی در طول اجرای دنباله اقدامات بالا ایجاد شود - بنابراین بهتر است هنگام نوشتن در EEPROM، وقفه ها را غیرفعال کنید.
خواندن حافظه غیر فرار کمی ساده تر است:

  1. صبر کنید تا EEPROM برای خواندن داده ها آماده شود (بیت EEWE رجیستر EECR بازنشانی می شود).
  2. آدرس را در رجیستر EEAR بنویسید.
  3. بیت EERE رجیستر EECR را روی یک تنظیم کنید.
  4. ما داده ها را از رجیستر EEDR می خوانیم (در واقع وقتی داده های درخواستی به ثبت داده منتقل می شوند، این اتفاق می افتد هارد ریستبیت EERE; اما نیازی به نظارت بر وضعیت این بیت نیست، زیرا عملیات خواندن از EEPROM همیشه در یک چرخه ساعت انجام می شود).

پس از تنظیم یک بیت در EERE روی یک، پردازنده 4 چرخه ساعت را قبل از اجرای دستور بعدی رد می کند.
همانطور که می بینیم، کار با حافظه غیر فرار- فرآیند زمان بر است. اگر اغلب داده ها را از EEPROM بنویسیم و بخوانیم، ممکن است برنامه شروع به کند شدن کند.

با این حال، ما در حال نوشتن برنامه ای در محیط IAR هستیم و خوش شانس هستیم: تمام کار خواندن و نوشتن از EEPROM توسط محیط توسعه انجام می شود - iar دارای اصلاح کننده "__eeprom" است که متغیرهایی را در حافظه غیر فرار ایجاد می کند. - و سپس ما فقط باید از متغیرهای " ثابت" به "جریان" بخوانیم (هنگام مقداردهی اولیه کنترلر)، یا از متغیرهای "جریان" به "ثابت" بنویسیم - یعنی وقتی مقدار فعلی تغییر می کند، مقدار متغیر در حافظه غیر فرار نیز باید تغییر کند.
متغیرهای جدید به شکل زیر خواهند بود:

Eeprom uint16_t EEP_MinTemperature;

چند کلمه کلی تر: و اگرچه ما نشانگرهای متغیرهای eeprom را فرض نمی کنیم، باید به خاطر داشته باشیم که eeprom یک فضای آدرس جداگانه است و برای ایجاد یک اشاره گر به eeprom (و کامپایلر این اجازه را به ما می دهد)، باید نشان می دهد که این یک اشاره گر به یک آدرس در eeprom است:

Uint16_t __eeprom *EEP_MinTemperatureAdr;

بیایید به کنترل کننده اجاق گاز و EEPROM برگردیم. در مورد ما، EEPROM وجود ندارد ماشین مجازیالبته انتظار نمی رود. علاوه بر این، باید در نظر گرفت که آیا برای کار با حافظه غیر فرار به یک کتابخانه جداگانه نیاز است - آنها در برنامه ضبط بسیار "پراکنده" هستند. تنظیمات مهم; اگر بخواهید یک کتابخانه جداگانه بسازید، باید ارجاعات متقابل انجام دهید: در کتابخانه EEPROM، کتابخانه های ADC، عنصر گرمایش و تنظیمات جهانی را به هم وصل کنید. و در این کتابخانه های جانبی، اتصال کتابخانه EEPROM روش خیلی خوبی نیست.
گزینه دیگر اضافه کردن یک متغیر eeprom به هر کتابخانه است که در آن باید تنظیمات را ذخیره کنید و تنظیمات مربوطه را مستقیماً در آن ذخیره کنید. ماشین های مجازی. ما این گزینه را اجرا خواهیم کرد.
ابتدا بیایید فهرست کنیم که چه متغیرهایی را باید در EEPROM ذخیره کنیم:

  1. نقاط کالیبراسیون
  2. مقادیر حداکثر-حداقل دمای تنظیم شده و مرحله تنظیم دما
  3. مقدار دما را تنظیم کنید
  4. ضرایب کنترل کننده PID

ما ارزش تایمر آشپزخانه را ذخیره نمی کنیم - فرض می کنیم که کاربر باید هر بار پس از خاموش کردن برق، تایمر اجاق گاز را تنظیم کند.
تمامی این تنظیمات توسط کاربر با چرخاندن انکودر و سپس فشردن مختصر دکمه کاربر انجام می شود. در همان زمان، ما به یاد داریم که تعداد چرخه های خواندن و نوشتن EEPROM هنوز محدود است، بنابراین دوباره همان اطلاعات را بازنویسی نکنید (به عنوان مثال، اگر کاربر همان مقدار تنظیمات را انتخاب کرده باشد). بنابراین، قبل از هر تغییر در متغیر __eeprom، بررسی می کنیم که آیا نیاز به بازنویسی دارد یا خیر:

//اگر مقدار تغییر کرده است، آن را در حافظه غیر فرار بازنویسی کنید، اگر (ADCTemperature.atMinTemperatureValue != (uint16_t)VMEncoderCounter.ecntValue) (ADCTemperature.atMinTemperatureValue = (uint16_t)teremperature. atMinTemperatureV alue; )

خواندن تنظیمات از EEPROM نیز ساده است - هنگام تنظیم اولیه تنظیمات "جریان"، ما به سادگی مقدار را از حافظه غیر فرار می خوانیم:

ADCTemperature.atMinTemperatureValue = EEP_MinTemperature;

برای اینکه دستگاه ما از همان ابتدا تنظیماتی در EEPROM داشته باشد، می‌توان پروژه اولین بوت را با این متغیرها کامپایل کرد:

Eeprom uint16_t EEP_MinTemperature = 20; ... //آرایه برای ذخیره نقاط کالیبراسیون در حافظه غیر فرار __eeprom TCalibrationData EEP_CalibrationData = ((20, 1300), (300, 4092));

در این حالت، کامپایلر قبل از شروع کار با تابع main، متغیرهای __eeprom را مقداردهی اولیه می کند. برای دریافت فایلی با حافظه غیر فرار (.eep)، باید به تنظیمات زیر بروید:
پروژه->گزینه ها..->لینکر->گزینه های اضافی
اگر کادر انتخاب «استفاده از گزینه‌های خط فرمان» علامت‌گذاری نشد، آن را علامت بزنید و خط را اضافه کنید
-Ointel-standard,(XDATA)=.eep
ابتدا پروژه را با متغیرهای اولیه کامپایل می کنیم، فایل eep را جداگانه ذخیره می کنیم. سپس هنگام ایجاد متغیرها مقدار دهی اولیه را حذف می کنیم.

این همه - اجاق گاز ما آماده است!

آردوینو یک خانواده کامل است دستگاه های مختلفبرای ایجاد پروژه های الکترونیکی استفاده از میکروکنترلرها بسیار راحت است و حتی برای افراد مبتدی نیز به راحتی قابل یادگیری است. هر میکروکنترلر از یک برد، برنامه های عملیاتی و حافظه تشکیل شده است. در این مقاله به حافظه غیر فرار مورد استفاده در آردوینو می پردازیم.

توضیحات حافظه EEPROM

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

به محض راه‌اندازی مجدد دستگاه یا خاموش شدن دستگاه، تمام داده‌های رم پاک می‌شوند. دو مورد دوم تمام اطلاعات را قبل از بازنویسی ذخیره می کنند و به شما امکان می دهند در صورت لزوم آن را بازیابی کنید. درایوهای فلش امروزه بسیار رایج هستند. ارزش آن را دارد که حافظه EEPROM را با جزئیات بیشتری در نظر بگیرید.

مخفف عبارت Electrically Erasable Programmable Read-Only Memory است و به زبان روسی ترجمه شده به معنای واقعی کلمه به معنای حافظه فقط خواندنی قابل برنامه ریزی با قابلیت پاک شدن الکتریکی است. سازنده ایمنی اطلاعات را برای چندین دهه پس از آخرین قطع برق تضمین می کند (معمولا یک دوره 20 ساله داده می شود، بسته به میزان کاهش شارژ دستگاه).

با این حال، باید بدانید که توانایی بازنویسی در یک دستگاه محدود است و بیش از 100000 بار نیست. بنابراین توصیه می شود به داده های وارد شده دقت و توجه داشته باشید و دوباره آن را رونویسی نکنید.

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

  • ATmega328 - 1 کیلوبایت
  • ATmega168 و ATmega8 - 512 بایت،
  • و ATmega1280 – 4 کیلوبایت.

این به این صورت طراحی شده است زیرا هر میکروکنترلر برای حجم خاصی از کارها طراحی شده است، تعداد پین های متفاوتی برای اتصال دارد و بر این اساس، حافظه متفاوتی مورد نیاز است. علاوه بر این، این مقدار برای پروژه هایی که معمولا ایجاد می شوند کافی است.

نوشتن در EEPROM به زمان قابل توجهی نیاز دارد - تقریباً. 3 میلی ثانیه. اگر در حین ضبط برق قطع شود، داده ها اصلا ذخیره نمی شوند یا ممکن است اشتباه ضبط شوند. برای جلوگیری از خرابی در حین کار، همیشه لازم است اطلاعات وارد شده را نیز بررسی کنید. خواندن داده ها بسیار سریعتر است و منبع حافظه کاهش نمی یابد.

کتابخانه

کار با حافظه EEPROM با استفاده از کتابخانه ای که مخصوص آردوینو ایجاد شده است انجام می شود. اصلی ترین آنها توانایی نوشتن و خواندن داده ها است. با دستور فعال می شود #شامل EEPROM.h.

  • برای سوابق- EEPROM.write (آدرس، داده)؛
  • برای خواندن– EEPROM.read (آدرس).

در این طرح‌ها: آدرس – آرگومان با داده‌های سلولی که داده‌های آرگومان دوم در آن وارد می‌شود. هنگام خواندن، از یک آرگومان استفاده می شود، آدرس، که نشان می دهد اطلاعات باید از کجا خوانده شود.

تابع هدف
خواندن (آدرس) 1 بایت را از EEPROM می خواند. آدرس - آدرسی که داده ها از آن خوانده می شوند (سلول از 0 شروع می شود).
نوشتن (آدرس، ارزش) مقدار (1 بایت، عدد از 0 تا 255) را در حافظه در آدرس می نویسد.
به روز رسانی (آدرس، ارزش) اگر محتوای قدیمی آن با محتوای جدید متفاوت باشد، مقدار را در آدرس جایگزین می کند.
دریافت (آدرس، داده) داده های نوع مشخص شده را از حافظه در آدرس می خواند.
قرار دادن (آدرس، داده) داده هایی از نوع مشخص شده را در حافظه در آدرس می نویسد.
EEPROM به شما امکان می دهد از شناسه "EEPROM" به عنوان یک آرایه برای نوشتن داده ها و خواندن از حافظه استفاده کنید.

نوشتن اعداد صحیح

نوشتن اعداد صحیح در حافظه EEPROM غیر فرار بسیار ساده است. وارد کردن اعداد زمانی اتفاق می افتد که عملکرد راه اندازی می شود EEPROM.write(). داده های مورد نیاز در داخل پرانتز نشان داده شده است. در این حالت اعداد از 0 تا 255 و اعداد بالای 255 متفاوت نوشته می شوند. اولین ها به سادگی وارد می شوند - حجم آنها 1 بایت است، یعنی یک سلول. برای نوشتن دومی، باید از عملگرهای highByte() برای بالاترین بایت و lowByte() برای کمترین بایت استفاده کنید.

عدد به بایت تقسیم می شود و به طور جداگانه در سلول ها نوشته می شود. به عنوان مثال، عدد 789 در دو خانه نوشته می شود: اولی حاوی ضریب 3 و دومی حاوی مقدار گم شده است. نتیجه مقدار مورد نیاز است:

3 * 256 + 21 = 789

برای « reunion" عدد صحیح بزرگ اعمال می شود تابع کلمه(): int val = کلمه (سلام، کم). باید بخوانید که حداکثر عدد صحیح برای ضبط 65536 (یعنی 2 به توان 16) است. در سلول هایی که هنوز ورودی های دیگری نداشته اند، مانیتور اعداد 255 را در هر کدام نمایش می دهد.

نوشتن اعداد و رشته های ممیز شناور

اعداد ممیز شناور و رشته ای شکلی از نوشتن اعداد واقعی هستند که با یک مانتیس و یک توان نمایش داده می شوند. چنین اعدادی با فعال کردن تابع در حافظه EEPROM غیر فرار نوشته می شوند EEPROM.put()، خواندن، به ترتیب، - EEPROM.get().

هنگام برنامه نویسی، مقادیر عددی ممیز شناور به عنوان float تعیین می شوند؛ شایان ذکر است که این یک دستور نیست، بلکه یک عدد است. نوع کاراکتر (نوع کاراکتر) - برای نمایش رشته ها استفاده می شود. فرآیند نوشتن اعداد روی مانیتور با استفاده از setup()، خواندن - با استفاده از حلقه() شروع می شود.

در طول این فرآیند، مقادیر ovf به معنی «بیش از حد پر شده» و nan به معنای «فقدان» ممکن است روی صفحه نمایشگر ظاهر شوند. مقدار عددی" این بدان معنی است که اطلاعات نوشته شده در سلول را نمی توان به عنوان یک عدد ممیز شناور بازتولید کرد. اگر به طور قابل اعتماد بدانید که در کدام سلول چه نوع اطلاعاتی ثبت شده است، این وضعیت به وجود نمی آید.

نمونه هایی از پروژه ها و طرح ها

مثال شماره 1

این طرح حداکثر 16 کاراکتر را از پورت سریال می نویسد و 16 کاراکتر از EEPROM را در یک حلقه خروجی می دهد. به لطف این، داده ها در EEPROM نوشته می شوند و محتویات حافظه غیر فرار نظارت می شود.

// عملکرد EEPROM #include را بررسی کنید int i, d; void setup() ( Serial.begin(9600)؛ // مقداردهی اولیه پورت، سرعت 9600 ) void loop() (// خواندن EEPROM و خروجی 16 داده به پورت سریال Serial.println(); Serial.print("EEPROM = ")؛ i= 0؛ while(i< 16) { Serial.print((char)EEPROM.read(i)); i++; } // проверка есть ли данные для записи if (Serial.available() != 0) { delay(50); // ожидание окончания приема данных // запись в EEPROM i= 0; while(i < 20) { d= Serial.read(); if (d == -1) d= " "; // если символы закончились, заполнение пробелами EEPROM.write(i, (byte)d); // запись EEPROM i++; } } delay(500); }

مثال شماره 2

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

#عبارتند از آدرس int = 0; // آدرس eeprom int read_value = 0; // داده های خوانده شده از eeprom char serial_in_data; // داده های پورت سریال int led = 6; // خط 6 برای LED int i; void setup() (pinMode(led, OUTPUT)؛ // خط 6 به عنوان خروجی Serial.begin(9600) پیکربندی شده است؛ // نرخ باود در پورت سریال 9600 Serial.println(); Serial.println("متن قبلی در EEPROM" : -")؛ برای(آدرس = 0؛ آدرس< 1024; address ++) // считываем всю память EEPROM { read_value = EEPROM.read(address); Serial.write(read_value); } Serial.println(); Serial.println("WRITE THE NEW TEXT: "); for(address = 0; address < 1024; address ++) // заполняем всю память EEPROM пробелами EEPROM.write(address, " "); for(address = 0; address < 1024;) // записываем пришедшие с последовательного порта данные в память EEPROM { if(Serial.available()) { serial_in_data = Serial.read(); Serial.write(serial_in_data); EEPROM.write(address, serial_in_data); address ++; digitalWrite(led, HIGH); delay(100); digitalWrite(led, LOW); } } } void loop() { //---- мигаем светодиодом каждую секунду -----// digitalWrite(led, HIGH); delay(1000); digitalWrite(led, LOW); delay(1000); }

مثال شماره 3

دو عدد صحیح را در حافظه می نویسد، آنها را از EEPROM می خواند و به پورت سریال خروجی می دهد. اعداد از 0 تا 255 با استفاده از تابع، 1 بایت حافظه را اشغال می کنند EEPROM.write()در سلول مورد نظر نوشته می شوند. برای اعداد بزرگتر از 255 باید با استفاده از آنها به بایت تقسیم شوند highByte()و lowByte()و هر بایت را در سلول خود بنویسید. حداکثر عدد در این مورد 65536 (یا 2 16) است.

#عبارتند از // وصل کردن کتابخانه EEPROM void setup() (int smallNum = 123؛ // عدد صحیح از 0 تا 255 EEPROM.write(0, smallNum)؛ // یک عدد را در سلول 0 int bigNum = 789 بنویسید؛ // عدد را تقسیم کنید > 255 در 2 بایت (حداکثر 65536) بایت hi = highByte (bigNum)؛ // بایت بالا کم = کم بایت (bigNum)؛ // بایت کم EEPROM.write(1، hi)؛ // نوشتن بایت بالا EEPROM در سلول 1 .write(2, low); // نوشتن بایت کم در سلول 2 Serial.begin(9600)؛ // مقداردهی اولیه پورت سریال ) void loop() ( for (int addr=0; addr<1024; addr++) { // для всех ячеек памяти (для Arduino UNO 1024) byte val = EEPROM.read(addr); // считываем 1 байт по адресу ячейки Serial.print(addr); // выводим адрес в послед. порт Serial.print("\t"); // табуляция Serial.println(val); // выводим значение в послед. порт } delay(60000); // задержка 1 мин }

مثال شماره 4

روش نوشتن اعداد و رشته های ممیز شناور EEPROM.put(). خواندن - EEPROM.get().

#عبارتند از // کتابخانه void setup() را وصل کنید ( int addr = 0؛ // آدرس float f = 3.1415926f؛ // عدد ممیز شناور (نوع شناور) EEPROM.put(addr, f)؛ // عدد f را در آدرس بنویسید addr addr += sizeof(float)؛ // محاسبه نام کاراکتر سلول حافظه آزاد بعدی = "سلام، SolTau.ru!"؛ // ایجاد آرایه ای از کاراکترها EEPROM.put(addr, name)؛ // آرایه را بنویسید به EEPROM Serial.begin (9600); // مقداردهی اولیه پورت سریال ) void loop() ( for (int addr=0; addr<1024; addr++) { // для всех ячеек памяти (1024Б=1кБ) Serial.print(addr); // выводим адрес в послед. порт Serial.print("\t"); // табуляция float f; // переменная для хранения значений типа float EEPROM.get(addr, f); // получаем значение типа float по адресу addr Serial.print(f, 5); // выводим с точностью 5 знаков после запятой Serial.print("\t"); // табуляция char c; // переменная для хранения массива из 20 символов EEPROM.get(addr, c); // считываем массив символов по адресу addr Serial.println(c); // выводим массив в порт } delay(60000); // ждём 1 минуту }

مثال شماره 5

استفاده از EEPROM به عنوان یک آرایه

#عبارتند از void setup() (EEPROM = 11؛ // سلول اول را بنویسید EEPROM = 121؛ // سلول دوم را بنویسید EEPROM = 141؛ // سلول سوم را بنویسید EEPROM = 236؛ // سلول چهارم را بنویسید .begin(9600 ) ) void loop() ( for (int addr=0; adr<1024; addr++) { Serial.print(addr); Serial.print("\t"); int n = EEPROM; // считываем ячейку по адресу addr Serial.println(n); // выводим в порт } delay(60000); }

کار با EEPROM

همانطور که قبلا ذکر شد، حافظه EEPROM محدود است. برای افزایش طول عمر حافظه غیر فرار، به جای تابع write() بهتر است از تابع update استفاده کنید. در این مورد، بازنویسی فقط برای سلول هایی انجام می شود که مقدار آن با مقدار جدید نوشته شده متفاوت است.

یکی دیگر از عملکردهای مفید حافظه میکروکنترلر مورد بحث، توانایی استفاده از سلول های ذخیره سازی بایت به عنوان بخشی از یک آرایه یکپارچه EEPROM است. در هر قالب استفاده، لازم است به طور مداوم یکپارچگی داده های ثبت شده نظارت شود.

چنین حافظه ای در آردوینو به طور استاندارد مهمترین چیزها را برای عملکرد کنترلر و دستگاه ذخیره می کند. به عنوان مثال، اگر یک کنترل کننده دما بر اساس چنین مبنایی ایجاد شود و داده های اولیه اشتباه باشد، دستگاه با شرایط موجود "ناکافی" عمل می کند - دما را تا حد زیادی دست کم یا بیش از حد برآورد می کند.

چندین موقعیت وجود دارد که EEPROM حاوی داده های نادرست است:

  1. پس از فعال سازی اولیه، هنوز هیچ ورودی وجود ندارد.
  2. در طول یک قطع برق کنترل نشده، برخی یا همه داده ها ثبت نمی شوند یا به اشتباه ثبت می شوند.
  3. پس از تکمیل چرخه های احتمالی بازنویسی داده ها.

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

برای کنترل یکپارچگی اطلاعات از کد کنترل سیستم استفاده می شود. بر اساس ثبت داده های اصلی ایجاد می شود و پس از تأیید، داده ها را دوباره محاسبه می کند. اگر نتیجه متفاوت باشد، خطا است. متداول ترین نسخه چنین چکی یک چک جمع است - یک عملیات ریاضی ساده برای اضافه کردن تمام مقادیر سلول انجام می شود.

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

اینها اصول اولیه کار با حافظه EEPROM غیر فرار برای میکروکنترلرهای آردوینو هستند. برای پروژه های خاص ارزش استفاده از این نوع حافظه را دارد. هم مزایا و هم معایب خود را دارد. برای تسلط بر روش های نوشتن و خواندن، بهتر است از کارهای ساده شروع کنید.

تمام میکروکنترلرهای خانواده مگا شامل حافظه غیر فرار ( EEPROMحافظه). حجم این حافظه از 512 بایت در مدل های ATmega8x تا 4 کیلوبایت در مدل های قدیمی است. EEPROMحافظه در فضای آدرس خود قرار دارد و مانند RAM به صورت خطی سازماندهی شده است. برای کار با EEPROMحافظه از سه رجیستر I/O استفاده می کند: یک ثبات آدرس، یک ثبت داده و یک ثبات کنترل.

ثبت آدرس

ثبت آدرس EEPROMحافظه EEAR (رجیستر آدرس EEPROM)از نظر فیزیکی در دو قسمت قرار دارد RVV EEARH:EEARL، واقع در امتداد
آدرس های $1F ($3F) و $1E ($3E)، به ترتیب. این رجیستر با آدرس سلولی که به آن دسترسی خواهید داشت بارگذاری می شود. ثبت آدرس هم قابل نوشتن و هم قابل خواندن است. در همان زمان، در ثبت نام EEARHفقط از کم اهمیت ترین بیت ها استفاده می شود (تعداد بیت های درگیر بستگی به حجم دارد EEPROMحافظه). بیت های ثبت نام استفاده نشده EEARHفقط خواندنی هستند و حاوی "0" هستند.

ثبت داده ها

ثبت داده ها EEPROMحافظه EEDR (EEPROM Data Register)واقع در $1D ($3D). هنگام نوشتن در این ثبات، داده هایی بارگذاری می شوند که باید در آن قرار گیرند EEPROMو هنگام خواندن، داده ها از آن خوانده می شوند EEPROM.

ثبت کنترل

ثبت کنترل EEPROMحافظه EECR (رجیستر کنترل EEPROM)واقع در $1C ($3C). این رجیستر برای
کنترل دسترسی EEPROMحافظه توضیحات آن در جدول زیر آمده است:

تخلیه نام شرح
7..4 - استفاده نشده است، به عنوان "0" خوانده شود
3 وهم انگیز وقفه از EEPROM را فعال کنید. این بیت تولید یک وقفه را کنترل می کند که با تکمیل چرخه نوشتن EEPROM رخ می دهد. اگر این بیت روی "1" تنظیم شود، وقفه ها فعال می شوند (اگر پرچم I رجیستر باشد
SREG نیز روی "1" تنظیم شده است). وقتی بیت EEWE پاک شد (به ادامه مطلب مراجعه کنید
جدول) وقفه دائما ایجاد می شود
2 EEMWE کنترل مجوز نوشتن در EEPROM. وضعیت این بیت عملکرد پرچم فعال نوشتن EEWE را تعیین می کند. اگر این بیت روی "1" تنظیم شود، هنگام نوشتن روی بیت EEWE "1"، داده ها در EEPROM نوشته می شوند. در غیر این صورت، تنظیم EEWE روی "1" تاثیری ندارد. پس از نصب نرم افزار، بیت EEMWE توسط سخت افزار از طریق ریست می شود
4 چرخه ماشین
1 EEWE اجازه نوشتن در EEPROM. وقتی این بیت روی "1" تنظیم شود، داده ها روی EEPROM نوشته می شوند (اگر EEMWE برابر با "1" باشد)
0 EERE مجوز خواندن از EEPROM. پس از تنظیم این بیت روی "1"، داده ها از EEPROM خوانده می شوند. پس از اتمام خواندن، این بیت توسط سخت افزار ریست می شود

برای نوشتن یک بایت در EEPROM شما نیاز دارید:

1. صبر کنید تا EEPROM برای نوشتن داده ها آماده شود (صبر کنید تا پرچم EEWE رجیستر EECR تنظیم مجدد شود).

2. منتظر تکمیل نوشتن در حافظه برنامه FLASH (صبر کنید تا پرچم SPMEN ثبات SPMCR تنظیم مجدد شود).

3. بایت داده را در رجیستر EEDR و آدرس مورد نیاز را در رجیستر EEAR بارگذاری کنید (در صورت لزوم).

4. پرچم EEMWE ثبت EECR را روی "1" تنظیم کنید.

5. گزارش را در بیت EEWE رجیستر EECR بنویسید. "1" برای 4 چرخه ماشین. پس از نصب این بیت، پردازنده
قبل از اجرای دستور بعدی، 2 چرخه ماشین را رد می کند.

برای خواندن یک بایت از EEPROM شما نیاز دارید:

1. وضعیت پرچم EEWE را بررسی کنید. واقعیت این است که در حالی که یک عملیات نوشتن در حافظه EEPROM انجام می شود (پرچم EEWE تنظیم شده است)، نه خواندن حافظه EEPROM و نه تغییر رجیستر آدرس قابل انجام نیست.

2. آدرس مورد نیاز را در رجیستر EEAR بارگیری کنید.

3. بیت EERE رجیستر EECR را روی "1" تنظیم کنید.

هنگامی که داده های درخواستی در رجیستر داده EEDR قرار می گیرند، بازنشانی سخت افزاری این بیت رخ می دهد. با این حال، نظارت بر وضعیت بیت EERE برای تعیین زمان تکمیل عملیات خواندن ضروری نیست، زیرا یک عملیات خواندن از EEPROM همیشه در یک چرخه ماشین کامل می شود. علاوه بر این، پس از تنظیم بیت EERE روی "1"، پردازنده 4 چرخه ماشین را قبل از شروع دستورالعمل بعدی رد می کند.

محیط AVR Studio GCC دارای یک کتابخانه استاندارد برای کار با EEPROM است که با اتصال فایل فعال می شود. . توابع اصلی هستند eeprom_read_byte()، eeprom_write_byte()، eeprom_read_word()، eeprom_write_word().به عنوان مثال، بیایید یک برنامه برای یک مینی شمارنده از 0 تا 9 بنویسیم که با فشار دادن یک دکمه، یک مقدار اضافه می شود و دکمه دیگری این مقدار را در حافظه ذخیره می کند. میکروکنترلر Atmega8 از یک ژنراتور ساعت داخلی با فرکانس 8 مگاهرتز کار می کند. یک نشانگر هفت قطعه تک رقمی با یک آند مشترک از طریق مقاومت های محدود کننده جریان R1-R7 به پورت B متصل می شود، آند مشترک به منبع تغذیه پلاس متصل می شود. نمودار زیر نشان داده شده است:

ابتدا کتابخانه های لازم برای عملیات از جمله EEPROM را به هم وصل می کنیم. متغیرها را تعریف کنید. متغیر "s" مقدار خروجی را در نشانگر ذخیره می کند؛ وقتی دکمه SB1 را فشار می دهید، این مقدار یک افزایش می یابد، اما نه بیشتر از 10. متغیر eeprom_var با EEPROM تعامل خواهد داشت. هنگامی که برق روشن می شود، EEPROM خوانده می شود، داده های خوانده شده به متغیر "s" اختصاص می یابد، بر این اساس، یک عدد مشخص بر روی نشانگر نمایش داده می شود. وقتی SB2 را فشار می دهید، داده های متغیر "s" در EEPROM نوشته می شود و نشانگر یک بار چشمک می زند.

#عبارتند از #عبارتند از #عبارتند از #define d0 ~(0x3F) // 0 #define d1 ~(0x06) // 1 #define d2 ~(0x5B) // 2 #define d3 ~(0x4F) // 3 #define d4 ~(0x66) // 4 #define d5 ~(0x6D) // 5 #define d6 ~(0x7D) // 6 #define d7 ~(0x07) // 7 #define d8 ~(0x7F) // 8 #define d9 ~(0x6F) // 9 char s بدون امضا; char بدون امضا eeprom_var EEMEM; // یک متغیر در EEPROM int main (void) تعریف کنید (DDRB = 0xFF؛ // پورت B برای خروجی PORTB = 0xFF؛ DDRD = 0x00؛ // پورت D برای ورودی PORTD = 0xFF؛ // روشن کردن مقاومت‌های pull-up s = eeprom_read_byte(&eeprom_var ); // یک بایت از EEPROM را بخوانید و در "s" while(1) قرار دهید (if((PIND&(1<< PD0)) == 0) // если кнопка SB1 нажата { while((PIND&(1 << PD0)) == 0){} // ждем отпускания кнопки s++; // увеличиваем "s" на единицу _delay_ms(200); } if(s == 10) // Когда дойдет до 10 обнуляем "s" { s = 0; } if((PIND&(1 << PD1)) == 0) // если кнопка SB2 нажата { while((PIND&(1 << PD1)) == 0){} // ждем отпускания кнопки DDRB = 0xFF; // мигаем индикатором _delay_ms(200); DDRB = 0x00; _delay_ms(200); DDRB = 0xFF; eeprom_write_byte(&eeprom_var, s); // записываем "s" в EEPROM _delay_ms(200); } if(s==0) // Выводим цифры на индикатор PORTB = d0; if(s==1) PORTB = d1; if(s==2) PORTB = d2; if(s==3) PORTB = d3; if(s==4) PORTB = d4; if(s==5) PORTB = d5; if(s==6) PORTB = d6; if(s==7) PORTB = d7; if(s==8) PORTB = d8; if(s==9) PORTB = d9; } }

نظرات

0 AntonChip 05/02/2013 22:15

من از مکس نقل قول می کنم:

شاید من یه چیزی رو اشتباه میگیرم ولی اگه یه اندیکاتور با OA داشته باشی یک مقاومت روی خط 5 ولت کافیه چرا بعد از المنتی که قراره از جریان زیاد محافظت کنن مقاومت های محدود کننده جریان نصب کنیم؟؟


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

0 AntonChip 05/15/2013 11:16

از gydok نقل می کنم:

چگونه یک آرایه دو بعدی در eeprom بنویسیم؟


کد:
#عبارتند از // شامل کتابخانه

رنگهای کاراکتر بدون علامت EEMEM=((1، 2، 3)، // آرایه را در EEPROM اعلام کنید
{4, 5, 6}};

eeprom_write_byte(&colors, 1); // عناصر آرایه را در EEPROM بنویسید
eeprom_write_byte(&colors, 2);
eeprom_write_byte(&colors, 3);
eeprom_write_byte(&colors, 4);
eeprom_write_byte(&colors, 5);
eeprom_write_byte(&colors, 6);

دمای کاراکتر بدون علامت
temp = eeprom_read_byte(&colors); // استخراج عنصر آرایه از EEPROM, 2nd row(), 1st column(), i.e. شماره 4

بازنشانی حافظه EEPROM

مثال در تمام سلول های حافظه حلقه زده و صفر را روی آنها می نویسد.

// اتصال کتابخانه به کار با EEPROM. #include "EEPROM.h" void setup() ( // از تمام سلول ها (بایت ها) عبور کنید و در آنها صفر بنویسید. برای (int i = 0; i)< EEPROM.length(); i++) EEPROM.update(i, 0); } void loop() { // Пустой цикл... }


تنظیم مجدد کارخانه

اگر می خواهید حافظه را به تنظیمات کارخانه برگردانید، باید 0 را با 255 جایگزین کنید، یعنی. نه صفرها، بلکه عدد 255 را بنویسید. بنابراین، در آینده با استفاده از تابع isNaN() می توان بررسی کرد که آیا نوشتن در حافظه EEPROM انجام شده است یا خیر.

// اتصال کتابخانه به کار با EEPROM. #include "EEPROM.h" void setup() ( // از تمام سلول ها (بایت ها) عبور کنید و اعداد 255 را در آنها بنویسید. برای (int i = 0; i< EEPROM.length(); i++) EEPROM.update(i, 255); } void loop() { // Пустой цикл... }

از ما بگویید

پیام

اگر تجربه کار با آردوینو را دارید و واقعاً برای خلاقیت وقت دارید، از همه دعوت می کنیم تا نویسنده مقالات منتشر شده در پورتال ما شوند. این ها می توانند درس ها یا داستان هایی در مورد آزمایش های شما با آردوینو باشند. شرح انواع سنسورها و ماژول ها. نکات و دستورالعمل ها برای مبتدیان. مقالات خود را بنویسید و پست کنید