طراحی کنترلر، مدارت دلخواه، پروژه ها و تمرینات درس میکروکنترلرها
این پروژه یک فاصله سنج می باشد که می توان در مواردی نیز به عنوان عمق سنج از آن استفاده نمود. حداقل فاصله قابل تشخیص 10cm و حداکثر 80cm تا 100cm می باشد.این پروژه قابلیت تشخیص نشتی گاز و کمی دود و افزایش دما را دارد. به این صورت که اگر نشتی رخ دهد با ارسال یک پیامک SMS برای شماره تعریف شده کاربر را مطلع می نماید. همچنین یک رله نیز فعال می شود که می تواند یه آژیر خطر را صدا درآورد.یک مدار صوتی جهت پخش فایل های صوتی MP3 و WMV با Sampling rate 8KHz-48KHz و خروجی دیجیتال به آنالوگ 24 بیتی می باشد که از حافظه های Micro SD تا 32GB و فرمت های FAT16 و FAT32 پشتیبانی می کند.کنترل نور یک لامپ 12 الی 24 ولتی DC توسط دو عدد کلید در بازه روشنایی 1 تا 99 درصد. به همراه نمایشگر جهت نمایش درصد روشنایی.این پروژه در اصل یک شمارنده می باشد که می توان عبور مرور افراد از یک گیت را شمارش کرد، شمارنده هم می تواند به صورت بالا شمار و هم پایین شمار کار کند. همچنین توسط شدت نور یک عدد LED می‌توان سنسور فرستنده و گیرنده را در یک راستای مستقیم تنظیم کرد. سنسورها ار نوع مادون قرمز با برد تقریبی 120cm می باشد.
پروژه فاصله سنج با سنسور مادون قرمز شارپ Sharp

MCP-37

پروژه فاصله سنج با سنسور مادون قرمز شارپ Sharp
پروژه نشت یاب گاز و کنترل با SMS

MCP-35

پروژه نشت یاب گاز و کنترل با SMS
پروژه mp3 پلیر ساده با avr به زبان C

MCP-32

پروژه mp3 پلیر ساده با avr به زبان C
دیمر دیجیتال با AVR به زبان سی

MCP-38

دیمر دیجیتال با AVR به زبان سی
پروژه شمارش افراد با سنسور مادون قرمز و avr

MCP-6

پروژه شمارش افراد با سنسور مادون قرمز و avr

ایجاد تاخیرهای دقیق با تایمرهای صفر و یک AVR به زبان سی

با توجه به سوالات مکرر کاربران در مورد تایمرها و ایجاد زمان های دقیق، در این مطلب تعداد زیادی مثال با تایمرهای صفر (8 بیتی) و یک (16 بیتی) جهت ایجاد زمان دقیق یک ثانیه برنامه نویسی شده اند. در این مثال ها همه به صورت وقفه و همه به صورت چک مداوم برنامه ها را نوشته ایم، بنابراین با مطالعه این مطلب و مشاهد برنامه ها دیگر نباید مشکلی در ایجاد تاخیر های دقیق با تایمر وجود داشته باشد. در ادامه ما با استفاده از یک میکروکنترلر atmega16 و یک عدد LED به همراه یک اسیلوسکوپ برای تک تک حالت ها برنامه های جداگانه با فایل های شبیه سازی جدا گانه ایجاد کرده ایم، تا این مسائل را به روشنی حل کنیم.

از بخش سفارش طراحی هم اکنون درخواست خود را ثبت کنید
حل و تشریح کلیه تمرینات درس میکروکنترلر AVR
طراحی و ساخت مدارات دلخواه شما با میکروکنترلر AVR


اولین نکته مهم در ایجاد تاخیرهای دقیق انتخاب مقسم فرکانسی تایمر یا همان Perscale می باشد.

یعنی باید به گونه انتخاب شود که با استفاده از آن به توان اعداد صحیح و روندی برای شمارنده تایمر انتخاب کرد. برای انجام این کار باید دقت و حوصله زیادی به خرج داد تا Perscale خوبی انتخاب کرد، که خود این مسئله به فرکانس کاری میکرو وابستگی شدیدی دارد، پس برای ایجاد یک زمان دقیق ما نباید در محاسبات حتی از یک ده هزارم اعشار هم صرف نظر کنیم که برای اینکار توصیه میکنیم از ماشین حساب استفاده کنید. (در این صورت شما تاخیر های دقیقی خواهد داشت)

در تمامی مثال ها ما فرکانس کاری میکرو را 4000000 هرتز انتخاب میکنیم و محاسبات را بر این اساس انجام می دهیم. F=4MHz همچنین برای راحتی کار از Codewizard نرم افزار استفاده میکنیم.

مثال های تایمر 8 بیتی صفر

ایجاد تاخیر 1 ثانیه با استفاده از وقفه تایمر صفر محتوای پوشه (TimersTimer 0 (8bit)1sec delay [INT])

Perscale=64 انتخاب میکنیم و مد تایمر هم شمارش تا FF می باشد، همچنین وقفه تایمر صفر و وقفه سراسری را هم فعال میکنیم. بنابراین TCCR0=0x03 خواهد شد. حال محاسبات تایمر:

Ft0= 4MHz/64=62500Hz فرکانس کاری تایمر

مدت زمان شمارش هر پله تایمر Tt0=1/62500=16us

رجیستر تایمر صفر 8 بیتی است بنابراین 250 پله شمارش نیاز می باشد تا 4ms ایجاد شود 16us*250=4ms

 پس اگر 250 مرتبه تایمر وقفه صادر کند ما 1 ثانیه تاخیر دقیق ایجاد خواهیم کرد 1sec=1000ms ⇒ 1000/4ms=250

عدد 250 به وجود آمده در مرحله 3 و 4 از نظر مقدار هیچ ربطی به هم ندارند و در این مثال به طور کامل تصادفی شبیه هم شده اند. در مرحله سوم گفتیم که برای ایجاد تاخیر 4ms باید 250 پله شمارش شود و همانطور که میدانیم این رجیستر از 0 تا FF را شمارش می کند بنابراین ما باید در هر بار ایجاد وقفه مقدار اولیه شمارش را 6 وارد کنیم تا شمارش از این مقدار تا 256 ادامه یابد و در نهایت 250 پله شمارش شود. تا این جا ما 4ms تاخیر ایجاد کردیم و همانطور که مشاهد میکنید این عدد صحیح و بدون اعشار می باشد. حال با استفاده از یک متغییر به نام c تعداد وقفه های تایمر را شمارش می کنیم. بنابراین برای ایجاد 1 ثانیه تاخیر باید 250 بار وقفه رخ دهد. به عنوان مثال برای ایجاد نیم ثانیه این عدد به 125 تغییر می یابد.

while (1){
 if(c>=250) {
  led=~led;
  c=0;
 }
}

 

بنابراین در یک حلقه بینهایت مقدار c چک می شود تا در صورتی که به 250 رسیده است وضعیت پورت A.0 را برعکس کند. یعنی هر ثانیه یک بار چشمک خواهد زد. همچنین می توانید با استفاده از اسیلوسکوپ این زمان دقیق را مشاهده نمائید.

ایجاد تاخیر 1 ثانیه با استفاده از چک مداوم در تایمر صفر محتوای پوشه (TimersTimer 0 (8bit)1sec delay chek)

تمامی مراحل مربوط به محاسبات تایمر دقیقا شبیه به مثال قبلی می باشد. اما منظور از چک مداوم چیست؟ در اینجا چون ما از وقفه استفاده نکرده ایم باید میکروکنترلر را وارد یک حلقه بینهایت کنیم و تنها شرط خروج از این حلقه را یک شدن پرچم سریز، تایمر صفر قرار دهیم. اما در این حلقه بینهایت چه مسائلی باید توسط برنامه نویس رعایت شود!

void delay_1s(){
 for(c=0; c<=250; c++){  
  CCR0=0x03;
  TCNT0=0x06;
  OCR0=0x00;
    
  while(!(TIFR & 0x02)){//wait for 1s
//other program with out delay
  };
  TCCR0=0x00; //timer0 off    
  TIFR|=0x02; //default flag timer0 ==> change to 1
 }
}

برای راحتی کار ما مراحل ایجاد مدت زمان 1 ثانیه را در یک تابع به نام delay_1s برنامه نویسی میکنیم. در مثال قبلی ما با استفاده از دستور if مقدار c را برای 250 شدن برسی می کردیم ولی در اینجا با کمک یک حلقه for این شمارش را انجام می دهیم. ابتدا تایمر را روشن میکنیم و بعد از اتمام نیز آن را خاموش می کنیم، تنها نکته آن در درحلقه بینهایت می باشد یعنی TIFR، همانطور که می دانیم این رجیستر مربوط به پرچم های تایمرهای 0 و 1 و2 میکرو می باشد، یعنی در هر کدارم از تایمر ها که سریز شمارش رخ دهید در این رجیستر بیت مربوطه آن یک می شود. حال در تایمر صفر پرچم سرریز تایمر صفر بیت دوم می باشد که مقدار آن 02 می شود. با استفاده از دستور AND بیتی یعنی TIFR & 0x02 تنها بیت دوم رجیستر TIFR یعنی (TOV0) مورد برسی قرار میگیرد و در صورتی که این بیت یک شود طبق شرط حلقه ! مخالف آن یعنی صفر است و حلقه شکسته خواهد شد. اما در صورتی که بیت TOV0 صفر باشد ! مخالف آن یک می شود و حلقه ادامه می یابد. بعد از حلقه بینهایت تایمر را خاموش می کنیم و رجیستر TIFR‌را OR بیتی می کنیم یعنی تنها بیت TOV0 صفر خواهد شد و دستور بر روی مابقی بیت ها تاثیری نخواهد داشت.

نکته: بیت TOV0 در هنگام فعال بودن وقفه بعد از رخ دادن وقفه و یک شدن آن به صورت اتوماتیک صفر خواهد شد. اما در حالت چک مداوم باید توسط برنامه نویس این بیت صفر شود تا تایمر برای سرریز بعدی آماده باشد.

در حلقه بینهایت چه مسایلی را باید رعایت کرد؟ در این حلقه ما می توانیم توابع یا سایر دستورات دیگر را فراخوانی کنیم یعنی در همان مدتی که داریم عمل زمان سنجی را انجام می دهیم کار دومی هم به میکرو محول کنیم. در این حلقه نباید از دستورات یا توابعی که مدت زمان اجرای آنها بیشتر یا مساوی 4ms است استفاده نمود، زیرا باعث گذر زمان شده و میکرو شرط حلقه را با تاخیر چک خواهد نمود، بنابراین مدت زمان 1 ثانیه ما دقیق نخواهد شد.

با توجه به نکته فوق ما می توانیم در این مدت زمان برای کار دوم میکرو مسائلی همچون: اسکن صفحه کلید، خواندن یا نوشتن بر روی پورتها، استفاده از مبدل آنالوگ به دیجیتال و سایر عملیاتی که مدت زمان اجرای آنها توسط CPU کمتر از 4ms باشد استفاده نمود. توصیه میکنم که از دستور sprintf و ریفرش LCD توسط دستور lcd_puts استفاده نکنید چون مدت زمان زیادی طول خواهد کشید تا اطلاعات برای LCD ارسال شود در نتیجه زمان سنجی ما دچار اختلال خواهد شد.

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

 

مثال های تایمر 16بیتی یک

محاسبات این تایمر نیز شبیه تایمر صفر می باشد با این تفاوت که بجای عدد 256 باید از عدد 16 بیتی 65536 استفاده کرد.

ایجاد تاخیر 1 ثانیه با استفاده از وقفه تایمر یک محتوای پوشه (TimersTimer 1 (16bit)1sec delay [INT])

چون شمارنده تایمر در اینجا 16 بیتی می باشد بنابراین قارد است از 0 تا FFFF یعنی 0 تا 65535  را بشمارد. از آنجایی که فرکانس تایمر 62500 هرتز شد و مدت زمان شمارش هر پله هم 16us شد بنابراین با تقسیم عدد 1 بر 16us حاصل 62500 پله شمارش خواهد شد پس 65536-62500=3036 خواهد شد یعنی شروع شمارنده تایمر باید از عدد 30 36 باشد. همانطور که ملاحضه می کنید در اینجا چون تایمر یک 16 بیتی می باشد و گستره شمارش بالایی دارد دیگر نیازی به یک متغیر c برای شمارش نیست و به راحتی خود تایمر این کار را انجام خواهد داد.

interrupt [TIM1_OVF] void timer1_ovf_isr(void){
 TCNT1H=0xBDC >> 8;
 TCNT1L=0xBDC & 0xff;
 led=~led;
}

در روتین وقفه تایمر یک هم باید مجددا مقدار شمارنده برای شمارش بعدی با عدد 3036 بارگذاری شود. همچنین در همین روتین ما عمل معکوس سازی پین A.0 را انجام می دهیم.

 

ایجاد تاخیر 1 ثانیه با استفاده از چک مداوم در تایمر یک محتوای پوشه (TimersTimer 1 (16bit)1sec delay chek)

در این جا هم مانند مثال شماره 2 می باشد با این تفاوت که بیت TOV1 برابر با 04 می باشد یعنی بیت سوم رجیستر TIFR و مابقی محاسبات نیز مانند حلت قبل می باشد.

void delay_1s(){
 TCCR1A=0x00;
 TCCR1B=0x03;
 TCNT1H=0x0B;
 TCNT1L=0xDC;
 ICR1H=0x00;
 ICR1L=0x00;
 OCR1AH=0x00;
 OCR1AL=0x00;
 OCR1BH=0x00;
 OCR1BL=0x00;
 while(!(TIFR & 0x04)){//wait for 1s
//other program with out delay
 };
 TCCR1B=0x00; //timer0 off    
 TIFR|=0x04; //default flag timer1 ==> change to 1
}

امیدوارم که توضیحات کامل بوده باشد و این مقاله مورد رضایت دوستان و کاربران محترم picpars.com واقع شده باشد. باز هم می توانید سوالات و مشکلات خود را در قسمت نظرات مطرح نمائید. با تشکر سید محسن قاسمیان

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

  منبع: www.picpars.com

  لطفا مقالات، آموزش‌ها و پروژه های خود را به آدرس ایمیل ارتباطی ایمیل نمائید تا آن را با نام خودتان در سایت منتشر کنیم.




فایل های ضمیمه ( ورود - عضويت )

فایل شماره 199 | حجم 104 کیلوبایت | دانلود 2744 بار

منبع www.picpars.com  نویسنده: سید محسن قاسمیان

منبع www.picpars.com  دانلود مثالهای ایجاد تاخیرهای دقیق با تایمرهای صفر و یک AVR به زبان سی

منبع www.picpars.com  پسورد: www.picpars.com

به این مطلب امتیاز دهید

برچسب ها:
تاریخ ارسال جمعه، 15 ارديبهشت ماه، 1391    نویسندهنویسنده: مدیریت    نظرات 23 نظر    بازدید بازدید [ 24930 ]   پرینتنسخه چاپی
فایل پی دی اف فایل پی دی اف   ارسال به دوستان ارسال به دوستان