0% found this document useful (0 votes)
40 views

50 Note Advanced C Programming Avr Microcontrollers

Uploaded by

ssPss
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
40 views

50 Note Advanced C Programming Avr Microcontrollers

Uploaded by

ssPss
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

‫‪www.avrlib.

ir‬‬ ‫مرجع تخصصی کتابخانه های حرفه ای ‪AVR‬‬

‫‪ 50‬نکته حرفه ای برنامه‬


‫نویسی زبان سی ‪ c‬و نکات ناب‬
‫میکروکنترلرهای ‪AVR‬‬
‫توسط ‪ :‬محسن احسانی نیا ‪[email protected]‬‬

‫منتشر شده توسط ‪ :‬مرجع تخصصی کتابخانه های حرفه ای ‪AVR‬‬

‫‪www.avrlib.ir‬‬
‫محصول رایگان‬
‫‪www.avrlib.ir‬‬ ‫مرجع تخصصی کتابخانه های حرفه ای ‪AVR‬‬

‫متغیرهای نوع ‪ char‬همیشه ‪ ۸‬بیتی هستند‪ .‬اما سایز متغیرهای نوع ‪ int‬بسته به نوع کامپایلر لزوما ‪ ۱۶‬بیت نیست‬ ‫‪- ۱‬سایز متغیرهای ‪: int‬‬
‫(حداقل سایز این نوع متغیر ‪ ۱۶‬بیت است‪).‬‬

‫در ارتباط ‪ rs485‬هنگامی که بایتی‬ ‫‪- ۲‬تغییر مود فرستنده به گیرنده در ارتباط ‪: RS485‬‬
‫ارسال می شود و سمت مقابل باید پاسخ دهد‪ ،‬به دلیل یک طرفه بودن ارتباط باید تاخیر کافی در پاسخ دادن سمت مقابل لحاظ شود تا فرستنده فرصت داشته باشد وضعیت خود را به‬

‫گیرنده تغییر دهد و قبل از تغییر وضعی ت از فرستنده به گیرنده‪ ،‬ارسال پاسخ از سمت مقابل آغاز نشود‪ .‬همچنین کدنویسی بخش فرستنده باید به گونه ای باشد که بعد از ارسال و برای‬

‫دریافت پاسخ‪ ،‬در حداقل زمان ممکن جهت خط به عنوان گیرنده تغییر داده شود و مواردی مانند وقوع یک وقفه نتواند تاخیری را در این تغییر جهت از فرستنده به گیرنده ایجاد کند‪.‬‬

‫در میکروکنترلرهایی که پین ریست آنها نیز می توانند به عنوان پین ‪ I/O‬مورد استفاده قرار گیرد ‪ .‬اگر با تنظیم فیوز بیت مورد نظر ان پین‬ ‫‪- ۳‬پین ریست ‪:‬‬
‫ریست از کار بیفتد و به عنوان ‪ I/O‬مورد استفاده قرار بگیرد ‪ .‬توسط پروگرمر های عادی قابل بازگردانی نخواهد بود‪.‬‬

‫توابع ‪ printf‬و ‪ scanf‬و توابع مشابه این دو در محیط کامپایلرهای زبان سی حافظه های زیادی را از کد هگز‬ ‫‪- ۴‬توابع ‪ printf‬و ‪: scanf‬‬
‫اشغال می کنند لذا تا زمانی که مجبور نشدید از این توابع استفاده ننمایید و حتی االمکان در صورت استفاده مود توابع را در حالت ‪ int‬قرار دهید‪.‬‬

‫فرق بین ‪ debug‬و‪ release‬در محیط های برنامه نویسی این است‬ ‫‪- ۵‬فرق بین ‪ DEBUG‬و‪: RELEASE‬‬
‫که تازمانی که پروژه شما در مرحله تست و خطا است شما از مود ‪ debug‬و زمانی که پروژه به اتمام رسید و شما قصد داشتید که آنرا در حالت نهایی منتشر کنید از مود ‪ release‬استفاده‬

‫می کنید‪.‬‬

‫برای ارتباط با مموری کارت ها مانند ‪ SD Card / MMC card , ….‬می توانید از کتابخانه ی ‪ fatfs‬و یا کتابخانه ‪ petitfat‬استفاده‬ ‫‪- ۶‬کتابخانه‪: Fat‬‬
‫نمایید ‪ .‬این کتابخانه بسیار کامل و بسیار تخصصی طراحی شده است ‪ .‬برای دانلود این کتابخانه می توانید به آدرس سایت دوست ژاپنی خوش سلیقه مان مراجعه نمایید‪. www.elm-‬‬

‫‪chan.org‬‬
‫‪www.avrlib.ir‬‬ ‫مرجع تخصصی کتابخانه های حرفه ای ‪AVR‬‬

‫اگر نیاز باشد تا به میکروکنترلرتان حافظه های خارجی مانند ‪ eeprom‬و یا ‪ SRAM‬خارجی را وصل کنید بهتر‬ ‫‪- ۷‬طبقه بندی اطالعات ‪:‬‬
‫است با استاده از روش جدول ‪ fat‬به طبقه بندی اطالعات مورد نظر خودتان بپردازید‪.‬‬

‫در میکروکنترلرهایی که نمی توان مستقیما ‪ SRAM‬های خارجی را به آن وصل نمود با توجه به اینکه وصل کردن یک‬ ‫‪- SRAM ۸‬خارجی ‪:‬‬
‫‪SRAM‬به آن تعداد زیادی از پایه ها را به هدر خواهد داد لذا می توان با ترفندی ساده کالک و دیتا را کنترل نمود و در تعداد پایه ها را به حداقل رساند‪.‬‬

‫در عملیات ‪ ADC‬باید جهت درست خواندن مقدار آنالوگ فرکانس خواندن نمونه ها را حداقل دو برابر فرکانس ورودی در نظر‬ ‫‪- ۹‬فرکانس‪: ADC‬‬
‫گرفت‪.‬‬

‫با برنامه نویسی مناسب میکرو‬ ‫‪: Multi Processor Communication Mode۱۰‬‬
‫کنترلر در مود ‪ MPCM‬می توان از عملیات مستر واسلیوی یوزارت استفاده نمود‪.‬‬

‫با توجه به اینکه میکروکنترلرهای سری مگا و تاینی عموما فاقد ‪ RTC‬داخلی هستند ‪ ،‬لذا می توان این مهم را توسط تایمر ‪ ۲‬و با‬ ‫‪- RTC ۱۱‬داخلی ‪:‬‬
‫وصل کردن یک کریستال ‪ ۳۲۷۶۸‬هرتزی به این تایمر و انجام برنامه نویسی مناسب این کار را انجام داد‪ .‬فقط باید در نظر داشت که به محض قطع شده منبع تغذیه این تایمر از کار خواهد‬

‫افتاد ‪ .‬لذا در کاربردهایی که منبع تغذیه قطع نمی شود این موضوع بسیار مناسب خواهد بود‪.‬‬

‫ماژول داخلی ‪ SPI‬در میکرو کنترلرهای اتمل بر خالف دیگر ماژول ها مانند ‪ TWI‬و یا ‪ USART‬یک پروتکل خام است که در آن آدرس‬ ‫‪: SPI‬‬ ‫‪:۱۲‬‬
‫دهی ‪ ،‬بیت پریتی و کشف خطا پیش بینی نشده است ‪.‬برعکس این کا باعث یک مزیت بزرگ در آن شده است و ان اینکه طراح به دلخواه خود می تواند پروتکل دلخواه خود را با حداکثر‬

‫سرعت ‪ ۴/۱‬سرعت کالک سی پی یو تعریف نمود ‪ .‬آدرس دهی ‪ ،‬کشف خطا ‪ ،‬کد کردن دیتا و … ازمزیت های خاص این پروتکل است‪.‬‬

‫در شیفت دادن بیتی به چپ و یا راست حداکثر می توان ‪ ۱۶‬بیت را شیفت داد‪.‬‬ ‫‪- ۱۳‬عملیات شیفت بیتی ‪:‬‬
‫‪www.avrlib.ir‬‬ ‫مرجع تخصصی کتابخانه های حرفه ای ‪AVR‬‬

‫در ارتباط با ال سی دی های گرافیکی و رنگی که نیاز به تغییر آنی و سریع دارند باید نوع‬ ‫‪- ۱۴‬ال سی دی گرافیکی و رنگی ‪:‬‬
‫کامپایل را در حداکثر سرعت قرار داد‪.‬‬

‫در محیط برنامه نویسی اتمل استودیو برای تعریف ثوابتی که قرار است در چندین فایل‬ ‫‪- ۱۵‬تعریف ثوابت در اتمل استودیو ‪:‬‬
‫هدر و چندین فایل سی مورد استفاده قرار بگیرند می توان به راحتی از مسیر زیر و با یک بار تعریف آن را انجام داد ‪ :‬ابتدا ‪ ALT+F7‬را فشار دهید ‪ .‬سپس از منوی سمت چپ‬

‫‪Toolchain‬و سپس ‪ AVR/GNU C Compiler‬و سپس ‪ Symbols‬را انتخاب و ثابت را در آن تعریف کنید به عنوان مثال کاربردی ترین تعریف فرکانس میکرو است که در این‬

‫محیط می توان اینگونه تعریف نمود‪: F_CPU=8000000UL‬‬

‫در سری های مگا و تاینی میکروکنترلرهای شرکت اتمل نمی توان اولویت وقفه ها را تعیین کرد ولی در سری ایکسمگا این کار‬ ‫‪- ۱۶‬اولویت وقفه ها ‪:‬‬
‫به راحتی قابل انجام است و با تعیین اولویت وقفه ها می توان از روند اینتراپت مطمئن شد‪.‬‬

‫برای چک کردن منبع ریست در میکروکنترلرهای ای وی آر از رجیستر ‪ MCUCSR‬استفاده نمود‪ .‬و با تعیین بیت یک شده نوع منبع‬ ‫‪- ۱۷‬منابع ریست ‪:‬‬
‫ریست را تعیین نمود‪.‬‬

‫به هنگام ارسال و یا دریافت دیتا در ماژول های مختلف یوزارت ‪i2c , 1wire , spi ،‬باید از سیستم ‪timeout‬‬ ‫‪- ۱۸‬سیستم ‪: timeout‬‬
‫استفاده نمود ‪ .‬برای پیاده سازی این روش می توان از وقفه تایمر استفاده نمود و با یک کردن یک فلگ در تایم زمانی مورد نظر از داخل حلقه ‪ while‬بیرون آمد‪.‬‬

‫برای تشخیص صحت درستی دیتای ارسالی بین دو دستگاه و یا میکروکنترلر می توان از روش ‪ checksum‬استفاده نمود ‪ .‬این روش بسیار ساده‬ ‫‪: - CRC ۱۹‬‬
‫بوده و تشخیص دیتای خطا در آن مشکل است و فقط دیتای خطا را تشخیص می دهد و توسط آن نمی توان بیت خطا را در یک بایت تشخیص داد‪ .‬روش دیگر استفاده از بیت ‪parity‬‬

‫است این روش هم به نوبه خود مفید است اما روش ساده ای است‪ .‬روش دیگر استفاده از روش ‪ CRC‬است ‪ .‬این ترفند شامل ‪ CRC8 , CRC16 , CRC32 , CRC64‬است و روش‬

‫بسیار پیشرفته تری نسبت به روش های قبل است‪.‬‬


‫‪www.avrlib.ir‬‬ ‫مرجع تخصصی کتابخانه های حرفه ای ‪AVR‬‬

‫برای اجرا کردن توابع وقفه بدون پیش آمدن‬ ‫‪- ۲۰‬اجرای وقفه بدون به وجود آمدن شرایط وقفه ‪:‬‬
‫شرایط وقفه و یا فلگ های مرتبط میتوان از روش ریست نرم افزاری استفاده نمود ‪ .‬فرض کنید تابع وقفه ای نوشته شده اما اصال این وقفه در تابع ‪ main‬پیکر بندی نشده است ‪ .‬حال به‬

‫نظر شما برای اجرای این تابع در هر لحظه دلخواه چه باید کرد ؟ راه حل کامال اصولی و قابل اجرا استفاده از روش ریست نرم افزاری است ‪ .‬برای فهمیدن این روش می توانید در محصوالت‬

‫رایگان سایت به دنبال محصول ” چگونه می توان میکرو را ریست نرم افزاری کرد ” بگردید و با دانلود رایگان آن و مطالعه تمام بحث های آن به این ترفند ناب دست پیدا کنید‪.‬‬

‫در ارتباط ‪ USART‬با طول دیتای ‪ ۹‬بیتی ‪ ،‬بیت نهم می تواند به عنوان شاخص تعیین کننده ‪ Command‬یا ‪ Data‬بودن ‪۸‬‬ ‫‪- ۲۱‬ارتباط یوزارت ‪:‬‬
‫بیت دیگر بکار رود‪ .‬از این بیت از طریق کدنویسی مناسب حتی می توان برای ‪ reset‬کردن و شروع مجدد ارتباط هایی استفاده کرد که ارتباط در وسط تبادل دیتا قطع شده باشد‪.‬‬

‫برای پیاده سازی پورت ‪ USB‬در میکروکنترلرهایی که این ماژول سخت افزاری را بر روی خود ندارند می توان از درایور‬ ‫‪- USB ۲۲‬نرم افزاری ‪:‬‬
‫نرم افزاری این ماژول استفاده نمود‪ .‬این ماژول فقط نیاز به یک وقفه خارجی و یک پین آزاد جهت ارتباط دارد‪.‬‬

‫عموما در سیستم کامند برنامه نویس می تواند با تعاریف قراردادی کامند های مورد نظر به ارسال و دریافت مستر اسلیوی بپردازد‪.‬‬ ‫‪- ۲۳‬سیستم کامند ‪:‬‬

‫یکی از پروتکل های قدرتمند تحت ماژول یوزارت ‪ ،‬پروتکل مودباس است ‪.‬این پروتکل را به راحتی میتوان بر روی اغلب‬ ‫‪- ۲۴‬پروتکل مودباس ‪:‬‬
‫میکروکنترلرها پیاده نمود و توسط آن یک سیستم کامندی استاندارد را تعریف نمود و مورد بهره برداری قرار داد‪.‬‬

‫برای ریست کردن میکرو کنترلر به صورت خود خواسته می توان به چندین روش این کار را انجام داد ‪:‬‬ ‫‪- ۲۵‬ریست نرم افزاری میکرو ‪:‬‬
‫اولین روش استفاده از پین خارجی است – راه حل دوم استفاده از تایمر واچ داگ و یا سگ نگهبان است و راه حل سوم استفاده از ریست نرم افزاری است ‪ .‬راه حل سوم توسط کدهای‬

‫برنامه نویسی به راحتی قابل اجرا است و نیازمند زمان ‪ TimeOut‬نیست و در همان لحظه عملیات ریست را انجام میدهد‪.‬‬
‫‪www.avrlib.ir‬‬ ‫مرجع تخصصی کتابخانه های حرفه ای ‪AVR‬‬

‫برای پیاده سازی عملکردهای ‪ DAC‬در میکروکنترلرهایی که این قابلیت را در‬ ‫‪- ۲۶‬پیاده سازی نرم افزاری ‪: DAC‬‬
‫درون خود ندارند می توان از خروجی تایمرها استفاده نمود بدین صورت که با کنترل میزان دیوتی سایکل‪ ،‬موج دلخواه و یا سیگنال آنالوگ دلخواه را تولید نمود‪.‬‬

‫برای ایجاد فرکانس های دقیق مانند فرکانس های صوتی می توان از سری میکرو‬ ‫‪- ۲۷‬ایجاد فرکانس های صوتی دقیق ‪:‬‬
‫کنترلرهای تاینی استفاده نمود ‪.‬به عنوان مثال تاینی ‪ ۲۵‬و تاینی ‪ ۴۵‬و تاینی ‪ ۸۵‬و تاینی ‪ ۸۶۱‬برای این کار بسیار مناسب هستند ‪ .‬این میکرو کنترلرها دارای تایمر با فرکانس ‪ ۶۴‬مگاهرتزی‬

‫هستند که در حالت عادی دارای دقت ‪ ۸‬برابری نسبت به فرکانس های ‪ ۸‬مگاهرتزی است‪.‬‬

‫با یک تایمر در میکروکنترلر‪ ،‬به تعداد واحدهای ‪ compare‬در آن تایمر می توان‬ ‫‪- ۲۸‬ایجاد پالس های دلخواه با تایمر ‪:‬‬
‫پایه )‪ (base‬زمانی مستقل از هم ایجاد کرد‪ .‬مثال اگر یک تایمر دارای سه واحد مقایسه باشد‪ ،‬از طریق این تایمر و وقفه های مقایسه یا بررسی ‪ flag‬های آن می توان سه پایه زمانی‬

‫مختلف و مستقل از هم را ایجاد کرد‪ .‬برای این کار باید تایمر در مد نرمال خ ود قرار بگیرد و بعد از هر بار عملیات مقایسه‪ ،‬بسته به زمان مورد نیاز مقدار مشخصی با رجیستر مقایسه جمع‬

‫شود‪.‬‬

‫قرار دادن خازن های بزرگ (مثال ‪ ۱۰۰۰‬میکروفاراد) در خروجی رگوالتورهای سری ‪ ۷۸‬و رگوالتورهای مشابه در زمان خاموش‬ ‫‪- ۲۹‬رگوالتور ‪: ۷۸۰۵‬‬
‫شدن مدار و در صورتی که ولتاژ ورودی رگوالتور سریع تر از ولتاژ خروجی آن افت کند‪ ،‬به دلیل تخلیه خازن از طریق پین خروجی رگوالتور می تواند باعث سوختن آن شود‪ .‬بنابراین در‬

‫صورت وجود خازن های بزرگ در خروجی این نوع رگوالتورها باید یک دیود بصورت معکوس از خروجی به ورودی رگوالتور متصل شود تا مسیر دشارژ خازن را فراهم کند و مانع از سوختن‬

‫احتمالی آن شود‪.‬‬

‫در صورت نیاز به وجود مقاومت ‪ pull up‬در پین ورودی‬ ‫‪- ۳۰‬مقاومت های ‪ pullup‬و ‪: pulldown‬‬
‫میکروکنترلر‪ ،‬فعال کردن این مقاومت بصورت داخلی ممکن است به تنهایی در محیط های پر نویز کافی نباشد و در مواقعی الزم است مقاومت ‪ pull up‬با مقدار مناسب بصورت خارجی‬

‫قرار داده شود‪ .‬همچنین در صورت نیاز به مقاومت ‪ pull down‬برای خانواده هایی که امکان فعال کردن این نوع مقاومت در آنها وجود دارد‪ ،‬در شرایط پرنویز ممکن است الزم باشد این‬

‫مقاومت بصورت خارجی قرار داده شود‪.‬‬

‫در ‪ AVR‬برای جلوگیری از پاک شدن ‪ eeprom‬داخلی باید ‪ Brownout detection‬فعال شود و سطح ولتاژ آن با توجه به مقدار تغذیه‪،‬‬ ‫‪: - eeprom ۳۱‬‬
‫در باالترین سطح ممکن تنظیم شود‪.‬‬
‫‪www.avrlib.ir‬‬ ‫مرجع تخصصی کتابخانه های حرفه ای ‪AVR‬‬

‫در کاربردهای صنعتی و پر نویز بهتر است پین ‪ reset‬بعد از برنامه ریزی میکروکنترلر بصورت مستقیم از طریق‬ ‫‪- ۳۲‬ریست خارجی میکرو ‪:‬‬
‫جامپر یا لحیم کاری (بسته به نوع میکروکنترلر و منطق این پین) به ‪ vcc‬یا ‪ gnd‬اتصال کوتاه شود‪.‬‬

‫برای جلوگیری از پاک شدن یا نوشته شدن اطالعات ناخواسته بر اثر نویز و نوسانات در ‪ eeprom‬های خارجی مانند‬ ‫‪- eeprom ۳۳‬خارجی ‪:‬‬
‫سری ‪ ۲۴‬بهتر است پین ‪ write protect‬به یکی از پین های میکروکنترلر متصل شود و با کد نویسی مناسب در تمام زمان ها به غیر از لحظات نوشتن‪eeprom ،‬در وضعیت محافظت‬

‫در برابر نوشته شدن قرار بگیرد‪.‬‬

‫با توجه به ‪ immediate‬و فوری بودن تغییر مقدار رجیستر ‪ compare‬در مد ‪ CTC‬تایمرهای‪ ، AVR‬تغییر مقدار‬ ‫‪- ۳۴‬مود ‪ CTC‬تایمر ‪:‬‬
‫رجیستر مقایسه می تواند منجر به ایجاد سیکل های ناخواسته برای صفر شدن تایمر کانتر شود‪ .‬برای درک بهتر‪ ،‬فرض کنید تایمر شماره یک در مد ‪ CTC‬قرار داشته باشد و ‪OCR1A‬‬

‫برابر ‪ ۲۰۰‬باشد و مقدار فعلی تایمر برابر ‪ ۱۰۱‬باشد‪ .‬اگر در این وضعیت مقدار ‪ OCR1A‬به ‪ ۱۰۰‬تغییر کند‪ ،‬به دلیل تاثیر فوری این تغییر مقدار‪ ،‬تایمر به شمارش خود تا ‪ ۶۵۵۳۵‬ادامه‬

‫می دهد و بعد مجددا صفر می شود تا در سیکل بعدی مقدار ‪ ۱۰۰‬اثرگذار باشد‪ .‬بنابراین در فرض این مثال‪ ،‬تعداد کالک الزم برای صفر شدن تایمر به دلیل تغییر مقدار‪ ، OCR1A‬بسیار‬

‫بیشتر از مقدار مورد انتظار خواهد بود که در عملیات زمان گیری‪ ،‬وقوع این شرایط باعث ایجاد خطا در زمان گیری می شود‪ .‬تغییر مقدار رجیستر مقایسه در مد ‪ CTC‬تایمرهای‪، AVR‬‬

‫می تواند باعث عملکرد ناخواسته در تعداد کالک الزم برای صفر شدن مقدار تایمر کانتر شود‪.‬‬

‫اگر در تایمری از میکروکنترلر مورد استفاده‪ ،‬مدی از ‪ fast pwm‬وجود داشته باشد که مقداز ‪TOP‬‬ ‫‪- ۳۵‬مود ‪ fast PWM‬تایمر ‪:‬‬
‫تایمر کانتر قابل تنظیم باشد‪ ،‬برای اجتناب از مشکل فوق بجای مد ‪ CTC‬می توان از این نوع ‪ fast pwm‬استفاده کرد‪ .‬مثال در ‪ mega64‬مدهای ‪ ۱۴‬و ‪ ۱۵‬تایمر کانترهای ‪ ۱‬و ‪ ۳‬چنین‬

‫خاصیتی دارند‪ .‬در مد ‪ ۱۵‬مقدار ‪ TOP‬برابر ‪ OCR1A‬است و با توجه به اینکه در این مد‪ ،‬عملیات ‪ update‬بصورت ‪ immediate‬نیست و از مکانیزم ‪ double buffering‬استفاده‬

‫می شود‪ ،‬بنابراین مشکل بوجود آمده در مد ‪ CTC‬در مقداردهی به ‪ OCR1A‬در صورت استفاده از مد ‪ ۱۵‬دیگر بوجود نخواهد آمد‪.‬‬

‫در کد نویسی برای هر گونه ارتباطی که انتظار برای پاسخ سمت مقابل وجود دارد‪ ،‬باید مکانیزم ‪ timeout‬در انتظار‬ ‫‪- ۳۶‬سیستم ‪: timeout‬‬
‫برای دریافت در نظر گرفته شود تا در صورت قطع ارتباط و عدم پاسخ سمت مقابل‪ ،‬برنامه در یک حلقه بی نهایت انتظار قرار نگیرد‪ .‬منظور از ‪ timeout‬این است که اگر سمت مقابل برای‬

‫مدت مشخصی پاسخ نداد‪ ،‬اجرای برنامه از حلقه انتظار خارج شود و روتین مناسب خطا اجرا شود‪.‬‬
‫‪www.avrlib.ir‬‬ ‫مرجع تخصصی کتابخانه های حرفه ای ‪AVR‬‬

‫در کدنویسی برای میکروکنترلرها‪ ،‬برای خودداری از استفاده از متغیرها و محاسبات اعشاری که در مواردی می تواند‬ ‫‪- ۳۷‬محاسبات اعشاری ‪:‬‬
‫منجر به طوالنی شدن زمان اجرای برنامه یا افزایش حجم آن شود‪ ،‬یک روش این است که اگر تعداد مشخصی از اعداد بعد از ممیز مورد نظر باشد‪ ،‬کلیه اعداد را با مقیاسی در نظر بگیریم‬

‫که همه اعداد اعشاری به صحیح تبدیل شوند و محاسبات بصورت صحیح انجام شوند و در نهایت هنگام نمایش و ارسال و …‪ ،‬ممیز را در محل مناسب قرار دهیم‪ .‬به عنوان مثال اگر در اعداد‬

‫و متغیرهای مورد استفاده تا دو رقم اعشار مورد نظر باشد‪ ،‬می توان عددها و متغیرها را از همان ابتدا با مقیاس صد برابر در نظر گرفت و در نهایت ممیز را در محل مناسب اعمال کرد‪ .‬مثال‬

‫بجای حاصلضرب ‪ ۱٫۹۹‬در ‪ ۲٫۱‬می توان با صد برابر در نظر گرفتن اعداد‪ ،‬حاصلضرب ‪ ۱۹۹‬در ‪ ۲۱۰‬را محاسبه کرد و در نهایت برای نمایش نتیجه‪ ،‬چهار رقم ممیز در نظر گرفت‪ .‬در اینحالت‬

‫روش حذف صفرهای اضافه سمت راست هم می تواند مورد استفاده قرار بگیرد‪ .‬چنانکه در همین مثال بجای ‪ ۴٫۱۷۹۰‬به عنوان نتیجه می توان صفر اضافه سمت راست را حذف کرد و‬

‫‪ ۴٫۱۷۹‬را نمایش داد یا ارسال کرد‪.‬‬

‫در ارتباط ‪ rs485‬هنگامی که بایتی ارسال می شود و سمت مقابل باید پاسخ دهد‪ ،‬به دلیل یک طرفه بودن ارتباط باید‬ ‫‪- ۳۸‬ارتباط ‪: RS485‬‬
‫تاخیر کافی در پاسخ دادن سمت مقابل لحاظ شود تا فرستنده فرصت داشته باشد وضعیت خود را به گیرنده تغییر دهد و قبل از تغییر وضعیت از فرستنده به گیرنده‪ ،‬ارسال پاسخ از سمت‬

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

‫مواردی مانند وقوع یک وقفه نتواند تاخیری را در این تغییر جهت از فرستنده به گیرنده ایجاد کند‪.‬‬

‫یکی از موارد مهم در کدنویسی که عدم توجه به آن می تواند منجر به‬ ‫‪- ۳۹‬مقدار دهی رجیستر های چند بایتی ‪:‬‬
‫اشکاالت غیر تکراری و با عملکرد به ظاهر تصادفی در اجرای برنامه شود‪ ،‬دسترسی به متغیرها از دو سطح مختلف برنامه است‪ .‬منظور از دو سطح مختلف برنامه‪ ،‬حلقه اصلی و یک وقفه و‬

‫یا دو سطح وقفه مختلف است‪ .‬دسترسی از سطوح مختلف به یک متغیر در صورتی که یک سطح از برنامه مقدار متغیر را تغییر دهد‪ ،‬در صورت عدم توجه برنامه نویس به تبعات این نوع‬

‫دسترسی می تواند در عملکرد برنامه خطاهایی را ایجاد کند‪ .‬برای توضیح بیشتر فرض کنید در ‪ AVR‬به یک متغیر چهار بایتی در حلقه اصلی برنامه و یکی از وقفه ها دسترسی وجود‬

‫داشته باشد‪ ،‬به نحوی که حلقه اصلی مقدار این متغیر را تغییر دهد‪ .‬به عنوان مثال عددی‪ ،‬اگر یک متغیر چهار بایتی دارای مقدار ‪x10ff0000 ۰‬باشد و الزم باشد در حلقه اصلی با متغیر‬

‫چهار بایتی دیگری با مقدار ‪ x00010000 ۰‬جمع شود و در محل متغیر اولیه ذخیره شود که حاصل این جمع در نهایت ‪x11000000 ۰‬خواهد بود‪ .‬اما با توجه به هشت بیتی بودن‬

‫ساختار ‪ AVR‬این جمع بصورت بایت به بایت انجام و ذخیره سازی می شود ‪ .‬حال اگر فرض کنیم وقفه ای در بین ذخیره سازی این متغیر و بعد از ذخیره سازی سه بایت با ارزش کمتر‬

‫پذیرفته شود و در روتین آن وقفه مقدار این متغیر از حافظه خوانده شود‪ ،‬در این وضعیت مقدار متغیر ‪x10000000 ۰‬خوانده خواهد شد چون بایت با ارزش بیشتر که قبال ‪x10 ۰‬بوده و‬

‫اکنون باید ‪ x11 ۰‬باشد‪ ،‬هنوز ذخیره سازی نشده است‪ .‬بنابراین مقدار خوانده شده صحیح نخواهد بود و می تواند باعث خطا در عملکرد برنامه شود‪ .‬شبیه همین مثال را می توان برای‬

‫تغییر مقدار یک متغیر توسط روتین وقفه و قضاوت اشتباه روی مقدار متغیر در حلقه اصلی مطرح کرد‪ .‬بطور کلی در این نوع دسترسی ها که از دو سطح مختلف برنامه انجام می شود‪ ،‬باید‬

‫در شیوه کدنویسی مراقب چنین خطاهای احتمالی باشیم که یک روش برای جلوگیری از چنین خطاهایی این است که قبل از انجام عملیات روی این نوع متغیرها‪ ،‬وقفه هایی که می توانند‬

‫منجر به چنین تغییراتی شوند بصورت موقت غیر فعال و بعد مجددا فعال شوند‪.‬‬

‫برای آنکه بتوان یک سروو موتور را کنترل کرد باید فرکانس ‪ ۵۰‬هرتز با دیوتی سایکل مشخصی را تولید نمود ‪ .‬گاهی‬ ‫‪- ۴۰‬کنترل سروو موتور ‪:‬‬
‫ممکن است نیاز باشد تا این کار را توسط یک تایمر ‪ ۸‬بیتی ایجاد نمود ‪.‬از آنجایی که تایمر های ‪ ۸‬بیتی ممکن است خاصیت مقایسه ای را در درون خود نداشته باشند می توان این کار را‬
‫‪www.avrlib.ir‬‬ ‫مرجع تخصصی کتابخانه های حرفه ای ‪AVR‬‬

‫به صورت مجازی انجام داد ‪ .‬در این روش برن امه نویس می تواند به صورت مجازی و توسط کدهای برنامه واحد های مقایسه را تولید و در آن واحدهای مقایسه عملیات تولید موج را انجام‬

‫دهد به عنوان مثال توسط یک تایمر ‪ ۸‬بیتی و فقط با فعال کردن وقفه سرریز تایمر می توان سه عدد استپر را روی هر پین دلخواهی کنترل نمود‪.‬اگر بخواهیم به صورت خالصه توضیح‬

‫دهیم می توانیم بگوییم که باید موج ‪ PWM‬با دیوتی سایکل دلخواه به صورت مجازی تولید گردد‪.‬‬

‫برای کنترل غیر دقیق مانند کنترل نور یک المپ و یا ساخت یک دیمر می توان از ‪ PWM‬مجازی استفاده نمود که‬ ‫‪- PWM ۴۱‬نرم افزاری ‪:‬‬
‫در این روش براحتی میتوان از تمامی پین ها به عنوان خروجی ‪ PWM‬استفاده نمود‪.‬‬

‫در اغلب میکروکنترلرهای تاینی حداکثر فرکانس ‪ MCU‬فرکانس ‪ ۲۰‬مگاهرتز است که این فرکانس در‬ ‫‪- ۴۲‬حداکثر فرکانس میکرو ‪:‬‬
‫میکروکنترلرهای سری مگا در حداکثر خود مقدار ‪ ۱۶‬مگاهرتز است لذا در استفاده های خاص میتوان از این میکروکنترلرها استفاده نمود‪.‬‬

‫برای پیاده سازی ماژولهای ارتباطی مانند ‪SPI,‬‬ ‫‪- ۴۳‬پیاده سازی نرم افزاری ماژول های ارتباطی ‪:‬‬
‫‪ Usart , TWI‬مواقعی که این ماژول های به صورت سخت افزاری در دسترس نیستند می توان به روش پیاده سازی نرم افزاری استفاده نمود در این روش دقت کار ماژول نرم افزاری‬

‫پیاده سازی شده بسته به دقت برنامه نویس دارد‪.‬‬

‫برای طراحی عمر مفید برای دستگاه های مبتنی بر میکروکنترلرهای‬ ‫‪- ۴۴‬قفل نرم افزاری و قفل سخت افزاری ‪:‬‬
‫‪AVR‬می توان از تایمر ها کمک گرفت بدین گونه که با ست کردن وقفه یک تایمر در تایم زمانی مثال ‪ ۲۰‬میلی ثانیه ‪ ،‬با هر بار رخ دادن وقفه یک شمارش به مقدار شمارنده تایمر اضافه‬

‫شود و به محض رسیدن به عدد خاص تایمر از کار بیفتد و عملیات شمارش به اتمام برسد و در صورت نیاز برنامه در درون یک حلقه گیر کند و یا اینکه مدام خودش را ریست نرم افزاری‬

‫کند‪ .‬همچنین برای طراحی قفل سخت افزاری می توان به روش مشابه عمل کرد بدین گونه که مثال کاربر با هر بار کار کردن با دستگاه یک شمارنده زیاد شود و به محض رسیدن به عدد‬

‫خاص دستگاه از کار بیفتد دقیقا شاید شبیه چیزی که در ‪ pattern‬کدهای گوشی های اندرویدی می بینیم که بعد از ‪ ۵‬بار اشتباه زدن الگو دستگاه موقتا از کار می افتد‪ .‬اما با این تفاوت‬

‫که در این روش دستگاه به کل از کار می افتد‪.‬‬

‫در هنگاه ارسال دیتا بین دو دستگاه اگر بخواهید دیتای مورد نظر خود را کد کنید در ساده ترین راه حل‬ ‫‪- ۴۵‬کد کردن دیتای ارسالی ‪:‬‬
‫پیشنهادی می توانید آنها را ‪ Not‬کنید و یا اینکه می توانید انها را با مقدار ‪xff Xor ۰‬کنید که نتیجه معکوس شدن مقادیر صفر ویک خواهد شد و در سمت گیرنده برای دیکد کردن‬

‫این دیتا می توانید این دیتا را دوباره با مقدار ‪xff Xor ۰‬کنید تا دیتای اولیه دوباره ساخته شود‪.‬‬
‫‪www.avrlib.ir‬‬ ‫مرجع تخصصی کتابخانه های حرفه ای ‪AVR‬‬

‫در برنامه نویسی حرفه ای بین این دو جمله تفاوت بسیاری‬ ‫‪- ۴۶‬تفاوت ‪ a++‬و ‪ ++a‬در دستورات شرطی ‪:‬‬
‫است )‪ : if(a++‬و )‪ if(++a‬در جمله اول ابتدا متغیر ‪ a‬مقایسه می شود و سپس بعد از مقایسه مقدار آن یک واحد افزایش می یابد‪ .‬اما در جمله دوم ابتدا مقدار ‪ a‬یک واحد افزایش‬

‫می یابد و سپس عمل مقایسه و شرط مورد نظر انجام می شود‪ .‬با فرض اینکه مقدار اولیه ‪ a‬صفر باشد می توانید متوجه این موضوع شوید که در مقایسه اول نتیجه شرط منفی است و‬

‫دستورات بعد از ‪ if‬اجرا نخواهد شد اما در جمله دوم نتیجه شرط مثبت است و در نتیجه دستورات پیرو این شرط اجرا خواهد شد‪ .‬لذا برنامه نویس حرفه ای باید به ترکیب این دو دقت‬

‫نماید و هر کدام را در موقعیت خود به درستی استفاده نماید‪.‬‬

‫عبارت ‪<<x ۵‬برابر است با ‪ x/32‬همچنین عبارت ‪>>x ۵‬برابر است با ‪ x*32‬لذا اگر بخواهید در برنامه نویسی‬ ‫‪- ۴۷‬عملیات شیفت بیتی ‪:‬‬
‫خود عددی را در توانهای ‪ ۲‬ضرب یا تقسیم کنید کافی است آنرا به راست یا چپ شیفت دهید‪.‬‬

‫فرض گنید متغیر ‪ a‬را به صورت متغیر هشت بیتی ‪char‬‬ ‫‪- ۴۸‬جلوگیری از ‪ over flow‬شدن متغیرها ‪:‬‬
‫عالمت دار تعریف کرده ایم و به آن مقدار اولیه ‪ ۱۰۰‬را داده ایم ‪ .‬حال در برنامه مان قرار است یک متغیر که مقدار آن ‪ ۵۰‬است را با آن جمع نماییم لذا با جمع کرذن این مقدار با مقدار‬

‫اولیه انتظار داریم که نتیجه ‪ ۱۰۰+۵۰‬یعنی ‪ ۱۵۰‬شود ‪.‬اما بر خالف انتظار ما نتیجه مقدار ‪ -۱۰۵‬خواهد شد و این یعنی که متغیر ما ‪ over flow‬شده است ‪ .‬لذا برنامه نویس می تواند یا‬

‫خود با نوشتن تابعی جدید جهت جلوگیری از این موضوع خود دست به کار شود و یا اینکه با تعیین مقدار تغییرات متغیر مورد نظر حیطه تغییرات را پیش بینی نماید‪.‬‬

‫در برنامه نویسی های حرفه ای میکروکنترلرهای ‪ avr‬با کامپایلرهای زبان سی مانند ‪codevisoionAVR‬‬ ‫‪- ۴۹‬افزایش خوانایی برنامه ‪:‬‬
‫و یا ‪ winAVR‬و ‪ AtmelStudio‬جهت خونایی برنامه رجیسترهای ‪ ۸‬بیتی و ‪ ۱۶‬بیتی که هر بیتشان کار خاصی را رانجام میدهد از متغیرهای خاصی استفاده می شود که در این جا به‬

‫چند نمونه از آنها اشاره می شود ‪ : bp=bit position‬یعنی موقعیت بیت مورد نظر که ممکن است عددی بین ‪ ۰‬تا ‪ ۱۵‬و یا بیشتر باشد‪( .‬متغیرهای ‪ ۸‬بیتی – ‪۱۶‬بیتی – ‪ ۳۲‬بیتی‪۶۴ -‬‬

‫بیتی ‪ ) . bm=bit mask‬این عبارت را درحالت ساده می توان به این صورت ترجمه کرد ‪ bm=1<<bp‬و این یعنی مقدار ‪ mask‬شده یا به توان ‪ ۲‬رسیده شده همان ‪ bp .‬عبارت‬

‫بعدی ‪ gc= group configuration‬این عبارت شبیه ‪ bm‬است اما با این تفاوت که در این جا ممکن چندین بیت و یا گروهی از بیت ها به چپ شیفت پیدا کرده باشند به عنوان مثال‬

‫عبارت ‪>>5 ۳‬یک نوع ‪ gc‬است که در این جا ‪ ۳‬بیت مربوط به عدد ‪ ۵‬به مقدار ‪ ۳‬واحد به سمت چپ شیفت پیدات کرده اند‪ .‬از عبارت ‪ gc‬زمانی استفاده می شود که بخواهیم مثال بیت‬

‫های مربوط به تایمر که باید در ان واحد چندین بیت مربوط به یک رجیستر را یک باره تنظیم نماییم استفاده می شود‪ .‬عبارت ‪ gm= group mask‬بی شباهت به ‪ bm‬این عبارت تقریبا‬

‫همان ‪ gc‬است با این تفاوت که در این جا تمام بیت های مربوط به عبارت ‪ gc‬تنظیم شده و یک هستند ‪ .‬برای درک بهتر ‪ gc‬و ‪ gm‬فرض کنید که بیت های ‪۳‬و‪۴‬و‪ ۵‬رجیستر ‪ a‬کالک‬

‫یک تایمر را تنظیم می کند و اگر مقدار این بیت ها در حالت ‪ ۰۰۱‬باشد کالک ‪ ۸‬مگاهرتر انتخاب می شود لذا عبارت ‪ gc‬برابر خواهد بود با ‪ gc=001<<3‬چون در این جا هر سه بیت را‬

‫یک باره برای انتخاب کالک ‪ ۸‬مگاهرتز تنظی می کند ‪.‬عبارت ‪ gm‬به این صورت خواهد بود ‪ gm= 7<<3‬چون ماسک شده این سه بیت مقدار ‪ ۷‬را نشان خواهد داد و چون موقعیت این‬

‫سه بیت در بیت های ‪ ۳‬و ‪ ۴‬و‪ ۵‬هستند پس باید ‪ ۳‬بیت هم به سمت چپ شیفت داده شود‪.‬‬
‫‪www.avrlib.ir‬‬ ‫مرجع تخصصی کتابخانه های حرفه ای ‪AVR‬‬

‫برای افزایش دقت ‪ ADC‬زمانی که ولتاژ اعمال شده به مبدل انالوگ به دیجیتال کم بوده می توان ولتاژ مرجع را‬ ‫‪- ۵۰‬افزایش دقت ‪ADC :‬‬
‫کم در نظر گرفت به عنوان اگر ولتاژ ‪ AVCC‬مقدار ‪ ۵‬ولت باشد با تغییر مقدار ‪ AREF‬از ‪ ۵‬ولت به ‪ ۱‬ولت دقت ‪ ۵‬برابر افزایش پیدا خواهد کرد‪.‬‬

You might also like