آموزش میکروکنترلر XMEGA
در قسمت دوم آموزش میکروکنترلر XMEGA به مباحث کلی درمورد خانواده XMEGA ازجمله محدودهی دما و تغذیه و کلاک پرداختیم. در این قسمت از آموزش میکروکنترلر XMEGA به آشنایی با رجیسترهای پورت در این خانواده میپردازیم. پیشفرض این آموزش داشتن آشنایی نسبی با رجیسترهای خانواده AVR و عملکرد آنها است.
PORTA.DIR:
در خانوادهAVR برای تعیین جهت یک پورت و پینهای مربوطه از رجیستر DDR استفاده میشود و بعداز آن نام پورت قرار میگیرد مانند DDRA. در خانواده XMEGA برای تعیین جهت پورتها از رجیستر PORTA.DIR استفاده میشود که DIR بهمعنای DIRECTION است. از این رجیستر به شکل PORTA_DIR هم میتوان استفادهکرد. پس اگر در این رجیستر بیتی را یک قراردهیم پین متناظر در پورت بهعنوان خروجی تعریف میشود.
PORTA.OUT:
در AVR برای تعیین وضعیت HIGH/LOW پایهها از رجیستر PORT استفاده میشود، این رجیستر در خانواده XMEGA به صورت PORTA.OUT وظیفه تعیین ۰ و ۱ بودن پورتها را برعهده دارد. البته این رجیستر در AVR وظیفه فعالکردن PULL UP داخلی برای پینهای ورودی را نیز دارد، بدینمعناکه اگر یک پین بهصورت وروردی تعیینشدهباشد و بیت متناظر در رجیستر پورت یک قراردادهشود PULL UP فعال میشود. اما مسئله فعالشدن PULL UP در رجیستر متناظر در XMEGA ،که PORTA.OUT است برقرار نیست. این رجیستر برای تعیین وضعیت پینهایی است که بهصورت خروجی تعریفشدهاند، اما برای پینهای ورودی وظیفه فعالکردن PULL UP بهعهده این رجیستر نیست. برایمثال میخواهیم پین شماره صفر از پورت A را بهصورت خروجی تعریفکنیم؛ برای اینکار باید بیت شماره صفر در PORTA.DIR را یک قراردهیم. حال اگر بخواهیم این پین در وضعیت LOW باشد باید در بیت شماره صفر در PORTA.OUT صفر نوشتهشود و اگر بخواهیم در وضعیت HIGH باشد باید بیت مربوطه یک نوشتهشود.
PORTA.IN
در AVR برای دسترسیبه وضعیت پینها از دستور PINA استفاده میشود با اینتفاوت که در XMEGA از دستور PORTA.IN استفاده میشود، این دستور امکان دسترسی CPU به پینهای PORTA برای تعیین وضعیت HIGH/LOW را فراهم میکند . بهعنوان یک قاعده کلی در مقداردهی به رجیسترها سعی میشود از اعداد استفادهنشود. بلکه از عبارتهای معنیدار معادل که در فایلهای هدر کامپایلر وجود دارد استفاده میکنیم. بااستفادهاز دستور ;PORTA.DIR=0X01 میتوان PA.0 را در وضعیت خروجی قراردهیم. میتوان بهجای این دستور از PORTA.DIR=1<<0 استفادهکرد. اما بهجای این دو دستور بهتر است از ;PORTA.DIR=PIN0_bm که در فایل هدر iox64a3.h تعریفشدهاست استفادهکنیم. همانطورکه در قبل اشارهشد مبنایکار ما atmel studio است و این فایل هدر هم در کتابخانه atmel studio وجود دارد. همچنین در برد آموزشی از ATXMEGA 64 A3 استفاده میکنیم. عباراتی در کدها وجود دارد که دستور را خواناتر میکند. پس بههمیندلیل سعیبر این است که بهجای مقداردهی عددی از عبارات تعریفشده در هدرها استفادهکنیم. اهمیت این مساله در زمانی مشخصاست که تناظری در مقداردهی رجیستر و خروجی وجود ندارد، مثلاً در رجیستر مربوطبه تایمر کانتر، USART ،SPI و… باید بهطورکلی از عبارات معنیدار استفادهکنیم که هم برای خود ما و هم برای کسانی که میخواهند از این کدها استفادهکنند قابلیت استفادهمجدد داشتهباشد و اصلاحاتبعدی که ممکناست روی کد انجام گیرد بهسادگی انجامشود. برای فهم این مساله به مثالزیر توجهکنید. اگر بخواهیم ازطریق رجیستر PORTA.OUT پینهای شماره ۰ و ۱ را در وضعیت HIGH قراردهیم و پینهای شماره ۲ تا ۷ را در وضعیت قبلی خودشان باقی بمانند، باید از عملگر OR استفادهکنیم.
PORTA.OUT|=PIN1_bm|PIN0_bm;
اگر بخواهیم مقدار پینهای ۰ و ۱ را با صفرکردن بیتهای متناظر انجامدهیم، باید بهجای OR از AND کنیم. اگر PORTA.OUT را بخوانیم و 0XFC را با آن ،AND کنیم، بیتهای شماره ۲ تا ۷ در وضعیتقبلی خود باقی میمانند و فقط بیتهای ۰ و ۱ صفر میشوند. این عملیات را اصطلاحا READ MODIFY WRITE مینامند. در زیر عبارت (PIN1_bm|PIN0_bm) برابر 0XFC است.
PORTA.OUT & =~(PIN1_bm|PIN0_bm);
عمل بعدی عملیات NOT یا TOGGLE کردن وضعیت برخی بیتها با حفظ وضعیت باقی بیتها است، که برای این حالت به وسیله XOR این کار را انجام میدهیم. هر بیتی که با یک XOR شود وضعیت آن NOT میشود، یعنی اگر صفر است یک میشود و اگر یک است صفر میشود. این عملیات READ MODIFY WRITE تامیده میشود. این نوع عملیات زمان بیشتری را بهدلیل چندمرحلهایبودن دستور اشغال میکند. این زمان شامل خواندن رجیستر، سپس با مقدار موردنظر OR یا AND و… کردن و در آخر نوشتن در محل است. هرچند یک دستور داریم ولی باید توجهداشت زمانیکه به کدهای اسمبلی ترجمه میشود به چندین مرحله تقسیم میشود. افزایش مراحل انجام دستور علاوهبر افزایش زمان باعث افزایش حجم اشغالشده حافظه FLASH میشود.
در خانواده XMEGA امکانی فراهمشدهاست که نیاز نیست از عملیات READ MODIFY WRITE استفادهشود. علاوهبراینکه رجیستر PORTA.OUT وجود دارد، متناظر با هر پورت رجیسترهای زیر نیز وجوددارند.
PORTA.OUTSET PORTA.OUTCLR PORTA.OUTTGL
اگر مقداری در این رجیسترها نوشته شود، در بیتهایی که یک هستند عملیات SET,CLR و TGL انجام میشود. برای مثال اگر بخواهیم فقط پینهای 0 و 1 را یک کنیم از دستور زیر استفاده میکنیم.
PORTA.OUTSET=PIN1_bm|PIN0_bm;
برای پاککردن مقدار یک پین از دستور PORTA.OUTCLR استفاده میشود. در این دستور هر بیتی که در رجیستر OUTCLR یک باشد پاک میشود. بااستفادهاز دستور PORTA.OUTTGL میتوان بیت متناظر با پین را تغییروضعیت داد، اگر ۱ باید ۰ میشود و اگر ۱ باشد ۰ میشود. همچنین این عملیات برای ورودی و خروجیکردن پورتها مورداستفاده قرارمیگیرد:
PORTA.DIRSET PORTA.DIRTCLR PORTA.DIRTGL
بهعنوانمثال و بااستفادهاز برد آموزشی که براساس این آموزشها و دستورها است به مثالزیر توجهکنید:
برای روشنشدن LEDها باید PE1 تا PE7 و PF0 بهصورت خروجی تنظیمشود. وضعیت PF0 باید HIGH باشد و برای روشنشدن هر LED نیاز است پین مربوطه یک شود.
در قسمت چهارم آموزش میکروکنترلر XMEGA با نحوه ایجاد پروژه و کامپایل و پروگرمکردن آن در AtmelStudio آشنا میشویم. با ما همراه باشید.
منبع: سیسوگ