آموزش AVR با کدویژن قسمت 3 (پورت های IO) (اصلاح شد)

در این قسمت از سری آموزش های avr به بررسی و نحوه استفاده از پایه های میکرو کنترلر به عنوان ورودی و خروجی می پردازیم

در کامپایلر کدویژن از سه رجیستر برای دسترسی به پورت ها استفاده خواهیم کرد با استفاده از این 3 رجیستر خواهیم توانست پورت  را بصورت ورودی و خروجی و همچنین خواندن وضعیت پایه و روشن و خاموش کردن آن را انجام دهیم

رجیستر اول DDRx:از این رجیستر بعنوان تعریف پایه دلخواه بعنوان ورودی و خروجی استفاده میکنیم در این رجیستر عدد 0 برای ورودی کردن و عدد 1 برای خروجی کردن یک پایه استفاده میشود

بطور مثال میکروی مگا32 چهار پورت با نام های A,B,C,D دارد که برای ورودی خروجی کردن آن به ترتیب زیر عمل میکنیم:

DDRA=0B00000000;

در مثال بالا تمام پایه های پورت A بصورت ورودی تعریف شده اند چون پورت A هشت پایه دارد و هر هشت پایه با عدد 0 مقداردهی شده اند و عدد صفر برای ورودی کردن به کار میرود همچنین کد 0B فقط نوع عدد (باینری) را مشخص میکند و ربطی به خروجی ورودی ندارد و بجای 0B میتوانید از 0x استفاده کرد که در این حالت باید عدد را به هگزادسیمال تبدیلکرد  به مثال های زیر توجه کنید:

DDRA=0B10101010;

پایه های پورت A بصورت یکی در میان ورودی و خروجی تعریف شده است

DDRB=0B11111111;

تمامی پایه های پورت B بصورت خروجی تعریف شده اند

DDRC=0B00001111;

چهار پایه اول پورت C بصورت خروجی چهار پایه دوم پورت C بصورت خروجی تعریف شده اند

DDRD=0B01010001;

پایه صفر ،چهار و ششم از پورت D بصورت خروجی و بقیه پایه ها بصورت ورودی تعریف شده اند.

DDRx MEGA32
DDRx MEGA32

کد های بالا بصورت دسته جمعی نوع ورودی خروجی پایه ها را مشخص می کند و برای اینکه بتوان بصورت تک تک هر پایه را بصورت ورودی یا خروجی تعریف کرد از DDRx.y  بصورت زیر استفاده مکنیم که x نام پورت و y شماره پایه مورد نظر از همان پورت:

DDRA.0=1;

پایه صفرم پورت A خروجی تعریف شده

DDRC.2=1;

پایه دوم پورت C خروجی تعریف شده

DDRD.7=0;

پایه هفتم پورت  D بصورت ورودی تعریف شده

رجیستر PORTx: از این رجیستر برای روشن و خاموش کردن پورت و همچنین و فعال و غیر فعال کردن مقاومت Pullup استفاده مکنیم

هنگامی که پورت را به صورت خروجی تعریف میکنیم این رجیستر پایه های مورد نظر را روشن و خاموش میکند ولی در صورتی که پورت را به صورت ورودی تعریف کنیم این رجیستر مقاومت Pullup را فعال و غیر فعال میکند

نحوه استفاده از این رجیستر:

DDRA=0B11111111;

PORTA=0B00000011;

در مثال بالا همه پایه بصورت خروجی تعریف شده و در خط دوم دو پایه اول پورت A یعنی A.0  ,   A.1  روشن و بقیه خاموش می باشد منظور از روشن بودن یعنی دو پایه اول ولتاژ +5 ولت دارند و بقیه پایه ها که خاموش هستند ولتاژ صفر ولت دارند

این رجیستر مانند رجیستر DDR حالت تکی دارد و می توان بصورت زیر نیز استفاده کرد(PORTx.y):

DDRA.0=1;

PORTA.0=1;

درمثال بالا پایه اول(همان بیت صفرم)از پورت A بصورت خروجی تعریف شده و در خط دوم همان پایه روشن میشود.

نحوه فعال و غیر فعال کردن مقاومت Pullup داخلی: این مقاومت را فقط در حالتی میتوان فعال و غیر فعال کرد که پایه مورد نظر بصورت ورودی تعریف شود:

DDRA=0B00000000;

PORTA=0B11111111;

در مثال بالا همه پایه های پورت A ورودی تعریف شده و در خط دوم با یک کردن مقدار هر پایه در رجیستر PORT مقاومت پول آپ داخلی هر پایه فعال شده است.

DDRA=0B11110000;

PORTA=0B11001100;

در مثال بالا بیت های 0 تا 3 ورودی و بیت های 4 تا 7 خروجی تعریف شده در خط دوم دو بیت 0 و 1 مقاومت پول آپ داخلی غیرفعال شده دو بیت 2 و 3 مقاومت داخلی پول آپ فعال شده دوبیت 4 و5 خاموش شده اند و دو بیت آخر یعنی 6 و 7 روشن شده اند

DDRA.5=0;

PORTA.5=0;

در مثال بالا بیت پنجم از پورت A ورودی تعریف شده و مقاومت پول آپ داخلی آن نیز غیرفعال شده

*مقاومت داخلی اغلب برای جلوگیری از ورود نویز در هنگامی که پایه بصورت ورودی تعریف میشود استفاده میشود .

رجیستر PINx,y:از این رجیستر برای خواندن وضعیت پایه مورد نظر در حالت ورودی استفاده میشود مثلا در حالتی که کلیدی را به یکی از پایه های میکرو وصل کرده اید و می خواهید بدانید که آیا کلید و صل است یا قطع

پروژه ها :

در این مثال قصد داریم تا با یک LED متصل به AVR  را روشن کنیم  پروژه ای مانند آموزش های قبل ایجاد کنید و میکروی مگا32 را انتخاب کرده و کریستال آن را روی 1 مگا هرتز تنظیم کنید و کد های زیر را به برنامه اضافه کنید(آموزش ایجاد پروژه):

#include <mega32.h>

void main(void){

DDRA.0=1;

PORTA.0=1;

}

در خط اول برنامه فایل هدر میکروی مورد نظر را به برنامه اضافه کردیم

در خط دوم تابع main را اضافه کردیم .همان طور که می دانید هر برنامه به زبان C از یک تابع اصلی با نام Main تشکیل میشود که هیچ مقدار بازگشتی ندارد

در خط سوم پایه اول یا همان بیت صفرم پورت A را خروجی تعریف کرده و در خط چهارم پایه  اول A را روشن می کنیم و در پایان تابع main را با علامت { تمام میکنیم.

سپس گزینه Build All را از منوی Project انتخاب میکنیم تا برنامه کامپایل شده و در صورت نبود اشکال فایل های خروجی را بسازد

با اجرای این برنامه در پروتئوس خواهید دید که LED متصل به پایه A.0 روشن میشود. دانلود فایل پروژه و پروتئوس این مثال  (لینک کمکی )

مثال دوم:ساخت چشمک زن ساده

یک پروژه جدید ایجاد کنید و مانند قبل میکروی مگا 32 را انتخاب و کلاک آن را 1 مگا هرتز تنظیم کنید و کد زیر را به پروژه اضافه کنید

(در کد زیر اشکالاتی وجود داشت که اصلاح شده است)

#include <mega32.h>
#include <delay.h>//کتابخانه تاخير
//تابع اصلي را اضافه ميکنيم
void main (void){
DDRA.0=1; // را خروجي تعريف کرديم A.0 پورت
while(1){ // حلقه بينهايت
        PORTA.0=1; //روشن
          delay_ms(1000); // تاخير به مدت 1000 ميلي ثانيه يا 1 ثانيه
          PORTA.0=0; //خاموش
          delay_ms(1000); // تاخير
           //تکرار حلقه
          }
}

در خط اول فایل هدر میکروکنترلر مورد نظر را اضافه می کنیم

چون در این پروژه نیاز به ایجاد تاخیر در برنامه است فایل کتابخانه ای تاخیر را به برنامه اضافه می کنیم  خط دوم

در خط بعدی تابع اصلی را اضافه میکنیم سپس در خط بعدی پایه اول (بیت صفرم ) پورت A را خروجی تعریف کرده ایم

در خط بعدی حلقه while را اضافه کرده ایم while به معنی تا زمانی که می باشد یعنی تا زمانی که شرط داخل while  درست باشد تمامی دستورات داخل حلقه while را اجرا کن و

while(1){

}

حلقه است که همیشه درست است و تا زمانی که از دستور break استفاده نشود این حلقه تکرار خواهد شد

در خط بعدی پایه A.0 را روشن میکنیم در خط بعدی از تابع delay_ms استفاده کرده ایم این تابع برنامه را به مدت عددی که داخل آن نوشته شده است (میلی ثانیه) نگه می دارد مثلا برای ایجاد تاخیر 2 ثانیه ای باید مقدار 2000 را در این تابع بنویسیم این تابع یکی از توابع فابل کتابخانه ای delay.h است که در اول برنامه اضافه کردیم این فایل کتابخانه ای تابع دیگری نیز دارد که به مقدار میکرو ثانیه تاخیر ایجاد می کند به مثال های زیر توجه کنید:

delay_ms(200);  ایجاد تاخیر به مدت 200 میلی ثانیه
delay_ms(5000);  ایجاد تاخیر به مدت 5 ثانیه

delay_us(100); ایجاد تاخیر به مدت 100 میکرو ثانیه
delay_us(1000); ایجاد تاخیر به مدت 1000 میکروثانیه یا به عبارت دیگر 1 میلی ثانیه

به برنامه نوشته شده خودمان برگریدم بعد از این که پایه A.0 صفر را روشن کردیم تاخیر 1 ثانیه ای در برنامه ایجاد نمودیم

در خط بعدی پورت A.0 را خاموش کردیم و دوباره در خط بعدی تاخیری به مدت 1 ثانیه ایجاد نمودیم

در خط بعدی حلقه while را با علامت { می بندیم و همچنین این کار را برای تابع main انجام می دهیم

برنامه را کامپایل کرده و در صورت نبودن خطا برنامه را در پروتئوس شبیه سازی کنید.

تمام مراحل بالا را می توانید بصورت یک فیلم از اینجا دانلود کنید با حجم 6 مگا بایت ( لینک کمکی )
فایل های پروژه و پروتئوس را از اینجا دانلود کنید حجم کمتر از 1 مگا بایت   ( لینک کمکی )

رمز تمامی فایل ها آدرس سایت با حروف کوچک می باشد www.agd.ir

در پروژه های قبل از پورت ها به عنوان خروجی استفاده کردیم حال در مثال زیر به نحوه استفاده از پورت در حالت خروجی می پردازیم

پروژه ای در کد ویژن مانند قبل ایجاد کرده و کد های زیر را درآن اضافه کنید:

(در کد زیر اشکالاتی وجود داشت که اصلاح شده است همچنین فایل ها این پروژه نیز اضافه شد که می توانید در زیر دانلود کنید)

#include <mega32.h>
#include <delay.h>//کتابخانه تاخير
//تابع اصلي را اضافه ميکنيم
void main (void){
DDRA.0=1; // را خروجي تعريف کرديم A.0 پورت
DDRB.0=0;   //را ورودی تعریف کردیم B.0 پین
DDRB.1=0;   //را ورودی تعریف کردیم B.1 پین
while(1){ // حلقه بينهايت
          if(PINB.0==1) PORTA.0=1; 
          if(PINB.1==1) PORTA.0=0;
          }
}

باز مثل قبل فایل هدر میکرو و تاخیر رو به برنامه اضافه کردیم بعد تابع اصلی برنامه و تعیین ورودی خروجی ها و در نهایت حلقه بی نهایت while

در داخل این حلقه دو تا شرط نوشتیم که چک میکنه که اگر پایه B.0 برابر یک شد پایه A.0 را روشن کن ودر شرط بعدی اگر پایه B.1 برابر یک شده پایه A.0 را خاموش کن

*منظور از یک شدن وصل شدن پایه به ولتاژ 5 ولت می باشد

دانلود فایل شماتیک و سورس در یک فایل  (لینک کمکی )

مقاومت Pullup یا مقاومت بالا کشنده چیست؟

مقاومت pullup مقاومتی است در داخل تراشه که بر روی هر یک از پایه های میکرو که قابلیت ورودی و خروجی دارد وجود دارد.این مقاومت در حالت عادی غیر فعال می باشد و زمانی می توان آن را فعال کرد که پایه بصورت ورودی تعریف شود.از این مقاومت برای کاهش اثر نویز استفاده می شود .اگر شما پایه ای را بصورت ورودی تعریف کنید و از هیچ مقاومت pullup یا pulldown استفاده نکنید خواهید دید که در بعضی اوقات بدون اینکه به پایه ورودی مقداری وارد شود میکرو خود به خود عمل میکند این همان اثر نویز محیط است که به میکرو وارد میشود برای حذف این نویز از مقاومت pullup یا pullDown استفاده میشود برای استفاده از مقاومت pullup باید پایه میکرو را ورودی تعریف کرده و سپس مقاومت بالا کشنده را به طریقی که در بالا ذکر شده بود فعال کرد در این حالت باید پایه را از نظر صفر شدن بررسی کرد ولی اگر بخواهید از مقاومت pulldown استفاده کنید باید مقاومت pullup داخلی غیر فعال و چون مقاومت pulldown در داخل میکرو تعبیه نشده باید مدار زیر را بسته و پایه از نظر یک شدن بررسی نماییم

شکل زیر یک مقاومت پول آپ خارج از آی سی را نشان می دهد مقاومت پول داون دقیقا مانند شکل زیر است فقط مقاومت 10 کیلو به جای اینکه به ولتاژ 5 ولت وصل شود به خط منفی مدار یا همان زمین( GND)وصل می شود

مقاومت پول آپ

77 دیدگاه در “آموزش AVR با کدویژن قسمت 3 (پورت های IO) (اصلاح شد)

  1. سلام
    آقا خیلی عالی بود!!!
    واقعاً لذت بردم!
    من فقط بیسیک بلدم اونم خیلی مبتدی در حد روشن و خاموش کردن پورت‌ها
    خیلی دنبال آموزش خوب و ساده و ابتدایی که از بیس توضیح داده باشه بودم.
    از زبان c و کدویژن هیچی بلد نیستم خیلی ساده و روان توضیح داده بودید.
    فقط خداییش مثل بعضیا نباشید که نصفه نیمه رها میکنن…
    انصافاً به راهتون ادامه بدید
    خیلیا مشتاق ادامه آموزشتون هستن
    الآن خیلی وقته که از آموزش قسمت سومتون می‌گذره…
    منتظریم…
    ممنون بابت زحماتی که میکشین
    موفق باشین

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

  3. سلام
    من مراحلی رو که گذاشتید همه رو انجام دادم. اما هنوز نمیدونم چطور میتونم برنامه ای رو که نوشتم در proteus استفاده کنم. فایل proteus شما رم گرفتم و اجرا کردم اما نتونستم در pruteus به سورس کد دسترسی پیدا کنم تا بتونم اونو تغییر بدم.
    ممنون میشم اگه یه توضیح مختصر بدین.

  4. سلام
    از مطالب بسیار مفید جناب عالی، خیلی ممنونم
    دو سؤال در مورد مقاومت pull up داشتم.

    – زمانی که برای یک پایه ورودی، مقاومت pull up فعال باشد به غیر از مواقعی که صفر روی پایه قرار می گیرد، این پایه همواره مقدار یک خواهد داشت. بنابراین چطور می توان تشخیص داد که قطعه خارجی متصل به این پایه چه زمانی یک روی پایه قرار داده است؟ (فرض کنیم که قطعه متصل به پایه در بازه های زمانی گسسته اطلاعات خود را ارسال کند)

    – اگر پایه ای به صورت ورودی تعریف شود و مداوماً از بیرون مقدار بگیرد؛ مثلاً به یک سنسور دما متصل باشد که دائماً دمای اندازه گیری شده را ارسال می کند؛ باز هم نیازی به فعال سازی مقاموت pull up وجود دارد یا خیر؟

    ممنون از لطف شما، در پناه حق باشید

    1. ببینید زمانی که پایه ای را پول آپ می کنیم می خواهیم صفر شدن پایه را چک کنیم ولی اگر بخواهیم یک شدن را چک کنیم نباید مقاومت پول آپ را فعال کنیم و باید مقاومت پول داون رو فعال کنیم و چون avr مقاومت پول داون ندارد باید با یک مقاومت ۱۰ کیلو پایه مورد نظر را به صفر وصل کنیم و یک بودن پایه را چک کنیم.

      سوالی که شما پرسیدید یکم اشتباه بنظر میاد چون پرسیدید که اگر پول آپ رو فعال کنیم چجوری چک کنیم که پایه یک شده است . خوب پایه اگه صفر نباشه خوب یک شده دیگه. یا من کلا منظورتون رو متوجه نشدم؟

      سوال دومتون : بستگی به خروجی سنسورتون داره. مثلا برای سنسور دمای lm35 باید مقاومت pull down وصل بشه نه pull up.

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

    1. سلام ممنون
      برق میکرو از پایه های به اسم vcc و gnd تامین میشه که بیشتر avr ها با ولتاژ ۳٫۳ تا ۵ ولت DC کار می کنند.
      واسه شروع نوع میکرو AVR مهم نیست با هر میکرویی که دم دستتون بود شروع کنید mega32 بهتره واسه شروع . بهتره اینه که اگه قصد دارید پروژه های صنعتی درست کنید با arm کار کنید.
      سوالی بود در خدمتم

  6. سلام.
    فوق العادس،نه نیست،بی نظیره بی نظیر…!!!
    قدر سایتتون رو بدونید.
    ادامه بدید همین جوری و مطالب جدید و با کیفیت و به زبان ساده برای همه بذارید
    موفق باشید…!!!

  7. واقعا خیلی ممنون ادامه بدید و تخصصی تر و فوق تخصیصی تر و گسترده تر از میکرو و بویزه از برنامه نویسی موتور استپر سخن بگووید زیرا در تمام دستگاههای مهم و دقیق این موتور با حال وجود داره . دمت گرم

  8. سلام خسته نباشید.
    فرض میکنیم ۸ تا پایه پورت B مقادیر ۱و۲و۴و۸و… به ما میدن حالا اگه بخوایم مقادیر پایه ها جابجا بشه مثلا پورت ۲ مقدار ۳۲ رو برای ما برگردونه چجوری باید خودمون مقدار دهی کنیم . ممنون میشم راهنمایی کنید .

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

    1. خیلی سادس میتونین به متغیر تعریف کنید که هر بار کلید زده شد رو توش ذخیره کنید و با توجه به اون متغییر خروجی تون رو کنترل کنید

  10. سلام ببخشید من از یک پورت میخوام برای دوکار استفاده کنم مثلا پایه های ۰ ۱ ۲ ۳ پورت A برای یه چیزی و ۴ و۵و ۶ و ۷ رو برای یه چیز دیگه باید چیکار کنم هرکجا رو گشتم و پرسیدم کسی نگفت بهم

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

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

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

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *