الکترونیک آموزش نکات برنامه نویسی در C برای میکرو کنترلر ها

اطلاعات موضوع

درباره موضوع در تاریخ, در دسته الکترونیک دیجیتال ایجاد شده و آغاز کننده آن Aliمی باشد و موضوع آن: نکات برنامه نویسی در C برای میکرو کنترلر ها است. این موضوع تا کنون 257 بازدید کننده و, 13 پاسخ داشته و 1 بار پسندیده شده...
نام دسته الکترونیک دیجیتال
نام موضوع نکات برنامه نویسی در C برای میکرو کنترلر ها
آغاز کننده موضوع Ali
تاریخ شروع
پاسخ‌ها
13
بازدیدها
257
پسندها
1
آخرین ارسال توسط Ali

Ali

مسئول نظارت بر محتوا
پرسنل مدیریت
ناظم انجمن
Jun 7, 2020
946
1,262
نکات برنامه نویسی در C برای میکرو کنترلر ها :

C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید
کد زیر اشتباه است :
C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید
در زبان C شما مستقیم نمیتوانید یک رشته را وارد یک Byte Array کنید و برای این کار باید از دستور زیر کمک بگیرید :
C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید

این کد، کاراکترهای "Hello world" را در آرایهٔ WrtieData کپی خواهد کرد. لطفاً توجه داشته باشید که باید اطمینان حاصل کنید که آرایهٔ شما دارای فضای کافی برای نگهداری رشتهٔ مدنظر داراست در غیر این صورت ممکن است با خطاهای buffer overflow مواجه شوید.
 

نکات برنامه نویسی در C برای میکرو کنترلر ها :

C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید
در هنگام برنامه نویسی میکروکنترلر ها یکی از نکاتی که باید بسیار به آن توجه کرد مدیریت حافظه میباشد زیرا حافظه ی بسیاری از میکروکنترلر ها به شدت محدود بوده و در هنگام کدنویسی اگر از روش های بهینه استفاده نکنیم ، ممکن است که حافظه ی میکروکنترلر پاسخگوی نیاز ما برای کامپایل تمام پروژه نباشد و خیلی از افراد در این مواقع تصمیم میگیرند که پردازنده ی خود را عوض کرده و یک پردازنده ی گران تر را جایگزین کنند و حتی سخت افزاری که برای پروزه خود طراحی کرده اند را کنار گذاشته و یک سخت افزار جدید برای پروژه خود و متناسب با پردازنده جدید طراحی کنند. این در صورتی است که با رعایت برخی نکات ممکن است که نیازی به انجام دادن چنین کاری نباشد و محصول خود را با هزینه کمتر تولید کرد
یکی از نکات مهم در مدیریت حافظه استفاده از توابع malloc , free میباشد :
تابع malloc :
تابع malloc برای تخصیص حافظه به اندازه‌ی خاصی به کار می‌رود. برای استفاده از تابع malloc، باید از کتابخانه‌ی stdlib.h استفاده شود. پارامتر ورودی این تابع، اندازه‌ی حافظه درخواستی است که قصد تخصیص آن را داریم. تابع malloc یک اشاره‌گر به حافظه‌ی تخصیص داده شده را برمی‌گرداند. در صورتی که حافظه‌ی درخواستی تخصیص داده نشود، تابع malloc مقدار NULL را برمی‌گرداند.

در زیر مثالی برای استفاده از تابع malloc آورده شده است:
C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید
در این مثال، یک اشاره‌گر به یک بلاک حافظه به اندازه ۱۰ عدد از نوع int تخصیص داده شده است. در ادامه، این بلاک حافظه با استفاده از حلقه تکمیل شده و سپس با استفاده از تابع free، آزاد شده است.

تابع free:
تابع free برای آزادسازی حافظه‌ی اختصاص یافته به یک اشاره‌گر استفاده می‌شود. تابع free به تنهایی می‌تواند به یک بلاک حافظه دسترسی داشته باشد که با استفاده از تابع malloc یا realloc تخصیص داده شده است. برای استفاده از تابع free، باید از کتابخانه‌ی stdlib.h استفاده شود.

در مثالی که بالا بیان شد ، پس از استفاده از بلاک حافظه‌ی تخصیص داده شده، با استفاده از تابع free، حافظه‌ی مربوط به آن بلاک آزاد شده است.
 
نکات برنامه نویسی در C برای میکرو کنترلر ها :

C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید
برای افزایش عملکرد برنامه، می توان از inline function استفاده کرد.
توابع inline برای بهینه‌سازی کد مورد استفاده قرار می‌گیرند. با استفاده از این توابع، کامپایلر می‌تواند بدنه‌ی تابع را در نقطه‌ی فراخوانی تابع در برنامه قرار داده و از این طریق از هزینه‌ی زمانی و حافظه‌ی مصرفی برای صدا کردن تابع در زمان اجرا کاست.

وقتی یک تابع به عنوان inline تعریف می‌شود، کامپایلر به جای ایجاد یک تابع جداگانه و فراخوانی آن در محل استفاده، بدنه تابع را به صورت مستقیم در محل فراخوانی قرار می‌دهد. به عبارت دیگر، هنگامی که تابعی را به صورت inline فراخوانی می‌کنیم، به جای اینکه کامپایلر به یک نقطه جداگانه در برنامه بروند و برای فراخوانی تابع به آنجا برگردند، بدنه تابع را مستقیماً در نقطه فراخوانی تعبیه می‌کنند.

بنابراین، با استفاده از inline، بجای ایجاد یک تابع و فراخوانی آن در برنامه، کد بدنه تابع به صورت مستقیم در محل فراخوانی قرار می‌گیرد. این باعث می‌شود که زمانی که برنامه اجرا می‌شود، زمان ایجاد تابع جداگانه برای فراخوانی، برای inline کاهش پیدا کند.
در زبان برنامه‌نویسی C، برای تعریف یک تابع به صورت inline، کلمه‌ی کلیدی inline در ابتدای تعریف تابع قرار می‌گیرد. برای مثال، تابع add را به صورت inline در زبان C می‌توان به شکل زیر تعریف کرد:
C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید

استفاده از inline در برنامه‌های C، به دلیل جایگزینی تابع با بدنه آن در محل فراخوانی، می‌تواند باعث افزایش سرعت اجرای برنامه شود، اگر از این قابلیت به درستی استفاده شود. این به این معنی است که در برنامه‌ای که از inline استفاده می‌کند، زمان اجرای برنامه ممکن است کوتاه‌تر باشد و سرعت آن بیشتر باشد.

اما این تفاوت در عمل ممکن است به دلیل محدودیت‌هایی در inline، غیر قابل توجه باشد. به عنوان مثال، تابع‌های بلند و پیچیده، به دلیل حجم زیاد کد، به‌صورت inline قابل قبول نیستند. همچنین، inline در برنامه‌هایی که از زمان اجرای برنامه مهمتر است، مانند سیستم‌های عامل، ممکن است به دلیل تلاش برای بهبود عملکرد، محدودیت داشته باشد.

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

برای مثال، می‌توانیم یک تابع inline برای تنظیم تایمر در میکروکنترلر AVR ایجاد کنیم. فرض کنید می‌خواهیم یک تایمر 8 بیتی در میکروکنترلر AVR تنظیم کنیم و زمان تنظیم آن بسیار حساس است. در این حالت، می‌توانیم از تابع inline برای بهینه‌سازی زمان اجرای تابع استفاده کنیم.

C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید

در این مثال، ابتدا تایمر 8 بیتی را با فرکانس کلاک 8 مگاهرتز تنظیم کرده و سپس با فراخوانی تابع set_timer_8bit، مقدار تایمر را به معادل 100 میلی ثانیه تنظیم می‌کنیم. با استفاده از inline در تعریف تابع set_timer_8bit، می‌توانیم زمان اجرای برنامه را بهبود بخشیم و کد بهینه‌تری برای میکروکنترلر AVR بنویسیم.
 
نکات برنامه نویسی در C برای میکرو کنترلر ها :

C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید

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

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

یکی از کاربردهای volatile در برنامه‌نویسی میکروکنترلرها است. برای مثال در میکروکنترلر AVR، ممکن است بخواهیم مقداری را در پورت ورودی‌ها خوانده و آن را به یک متغیر تخصیص دهیم. با تعریف این متغیر به عنوان volatile، کامپایلر مجبور است هر بار که مقدار پورت ورودی‌ها تغییر کرده است، مقدار آن را از مکان حافظه‌ی اصلی خوانده و به روز رسانی کند. بدون تعریف volatile، کامپایلر ممکن است بهینه‌سازی‌هایی انجام دهد که باعث نادرستی در کد برنامه شود.
برای مثال، فرض کنید که می‌خواهیم وضعیت یک پین ورودی را در میکروکنترلر AVR خوانده و در یک متغیر ذخیره کنیم. کد زیر را در نظر بگیرید:
C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید

در این کد، PINB به عنوان یک متغیر volatile تعریف شده است. در هر بار اجرای حلقه‌ی while، مقدار پورت ورودی‌ها را از آدرس 0x23 خوانده و در متغیر input ذخیره می‌کنیم. با تعریف PINB به عنوان volatile، کامپایلر مجبور است هر بار مقدار پورت ورودی‌ها را از حافظه‌ی اصلی خوانده و به روز رسانی کند. اگر این متغیر به عنوان volatile تعریف نشود، کامپایلر ممکن است مقدار پورت ورودی‌ها را در حافظه‌ی موقت ذخیره کرده و از آن استفاده کند، در حالی که واقعیتاً مقدار پورت ورودی‌ها تغییر کرده است.
مثال دوم :
در واحد ADC، مقدار ولتاژ ورودی به دستگاه تبدیل آنالوگ به دیجیتال اندازه‌گیری می‌شود و در یک متغیر ذخیره می‌شود. این متغیر باید به عنوان volatile تعریف شود تا هر بار که مقدار ولتاژ ورودی تغییر کند، به روز رسانی شود.
برای مثال، فرض کنید که می‌خواهیم مقدار ولتاژ ورودی به پین ADC0 را در یک متغیر ذخیره کنیم. کد زیر این کار را انجام می‌دهد:
C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید
در کل، استفاده از volatile بسیار مهم است در مواقعی که با متغیر‌هایی سروکار داریم که توسط سخت‌افزار و یا دیگر قسمت‌های برنامه تغییر مقدار داده می‌شوند.
 
کات برنامه نویسی در C برای میکرو کنترلر ها :

C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید
در زبان برنامه‌نویسی C، اشاره گر(Pointer) یک متغیر است که آدرس حافظه را نشان می‌دهد. به عبارت دیگر، اشاره گربه مکان دقیق در حافظه اشاره می‌کند.. با استفاده از پوینترها، می‌توان داده‌ها را از حافظه بخوانید، به حافظه بنویسید و یا به عنوان آرگومان در تابع‌ها استفاده کنید.
برای ایجاد یک اشاره گردر زبان C، از علامت * استفاده می‌شود. به عنوان مثال:
C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید
این کد یک اشاره گربه یک متغیر از نوع uint8_t تعریف می‌کند. برای دسترسی به محتوای آدرس مربوط به اشاره گر، از عملگر * استفاده می‌شود. به عنوان مثال
C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید

این برنامه از اشاره گرportc_ptr برای دسترسی به وضعیت پین‌های ورودی پورت C استفاده می‌کند. هر بار که وضعیت پین 0 پورت C تغییر کند، وضعیت همه پین‌های پورت B تغییر می‌کند.
تفاوت اصلی بین یک متغیر pointer و یک متغیر معمولی در C، در نحوه‌ی ذخیره‌سازی و نحوه‌ی دسترسی به مقدار آن‌ها است. در حالی که یک متغیر معمولی دارای مقدار خود است و می‌توان به آن به صورت مستقیم اشاره کرد، یک متغیر pointer فقط آدرس متغیر دیگری را نگه‌داری می‌کند و برای دسترسی به مقدار آن متغیر، باید از عملگر (*) استفاده کرد.

برای مثال، فرض کنید یک متغیر عددی به نام x و یک متغیر pointer به نام p در برنامه AVR خود داریم. اگر مقدار x برابر با 10 باشد، برای نمایش مقدار x در مانیتور سریال، می‌توان به دو روش زیر عمل کرد:

1- استفاده از متغیر x:
C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید

در این روش، مقدار متغیر x را به رشته تبدیل کرده و با استفاده از تابع uart_puts، رشته را در مانیتور سریال نمایش می‌دهیم.

2- استفاده از متغیر pointer:
C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید
در این روش، یک متغیر pointer به نام p به آدرس متغیر x اشاره می‌کند. سپس با استفاده از تابع sprintf، مقدار متغیر x را به رشته تبدیل کرده و با استفاده از تابع uart_puts، رشته را در مانیتور سریال نمایش می‌دهیم

سایز یک اشاره‌گر در میکروکنترلرهای مختلف می‌تواند متفاوت باشد و این بسته به ساختار میکروکنترلر و نوع آن بستگی دارد. برای مثال، در برخی از میکروکنترلرها مانند AVR، سایز یک اشاره‌گر 2 بایت است که به این معناست که اشاره‌گر برای نگهداری آدرس حافظه، دو بایت از حافظه را اشغال می‌کند. در مقابل، در برخی دیگر از میکروکنترلرها مانند ARM، سایز یک اشاره‌گر 4 بایت است.

در زبان C برای بدست آوردن سایز یک اشاره‌گر می‌توان از اندازه‌گیری سایز یک متغیر pointer به کمک دستور sizeof استفاده کرد. برای مثال، برای بدست آوردن سایز یک اشاره‌گر ، می‌توان به صورت زیر عمل کرد:
C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید
 
کات برنامه نویسی در C برای میکرو کنترلر ها :


C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید

Overview :
بطور کلی می‌توانیم استک را به عنوان یک حافظه موقت برای داده‌ها توصیف کنیم. دسترسی به داده‌ها در استک بطور Last In First Out (LIFO) یا به عبارتی آخرین داده‌ای که در استک ذخیره شده است اولین داده است که می‌تواند بازیابی شود و اولین داده‌ای که در استک ذخیره شده است آخرین داده است که می‌تواند بازیابی شود. عمل افزودن داده به استک PUSH نامیده می‌شود و عمل بازیابی داده به POP یا PULL معروف است.
Stack Usage in Programming Languages
اکثریت قریب به اتفاق زبان های برنامه نویسی که توابع را پیاده سازی می کنند از یک Stack(پشته) استفاده می کنند. به هر تابع بخش مخصوص به خود از حافظه داده می شود تا در آن کار کند. این بخش بخشی از Stack است و به عنوان Stack frame نامیده می شود. معمولاً شامل اجزای زیر است
آدرس برگشتی (وقتی تابع کامل شد به فراخوانی تابع برمی گردد)
آرگومان ها به تابع منتقل می شوند
متغیرهای محلی تابع
کپی های ذخیره شده از هر register که توسط تابع تغییر یافته و باید بازیابی شود.

وقتی یک برنامه وارد یک تابع می‌شود، فضایی در بالای stack تخصیص داده می‌شود. وقتی برنامه از تابع خارج می‌شود، فضا آزاد می‌شود. عمر متغیرها در stack ، محدود به مدت زمان اجرای تابع است. داده‌هایی که باید بین فراخوانی‌های تابع ذخیره شوند، در heap ذخیره می‌شوند.
Usage in Microprocessors

استفاده از Stack برای سیستم های embedded بسیار حیاتی است و تنظیم آن به درستی برای پایداری و اعتماد سیستم بسیار حائز اهمیت است. دست کم گرفتن استفاده از Stack، مشکلات جدی مانند متغیرهای Overwrite شده ،اشاره گرهای Uninitialized و corrupted return addresses ایجاد می کند.

متغیرهای Overwrite :
به متغیرهایی اطلاق می‌شود که مقدار آن‌ها به طور ناخواسته توسط برنامه دیگری تغییر داده شده است.. این اتفاق می‌تواند باعث خرابی برنامه و در نتیجه بروز مشکلات جدی مانند عدم پاسخگویی و حتی از دست دادن داده‌های مهم شود.

اشاره‌گرهای Uninitialized :
اشاره‌گرهایی هستند که به یک مکان مشخص در حافظه اشاره می‌کنند، اما به آن مقداری داده نشده است. به عبارت دیگر، مقدار داخل حافظه که به آن اشاره می‌شود تعیین نشده است. استفاده از اشاره‌گرهای Uninitialized می‌تواند باعث بروز مشکلات جدی در برنامه شود مانند کرش کردن برنامه، تغییر غیرمنتظره مقادیر در حافظه و یا بروز خطاهای دیگر در زمان اجرای برنامه. بنابراین این مهم است که در هنگام تعریف و استفاده از اشاره‌گرها، ابتدا مقدار آن‌ها تعیین شود.

corrupted return addresses:

در برنامه نویسی، زمانی که یک تابع فراخوانی می شود، برنامه به داخل تابع می رود و پس از اجرای تابع، برنامه باید به ادامه خطی که قبل از فراخوانی تابع وجود داشت، بازگردد. این خط با استفاده از یک متغیر به نام return address ذخیره می شود. اگر در حین اجرای تابع، این متغیر به هر دلیلی دچار خرابی شود، برنامه بعد از پایان تابع به جای بازگشت به ادامه خط، به جای آن به یک محل تصادفی در حافظه می رود که ممکن است عواقب خطرناکی داشته باشد. به این مشکل "corrupted return address" یا "آدرس بازگشتی خراب شده" گفته می شود.
 
نکات برنامه نویسی در C برای میکرو کنترلر ها :


C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید
چدر میکروکنترلرها، Heap یک بخش از حافظه است که برای ذخیره داده ها در حین اجرای برنامه استفاده می شود. Heap شامل یک فضای ذخیره‌سازی دینامیکی است که برای ایجاد و حذف داده ها به کار می رود و برای ذخیره‌سازی داده هایی که اندازه آن ها در زمان کامپایل مشخص نمی شود، استفاده می شود. این حافظه برای استفاده از داده هایی که در زمان اجرای برنامه ایجاد می شوند، به کار می رود.

به عبارت دیگر، Heap یک منبع حافظه است که به صورت پویا توسط برنامه در زمان اجرا مدیریت می شود. برای تخصیص حافظه در Heap، باید از توابعی مانند malloc و calloc در زبان برنامه‌نویسی C استفاده کرد. این توابع به کاربر اجازه می دهند تا در زمان اجرا به صورت پویا حافظه اختصاص دهند.

در صورت استفاده نادرست از Heap ممکن است با مشکلاتی مانند Fragmentation و Memory Leaks مواجه شوید که می توانند باعث کاهش عملکرد برنامه شوند و حتی باعث خرابی سیستم شوند. بنابراین، استفاده صحیح از Heap و دقت در مدیریت حافظه می تواند بهبود قابل توجهی در عملکرد برنامه و کاهش احتمال خطاهای رخ داده در سیستم داشته باشد.

مثال ۱:
فرض کنید که در برنامه‌ی شما، باید یک آرایه‌ی دو بعدی با ابعاد مشخصی ایجاد کنید. در این صورت، شما می‌توانید از Heap برای ایجاد آن استفاده کنید. در ابتدا با توابع مانند malloc یا calloc، فضای حافظه‌ای را به اندازه‌ی مورد نیاز تخصیص می‌دهید، سپس آرایه‌ی دو بعدی را در آنجا ایجاد می‌کنید.

C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید





(توضیح int** باشه طلبتون )

در این مثال، یک آرایه‌ی دو بعدی به ابعاد ۵ در ۱۰ ایجاد شده است. ابتدا یک آرایه‌ی از اشاره‌گرها با اندازه rows ایجاد شده است، سپس به ازای هر ردیف، یک آرایه‌ی جدید با اندازه cols و به ازای هر ستون، با اندازه یک integer ایجاد می‌شود. هر اشاره‌گر به آرایه‌ی سطری در arr اشاره می‌کند.

مثال ۲:
یکی دیگر از مثال‌های استفاده از Heap، ایجاد یک رشته (string) با طول نامعلوم است. به جای تعریف یک آرایه‌ی ثابت برای رشته، می‌توانید از Heap استفاده کنید تا حافظه‌ای به اندازه‌ی لازم تخصیص دهید. برای این کار می‌توانید از تابع malloc استفاده کنید.

C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید

در این مثال، یک رشته به طول ۱۰۰ با استفاده از malloc ایجاد شده است. سپس با تابع strcpy، متن مورد نظر به رشته انتقال داده شده و در نهایت با تابع printf، رشته چاپ می‌شود. در پایان نیز با استفاده از تابع free، حافظه‌ی تخصیص داده شده به رشته با استفاده از malloc آزاد می‌شود تا از ایجاد حافظه‌ی غیر ضروری جلوگیری شود.

توجه کنید که استفاده از heap باید با دقت و با توجه به نیاز برنامه‌ی شما باشد. همچنین، پس از اتمام کار با حافظه‌ی تخصیص داده شده در Heap، باید آن را با تابع free آزاد کنید تا از حافظه‌ی غیر ضروری جلوگیری شود.
 
نکات برنامه نویسی در C برای میکرو کنترلر ها :


C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید
در زبان برنامه‌نویسی C، pointer to pointer برای زمانی استفاده می‌شود که می‌خواهیم آدرس یک pointer دیگر را ذخیره کنیم. pointer اول برای ذخیره آدرس متغیر استفاده می‌شود و pointer دوم برای ذخیره آدرس pointer اول استفاده می‌شود. به همین دلیل آن‌ها را double-pointer می‌نامند. می‌توان از یک pointer to pointer برای تغییر مقادیر پوینترهای معمولی یا ایجاد آرایه 2 بعدی به اندازه متغیر استفاده کرد. یک double-pointer در حافظه نیز همان فضایی که یک pointer معمولی به خود اختصاص می‌دهد را اشغال می‌کند.
• تعریف pointer to pointer در زبان برنامه‌نویسی C
تعریف pointer to pointer در زبان برنامه‌نویسی C شبیه تعریف یک pointer است، با این تفاوت که باید یک '*' اضافی قبل از نام پوینتر قرار داده شود.
C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید

این کد یک نمونه از تعریف یک پوینتر به پوینتر در زبان برنامه‌نویسی C است. در این مثال، ما یک متغیر از نوع int به نام "val" داریم که یک مقدار عددی به آن اختصاص داده شده است. سپس با استفاده از یک پوینتر معمولی به نام "ptr"، آدرس متغیر "val" را ذخیره می‌کنیم. در ادامه، با استفاده از یک پوینتر به پوینتر به نام "d_ptr"، آدرس پوینتر "ptr" را نیز ذخیره می‌کنیم. در واقع، "d_ptr" به یک پوینتر معمولی اشاره می‌کند که خود به پوینتر "val" اشاره دارد.

در کلیت، تعریف پوینتر به پوینتر به ما این امکان را می‌دهد که به پوینترها به عنوان یک متغیر دسترسی داشته باشیم و آدرس آنها را در یک پوینتر دیگر ذخیره کنیم. این کار برای مواردی مانند ایجاد آرایه‌های چند بعدی با اندازه متغیر قابل تغییر مفید است.
این کد یک نمونه از استفاده از پوینتر به پوینتر (double pointer) در زبان برنامه‌نویسی C است:
C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید
این برنامه، مثالی از استفاده از Double Pointer در زبان C است. در ابتدا یک متغیر به نام var از نوع integer با مقدار 789 تعریف شده است. سپس یک pointer به نام ptr2 برای متغیر var تعریف شده و آدرس آن در این pointer ذخیره شده است. در ادامه یک double pointer به نام ptr1 تعریف شده و آدرس pointer ptr2 در آن ذخیره شده است.

در خطوط بعدی، مقدار متغیر var با استفاده از هر دو single pointer و double pointer چاپ شده است. ابتدا مقدار متغیر var، سپس با استفاده از pointer ptr2 و در نهایت با استفاده از double pointer ptr1 و ptr2 چاپ شده است.

در نتیجه، این برنامه خروجی زیر را تولید می‌کند:

C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید

کاربرد double pointer در تعریف ارایه های 2 بعدی :

ما می‌توانیم با استفاده از double pointer به آرایه‌های دو بعدی دسترسی داشته باشیم. در این حالت، ما یک single pointer برای هر سطر از آرایه و یک double pointer برای نشان دادن سطرهای آرایه داریم. برای مثال، فرض کنید می‌خواهیم آرایه‌ای دو بعدی با اندازه 3*3 از نوع int تعریف کنیم. می‌توانیم به شکل زیر این کار را انجام دهیم:

C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید


این برنامه یک آرایه دو بعدی با اندازه 3 در 3 تعریف می‌کند و سپس به صورت دستی مقادیر آن را پر می‌کند. بعد از آن، تمام مقادیر آرایه چاپ می‌شوند. در انتها، حافظه مربوط به آرایه را آزاد می‌کند.

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

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

خروجی این تابع، ماتریس ۳ در ۳ زیر را در خروجی چاپ می‌کند و سپس حافظه‌ی اختصاص داده شده به ماتریس را آزاد می‌کند:

0 1 2
1 2 3
2 3 4


• تفاوت بین استفاده از double pointer و تعریف معمولی برای آرایه های 2 بعدی در C، به دو دلیل اصلی برمی‌گردد: دسترسی به عناصر و اختصاص حافظه.

در تعریف معمولی آرایه دو بعدی، می‌توان عناصر آن را به صورت مستقیم با نشانی آنها در حافظه دسترسی داد. برای مثال، اگر یک آرایه دو بعدی به نام arr با ابعاد 3 در 3 داشته باشیم، می‌توان به عناصر آن با استفاده از فرمول arr[j] دسترسی داشت. اما در استفاده از double pointer، نیاز است که در ابتدا فضای حافظه برای سطرها تخصیص داده شود، و سپس برای هر سطر، فضای حافظه برای ستون‌ها تخصیص داده شود. در این روش، ابتدا یک اشاره‌گر از نوع int ** برای سطرها تعریف می‌شود، سپس برای هر سطر، یک اشاره‌گر جدید از نوع int * تعریف می‌شود که به فضای حافظه برای ستون‌های آن سطر اشاره می‌کند.

به عبارت دیگر، در تعریف معمولی، فضای حافظه برای تمام آرایه در یک بلاک در نظر گرفته می‌شود و ابعاد آن در زمان کامپایل مشخص می‌شود. اما در double pointer، اولاً باید حافظه برای اشاره‌گرهای سطرها تخصیص داده شود، سپس برای هر سطر، باید فضای حافظه برای ستون‌های آن تخصیص داده شود. به عنوان نتیجه، double pointer می‌تواند انعطاف‌پذیری بیشتری در استفاده از حافظه داشته باشد، اما در عوض، ایجاد آن بیشتر از زمان و تلاش می‌طلبد.
استفاده از double pointer برای تعریف آرایه های دو بعدی در C، مزیت های زیر را دارد:

1. اختصاص دادن حافظه دقیق: با استفاده از double pointer، می‌توانید دقیقاً مشخص کنید که چه مقدار حافظه برای آرایه شما اختصاص داده می‌شود. این باعث می‌شود که از حافظه بیشتر و نامطمئن استفاده نکنید و به راحتی از حافظه کمتری برای برنامه خود استفاده کنید.

2. قابلیت تغییر اندازه: استفاده از double pointer می‌تواند به شما امکان تغییر اندازه آرایه را بدهد. به عنوان مثال، می‌توانید بعد از تخصیص حافظه برای یک آرایه ۲ بعدی با استفاده از double pointer، اندازه آن را تغییر دهید و از آن به عنوان یک آرایه با ابعاد جدید استفاده کنید.

3. افزایش سرعت: استفاده از double pointer می‌تواند به طراحی و اجرای سریعتر برنامه شما کمک کند، زیرا برنامه شما برای دسترسی به داده‌ها، فقط باید به یک اشاره‌گر (pointer) دسترسی داشته باشد که به اشاره‌گر دیگری اشاره می‌کند.
 
نکات برنامه نویسی در C برای میکرو کنترلر ها :

C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید
استفاده از روش زیر برای گذاشتن صفر در پشت عدد غلط است :
C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید

اگر بخواهیم با استفاده از تابع sprintf در پشت عدد صفر بگذاریم مثلا (002 ) را نمایش دهیم از روش زیر استفاده میکنیم :
C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید


در این کد، ابتدا محدوده‌هایی که ورودی در آن قرار دارد بررسی می‌شوند. اگر عدد کوچکتر از 10 باشد، یعنی تنها یک رقم دارد، دو صفر به پشت آن اضافه می‌شود و به عنوان خروجی یک رشته با سه رقم اعشاری تولید می‌شود. اگر عدد بین 10 تا 100 باشد، یعنی دو رقم دارد، یک صفر به پشت آن اضافه می‌شود و به عنوان خروجی یک رشته با دو رقم اعشاری تولید می‌شود. و اگر عدد بین 100 تا 1000 باشد، یعنی سه رقم دارد، هیچ صفری به پشت آن اضافه نمی‌شود و به عنوان خروجی یک رشته با یک رقم اعشاری تولید می‌شود.
 
نکات برنامه نویسی در C برای میکرو کنترلر ها :

C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید
در زبان برنامه‌نویسی enum یک نوع داده‌ای است که برای تعریف یک مجموعه مقادیر ثابت استفاده می‌شود. کلمه enum به معنای enumeration (شمارش) است و از آن برای تعریف مجموعه‌ای از مقادیر ثابت استفاده می‌شود که قابل شمارش هستند.

با استفاده از enum، می‌توانید یک مجموعه از عناصر ثابت(که به عنوان عضوهای enum شناخته می‌شوند) را تعریف کنید.


ثابت های از نوع enum نیز قابل تعریف هستند. این ثابت ها را می‌توان به دو روش تعریف کرد :

C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید
مقدار default value ثابت های enum از اولین ثابت با شماره صفر مقدار دهی شده و همین ترتیب متغیر بعدی 1 وبعدی 2 و.... مقدار دهی میشود .
مثال های زیر را مشاهده کنید

این برنامه یک مثال ساده است که نحوه کار با enum در زبان C را نشان می‌دهد. کد زیر را بررسی کنید:

C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید


خروجی (Output) این برنامه عدد 2 است. این به این دلیل است که در enum week، مقدار Wed به عنوان سومین ثابت تعریف شده است و بازنمایی عددی آن برابر با 2 است. بنابراین، در خط printf، عدد 2 چاپ می‌شود.

مثال بعدی :

C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید

در این مثال، یک enum به نام SystemState تعریف شده است که شامل ثابت‌های IDLE، BUSY و ERROR است. این enum برای نشان دادن حالت‌های مختلف سیستم استفاده می‌شود.

تابع updateSystem نیز تعریف شده است که ورودی آن یک متغیر از نوع SystemState است. در این تابع، با استفاده از switch، عملیات‌های مربوط به هر حالت سیستم انجام می‌شود. برای هر حالت، یک بلوک کد مشخص وجود دارد که عملیات مربوط به آن حالت را انجام می‌دهد.

در تابع main نیز از تابع updateSystem برای تنظیم سیستم در حالت BUSY استفاده شده است. در نهایت، مقدار 0 به عنوان خروجی برگشتی main بازگشت داده می‌شود.

به این ترتیب، این برنامه با استفاده از enum و تابع updateSystem، قادر است تا عملیات مربوط به هر حالت سیستم را انجام دهد و در این مثال، سیستم در حالت BUSY تنظیم شده است.
 
نکات برنامه نویسی در C برای میکرو کنترلر ها :


C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید
در زبان برنامه‌نویسی C، "struct" یک کلمه کلیدی است که برای تعریف یک نوع دادهٔ ساختاری (structure) استفاده می‌شود. یک ساختار مجموعه‌ای از متغیرها است که به صورت یک واحد مجزا مدلسازی می‌شوند و به عنوان یک نوع داده جدید تعریف می‌شوند. این متغیرها می‌توانند انواع داده‌های مختلفی مانند اعداد صحیح، اعداد اعشاری، رشته‌ها و غیره باشند.

ساختارها (structs) به برنامه‌نویسان اجازه می‌دهند تا اطلاعات مرتبط را در یک متغیر ترکیبی جمع‌آوری کنند. این کار باعث می‌شود کد خوانا‌تر، قابل توسعه‌تر و قابل نگهداری‌تر شود. به عبارت دیگر، می‌توانید یک ساختار را به عنوان یک "کانتینر" از متغیرها در نظر بگیرید که این متغیرها می‌توانند به طور مستقل یا در کنار یکدیگر استفاده شوند.

برای تعریف یک ساختار، ابتدا باید الگوی ساختار را تعریف کنید. این الگو شامل نام ساختار و نوع و تعداد فیلدهایی است که در آن قرار دارند. به عنوان مثال، فرض کنید می‌خواهید یک ساختار برای نمایش یک کتاب تعریف کنید که شامل عنوان، نویسنده و سال انتشار است. شما می‌توانید ساختار زیر را برای این منظور تعریف کنید:

C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید


در این مثال، "Book" نام ساختار است و سه فیلد با نوع‌های داده‌ای مختلف در آن تعریف شده است: "title" یک رشته با حداکثرطول 100 کاراکتر، "author" یک رشته با حداکثر طول 100 کاراکتر و "year" یک عدد صحیح است.

با تعریف این ساختار، شما می‌توانید متغیرهایی از نوع "Book" بسازید و از فیلدهای داخلی آن‌ها استفاده کنید. به عنوان مثال:

C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید


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

بنابراین، تفاوت اصلی بین "struct" و "enum" در این است که "struct" یک نوع داده ساختاری است که مجموعه‌ای از فیلدها را در خود جمع‌آوری می‌کند، در حالی که "enum" برای تعریف مجموعه‌ای از ثابت‌ها با مقادیر صحیح استفاده می‌شود.

در برنامه‌نویسی میکروکنترلرها، می‌توانید از ساختارها برای نگهداری و مدیریت اطلاعات مربوط به ماژول‌ها و واحدهای مختلف استفاده کنید. در مثال زیر، یک نمونه از استفاده از ساختار (struct) در واحد RTC (Real-Time Clock) برای میکروکنترلر LPC1768 آورده شده است:

C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید


در این مثال، یک ساختار به نام "DateTime" تعریف شده است که شامل فیلدهای مربوط به زمان و تاریخ می‌باشد. سپس، تابع "getDateTime" تعریف شده است که از RTC (Real-Time Clock) مقادیر زمان و تاریخ فعلی را دریافت کرده و در ساختار DateTime ذخیره می‌کند.

در نهایت، خروجی شبیه زیر در خروجی نمایش داده می‌شود:
Current date and time: 12/05/2023 15:30:45


در این مثال، ساختار struct برای نگهداری اطلاعات زمان و تاریخ در برنامه‌نویسی میکروکنترلر LPC1768 استفاده شده است. این نمونه نشان می‌دهد که با استفاده از ساختارها، می‌توانید اطلاعات را سازماندهی کرده و به آسانی آنها را دریافت و استفاده کنید.
 
نکات برنامه نویسی در C برای میکرو کنترلر ها :


تفاوت += ,=+

در زبان برنامه‌نویسی C، عملگرهای += و =+ دو عملگر جداگانه هستند و تفاوت‌های مهمی در عملکرد آنها وجود دارد.

1. +=:
عملگر =+ یک عملگر ترکیبی است که به متغیر ارزشی را اضافه می‌دهد و سپس نتیجه را به همان متغیر اختصاص می‌دهد. به طور خلاصه، x += y برابر است با x = x + y. بدین ترتیب، مقدار متغیر x با ارزش y افزایش می‌یابد.

مثال:
C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید


2. =+:
عملگر += در زبان C به صورت تفکیکی از دو عملگر تشکیل شده است. عملگر = برای اختصاص مقدار به یک متغیر استفاده می‌شود، و عملگر + برای انجام عملیات جمع بین دو عدد استفاده می‌شود. بنابراین، وقتی از x =+ y استفاده می‌کنیم، به واقع معادل x = +y خواهیم داشت. به طور خلاصه، مقدار متغیر x برابر با عدد مثبت y قرار می‌گیرد.

مثال:
C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید


بنابراین، تفاوت اصلی بین += و =+ در C در این است که += مقدار را به متغیر اضافه می‌کند، در حالی که += مقدار را به صورت مثبت به متغیر اختصاص می‌دهد.

بنابراین، پس از اجرای کد زیر:
C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید

مقادیر متغیرها به ترتیب به شکل زیر تغییر می‌کنند:
- x برابر -10 می‌شود.
- y برابر -20 می‌شود.
- z برابر +20 می‌شود.

توجه کنید که z برابر +20 است، زیرا y مقدار -20 داشت و با +=، +y به عنوان عدد مثبت به z اختصاص داده شده است.
 
کات برنامه نویسی در C برای میکرو کنترلر ها :


C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید

متغیرها می‌توانند با استفاده از کلمه کلیدی const و پیش پردازنده #define به عنوان ثابت تعریف شوند. جزئیات درباره این دو روش به شرح زیر آمده است.

کلمه کلیدی const:
متغیرها می‌توانند با استفاده از کلمه کلیدی "const" قبل از نوع داده‌ای متغیر به عنوان ثابت تعریف شوند. متغیرهای ثابت فقط یک بار می‌توانند مقداردهی اولیه شوند و مقدار پیش‌فرض آنها صفر است.

برنامه‌ای که نمونه‌ای از تعریف متغیرهای ثابت در زبان برنامه‌نویسی C با استفاده از کلمه کلیدی const را نشان می‌دهد به شرح زیر است:

C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید


خروجی این برنامه به شرح زیر است:

مقدار پیش‌فرض متغیر a: 0
مقدار متغیر b: 12


دستور قبل پردازنده #define:
متغیرها می‌توانند با استفاده از دستور پیش پردازنده #define به عنوان ثابت تعریف شوند، زیرا این دستور یک نام مستعار برای هر مقدار تعریف می‌کند.

برنامه‌ای که نمونه‌ای از تعریف متغیرهای ثابت در زبان برنامه‌نویسی C با استفاده از دستور قبل پردازنده #define را نشان می‌دهد به شرح زیر است:

C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید


خروجی این برنامه به شرح زیر است:

مقدار num برابر است با: 25


در ادامه، تفاوت‌های مهم بین const و ماکروها را بررسی می‌کنیم:

1. زمانی که تعریف می‌شوند:
- const: متغیرهای ثابت با استفاده از کلمه کلیدی const در زمان کامپایل تعریف می‌شوند. آنها به عنوان متغیرهای با نوع داده در کد شناخته می‌شوند و مقدار آنها را نمی‌توان در طول اجرای برنامه تغییر داد.
- ماکروها: ماکروها با استفاده از دستور پیش پردازنده #define تعریف می‌شوند. آنها بیشتر به عنوان جایگزینی متنی برای مقادیر استفاده می‌شوند. ماکروها در زمان قبل از فرآیند کامپایل، برای تغییر کدهای متنی بکار می‌روند و بعد از آن در برنامه نهایی وجود ندارند.

2. بررسی و نوع داده:
- const: متغیرهای ثابت معمولاً دارای نوع داده‌ای هستند و به صورت استاندارد در زبان‌های برنامه‌نویسی دارای بررسی نوع داده هستند. این به این معناست که کامپایلر قادر است از قوانین نوع داده استفاده کند و خطاها را چک کند.
- ماکروها: ماکروها در واقع متنی هستند که در هر جایی که ماکرو فراخوانی می‌شود، جایگزینی می‌شوند. زیرا ماکروها قبل از فرآیند کامپایل تبدیل می‌شوند، بنابراین نوع داده‌ای ندارند و تنها به متن جایگزین شده می‌شوند.

3. محدوده قابل دسترسی:
- const: متغیرهای ثابت معمولاً دارای محدوده قابل دسترسی است. به این معنا که آنها فقط در دامنه‌ای که تعریف شده‌اند، قابل دسترسی هستند.
- ماکروها: ماکروها به صورت جایگزینی متنی عمل می‌کنند و به هر جایی که ماکرو فراخوانی می‌شود، جایگزین می‌شوند. بنابراین، ماکروها دارای محدوده قابل دسترسی مستقلی نیستند و در تمام برنامه قابل دسترسی هستند.

4. عملکرد:
- const: متغیرهای ثابت در زمان اجرای برنامه به صورت مستقیم استفاده می‌شوند. آنها در حافظه ذخیره می‌شوند و به عنوان یک مکانیزم قابل اعتماد برای تعریف مقادیر ثابت عمل می‌کنند.
- ماکروها: ماکروها قبل از فرآیند کامپایل جایگزینی می‌شوند و هیچ محلی در حافظه اشغال نمی‌کنند. به عنوان یک جایگزینی متنی کار می‌کنند و مقدار ماکرو در کل برنامه جایگزین می‌شود.


در زمینه برنامه‌نویسی با متغیرهای ثابت (constants)، می‌توان به نکات زیر اشاره کرد:

1. تعریف مقدار اولیه: متغیرهای ثابت باید در هنگام تعریف مقدار اولیه داشته باشند و بعد از آن نمی‌توانند تغییر کنند. بنابراین، حتماً باید در زمان تعریف مقدار اولیه متغیر ثابت را ارائه دهید.

2. نامگذاری مناسب: برای متغیرهای ثابت، نامگذاری مناسبی انتخاب کنید تا مفهوم و مقصود مقدار ثابت را به خوبی بیان کند. استفاده از نامهای توصیفی و معنی‌دار می‌تواند بهبود خوانایی کد شما را فراهم کند.

3. استفاده در جای مناسب: از متغیرهای ثابت در جاهایی استفاده کنید که مقادیر آنها ثابت باقی می‌مانند و نیازی به تغییر ندارند. این شامل مقادیر ثابت در فرمول‌ها، ثوابت ریاضی، کدهای ثابت و مقادیر پیش‌فرض می‌شود.


استفاده صحیح از متغیرهای ثابت در برنامه‌نویسی می‌تواند کد شما را قابل فهم‌تر، قابل نگهداری‌تر و کارآمدتر کند. با توجه به ویژگی‌های ثابت، می‌توانید در برنامه‌نویسی خود از آنها بهره‌برداری کنید.
 
نکات برنامه نویسی در C برای میکرو کنترلر ها :


C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید

در زبان برنامه‌نویسی C، بیت فیلد (Bit Field) به عنوان یک نوع داده‌ای (Data Type) تعریف می‌شود که به کاربر اجازه می‌دهد تا بیت‌های داخل یک آدرس حافظه را به صورت مجزا کنترل کند. این داده‌ی نوع، در واقع به برچسب‌های مخصوصی که در داخل یکی از متغیرهای دیگر در C می‌توان اعمال کرد، ارجاع داده می‌شود.

مثال:

برای تعریف یک بیت فیلد در C، ابتدا باید یک ساختار (Struct) تعریف کرد. در این ساختار، می‌توان بیت‌های مختلف را با استفاده از مقادیر صحیح (Integer) تعریف کرد. به عنوان مثال، برای تعریف یک بیت فیلد به نام flags با دو بیت، می‌توان به شکل زیر عمل کرد:

C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید


در این مثال، یک ساختار با دو عضو flag1 و flag2 تعریف شده است که هر کدام از آنها یک بیت از آدرس حافظه را تشکیل می‌دهد. با استفاده از این ساختار، می‌توان هر کدام از بیت‌های flag1 و flag2 را به صورت مجزا تنظیم کرد. به عنوان مثال:

C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید


در این مثال، با استفاده از نام ساختار flags و عضو flag1 و flag2، هر کدام از بیت‌های مربوطه را به صورت مجزا تنظیم کردیم.

فرض کنید می خواهید از واحد ADC میکروکنترلر AVR برای خواندن ولتاژ ورودی استفاده کنید. می توانید از یک ساختار داده ای با فیلدهای بیت برای ذخیره نتایج ADC استفاده کنید:

C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید


حال می توانید این ساختار داده ای را در برنامه AVR خود استفاده کنید:

C:
محتوای بلوک کدها در دسترس شما نیست. برای مشاهده بلوک کدها، وارد انجمن شوید یاثبت نام کنید


در اینجا، ابتدا یک متغیر از نوع AdcResult تعریف شده است و سپس فیلد channel به مقدار 0 تنظیم شده است. سپس ADC شروع به تبدیل می کند و بعد از پایان تبدیل، مقدار ADC در فیلد value ذخیره می شود. سپس می توانید از این متغیر در برنامه AVR خود استفاده کنید.

استفاده از Bit field ها به عنوان یک روش بهینه سازی حافظه در برنامه نویسی C مورد استفاده قرار می گیرد. با استفاده از این روش، می توانید حجم حافظه را به صورت قابل توجهی کاهش دهید و در عین حال عملکرد برنامه را بهبود بخشید.
 
عقب
بالا