رجیستر های PORT and DDR در Atmel studio
Aدر پست قبلی به طور کلی با رجیستر های DDR و PORT آشنا شدیم در این قسمت به صورت عملی در IDE اتمل استودیو این رجیستر ها را به کار می گیریم .
در مرحله اول بر روی یکی از port های میکروکنترلر یک فلاشر ساده ایجاد می کنیم
در این جلسه از میکرو کنترلر atmega8a استفاده می کنیم و بر روی PROTEUS شبیه سازی می کنیم .
کد ها با توضیحات مربوطه :
#include <avr/io.h> //اد کردن کتابخانه عمومی AVR #define F_CPU 8000000 //تعریف کردن فرکانس میکرو #include <util/delay.h> //اد کردن کتابخانه تاخیر //تابع اصلی برنامه int main(void) { DDRB=0b11111111; //خروجی کردن کل پورت B PORTB=0b00000000; // صفر کردن پورت B while (1) //حلقه بینهایت { PORTB=0b11111111; // یک کردن کل پورت B _delay_ms(500); // ایحاد تاخیر 500 میلی ثانیه PORTB=0b00000000; // خاموش کردن پورت _delay_ms(500); //ایجاد تاخیر 500 میلی ثاینه } }
در بالا با استفاده از رجیستر های DDR و PORT یک فلاشر ساده ایجاد کردید که می توانید فایل های این مثال رو از زیر دانلود کنید :
تا اینجای کار برنامه بسیار ساده و مانند IDE کد ویژن بو اما کار جایی سخت می شود که بخواهیم فقط یک بیت از یک رجیستر را تنظیم کنیم البته در پایین تر توضیح می دهیم
روش اصلی تنظیم کردن فقط یک بیت از یک رجیستر
یک کردن فقط یک بیت یک رجیستر :
عموما از کد زیر برای یک کردن یک بیت در برنامه استفاده می کنند:
PORTX |= (1<<PORTXY);
به جای X می توانید پسوند پورت مورد نظر خود را بزارید و به جای y هم باید شماره پایه مورد نظر خود تان را بزارید .
مثال :
PORTB |= (1<<PORTB6);
حالا میریم سراغ اینکه اصلا این کد چه کاری رو انجام می دهد :
اگه بخواهیم به طور کلی توضیح دهیم اول مقدار اولیه رجیستر را می خواند و بعد بیت مورد نظر شما رو با در نظر گرفتن مقدار اولیه بیت های دیگر یک می کند
اگر مقدار با عملگر های زبان c آشنا باشید کد بالا مخفف کد زیر می باشد :
PORTB = PORTB | (1<<PORTB6);
عملکرد کد تغریبا گویا ست فقط قسمت دوم آن شاید برای شما نا آشنا باشد :
(1<<PORTB6)
عبارت PORTB6 یک عبارت از پیش تعریف شده یا به عبارت دیگه یک define می باشد که در کتاب خانه io.h تعریف شده است که فقط مقدار عددی بیت مورد نظر می باشد که مانند کد زیر تعریف شده است .
#define PORTB6 6
عبارت (1<<PORTB6) مقدار یک رو به اندازه مقدار تعریف شده همون define که در مثال ما 6 هستش شیفت می دهد به سمت راست و کد 01000000رو تولید می کنه و در ادامه با مقدار قبلی رجیستر PORTB به صورت بیتی جمع می کند . مثال :
اگه به صورت مثال مقدار قبلی رجیستر را برابر مقدار 10001001 مقدار تولید شده به صورت زیر می شود :
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
کد خروجی شیفت |
1 |
0 |
0 |
1 |
0 |
0 |
0 |
1 |
کد قبلی رجیستر |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
خروجی نهایی |
همون طور که دید فقط بیت مورد نظر شما در این حالت تغییر کرد و بقیه بیت ها مقدار قبلی خود را نگه داشتند.
و در آخر کد نهایی بر روی رجیستر ما ریخته می شود
صفر کردن فقط یک بیت از یک رجیستر
بعد از یک کردن نوبت به صفر کردن یک بیت می رسه برای صفر کردن بیشتر اوقات از کد زیر استفاده می کنن :
PORTX &= ~(1<<PORTXY) ;
به جای X می توانید پسوند پورت مورد نظر خود را بزارید و به جای y هم باید شماره پایه مورد نظر خود تان را بزارید .
مثال :
PORTB &= ~(1<<PORTB6) ;
مانند قبل نحوه عمل کرد این کد را برسی می کنیم :
کد بالا مخفف کد زیر می باشد :
PORTB = PORTB & ~(1<<PORTB6) ;
در پرانتز (1<<PORTB6) کد 01000000 به صورت باینری ایجاد می شود و بعد این کد با استفاده از عملگر (~) به صورت بیتی not یا به عبارت دیگه به صورت بیتی غرینه می شود :
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
کد پرانتز |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
1 |
غرینه شده |
بعد از قرینه شدن با مقدار اولیه AND بیتی می شود تا تداخلی با مقدار اولیه نداشته باشد و در آخر بر روی رجیستر ریخته می شود
برای مثال ما مقدار اولیه را 11001001 می گیریم :
1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | کد not شده |
1 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | کد قبلی رجیستر |
1 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | خروجی نهایی |
در بالا روش های اصلی و پایه نوشتن بر روی فقط یک بیت در یک رجیستر را توضیح دادیم در روش های دیگر پایه کار همین روش های بالا می باشد و فقط به صورت یک کد یا یک کتابخانه آماده هستند که کار را آسان تر می کنند که در ادامه به آنها هم می پردازیم :
ابتدا به سراغ یک کتابخانه معروف به نام avrlibdefs.h می رویم (لینک دانلود فایل این کتابخانه در پایان این قسمت موجود است )
این کتابخانه امکانات جالبی دارد که ما به دوتا از دستورات این کتابخانه که موضوع اصلی ما هستند می پردازیم :
sbi(reg,bit); cbi(reg,bit);
کد خط اول بیت رجیستر مورد نظر رو یک می کند و کد دستور خط دوم بیت رجیستر مورد نظر رو صفر می کند فقط کافی است که به جای reg نام رجیستر و به جای bit نام بیت مورد نظر خود را وارد کنیم
مثال :
sbi(PORTB,6); cbi(PORTB,6);
بازدیدها: 1125