۳-۷ آشنایی با مفهوم وقفه (Interrupt)
۲۷ بهمن ۱۳۹۷۱-۸ ارتباط سریال USART
۲۷ بهمن ۱۳۹۷اگر کمی دقیق باشید حتما این موضوع به ذهنتان خطور کرده است که چرا به جای استفاده از تابعی مثل ()delay_ms ما برای یک ثانیه شمار به سراغ تایمر کانترها رفتیم؟ علت این است که تابع ()delay_ms در فواصل زمانی زیاد از دقت بسیار پایینی برخوردار است و ما اینجا در صدد طراحی یک ثانیه شمار با دقت فوقالعاده بالا هستیم بنابراین از تایمرکانترها استفاده کردیم. همچنین در این کار از کلاک داخلی میکرو استفاده میکنیم.
برای این منظور لازم است که بدانید وقتی در ابتدای ساخت پروژهی AVR خود در محیط Code Wizard میزان Clock source را برابر یک عدد قرار میدهید این عدد به چه معناست و چه تاثیری در کار ما دارد؟ یکی از معانی این عدد در مبحث تایمرها تعداد حداکثر پالس مربعی است که مولد تولید پالس میکرو در واحد زمان که همان یک ثانیه است میتواند تولید کند. مثلا وقتی Clock میکرو را برابر 1MHz قرار میدهید مولد پالس داخلی میکرو در هر ثانیه میتواند تا یک میلیون پالس تولید کند که این تعداد پالس میتواند در صورت وارد شدن به واحد Timer Counter شمرده شده و زمان از روی آن محاسبه شود. به این نحو که در مثال بالا به ازای ورود هر یک میلیون پالس ۱ ثانیه سپری شده است.
برای این کار ابتدا باید منبع کلاک میکرو را منبع داخلی که همان System Clock است قرار دهیم. سپس در بخش Clock Value میتوانیم فرکانس تولید پالس مربعی را تعیین کنیم که حداکثر میتواند با فرکانس کاری خود میکرو برابر باشد یا قسمتی از این فرکانس باشد. در اینجا ما همانند شکل زیر فرکانس 1Mhz را برمیگزینیم.
پس از انجام این تنظیمات و همچنین فعال سازی وقفه ی سرریز عمل کد نویسی را شروع میکنیم.
#include <mega32.h> #include <alcd.h> #include <delay.h> #include <stdio.h> #include <stdlib.h> int counter=0, second=0; char str[20]; // Timer 0 overflow interrupt service routine interrupt [TIM0_OVF] void timer0_ovf_isr(void) { counter++; if(counter ==3906){ second++; counter=0; } } while(1) { sprintf(str,"second left = %d",second); lcd_puts(str); delay_ms(50); lcd_clear(); }
نحوهی عملکرد این کد به این شکل است که چون در هر ثانیه یکمیلیون پالس وارد واحد تایمرکانتر صفر میشود و در هر ۲۵۶ پالس وارد شده یک وقفه رخ میدهد، بنابراین در یک ثانیه (1000000/256) عدد وقفه رخ میدهد که حاصل آن عددی است نزدیک به ۳۹۰۶، بنابراین اگر ما در هر ۳۹۰۶ بار رخ دادن وقفه یک واحد به متغیر زمان خود برحسب ثانیه اضافه کنیم توانستهایم زمان بر حسب ثانیه را به طور دقیق محاسبه کنیم.
همچنین به خاطر داشته باشید که در کار با تایمرکانترها تنظیم دقیق و هماهنگی بین کلاکها هم در زمان پروگرمینگ و هم در زمان شبیهسازی بسیار مهم و حیاتی است و هر گونه بیدقتی در این تنظیمات موجب عملکرد نادرست پروژه در زمان اجرا میشود.
11 Comments
با سلام
اگر بخواهیم با استفاده از یک انکودر ، سرعت موتور را تنظیم کنیم ، سپس به ازای هر یک دقیقه ، تعداد دور بر دقیقه را مشخص کنیم ، لطفا راهنمایی بفرماییذ
با تشکر
با سلام
کار بسیار ساده هست، اول باید ببینین دقت انکدرتون چقده، به این مفهوم که چند پالس به ازای هر دور بهتون میده، مثلا فرض کنین تعداد پالسها N عدد باشه ، حالا ACC=360/N دقت انکودر شماس، به این معنی که به ازای هر پالس از انکدر ، شفتِ موتور شما ACC درجه تغییر کرده. حال با محاسبه :
p =Acc *number of received Pulses مقدار کنونی زاویه را محاسبه نمایید ( if p>= ۳۶۰ then p=0 )
حالا برای محاسبه سرعت، شما باید مقدار ((p(i)-p(i-1)/(t(i)-t(i-1) را حساب کنین، در اینجا( p(i معادل زاویه در لحظهای i أم و (t(i زمان این اندازه گیری هست، در واقع شما باید زمان رو هم در کنار زاویه اندازه گیری کنین، برای این کار تو میکرو باید یه واحد تایمر کانتر رو راه اندازی کنین که زمان رو فقط همیشه تو یه متغیر نگاه داره، بعد باید یه واحد دیگه تایمر کانتر رو بهrising edge یا falling edge حساس کنین که پالسهای انکدر رو بشمرین، بد تو هر لحظه که p رو محاسبه کردین، زمان این اندازه گیری که تو متغیر زمان هست رو هم سیو میکنین، بعد باتوجه به فرمول بالا سرعت رو حساب میکنین.
سرعت محاسبه شده سرعت دورانی است (angular Velocity)، برای محاسبه RPM، باید از فرمول زیر بهر ببرین:
Angular velocity= (2*pi*rpm)/60
pi= 3.14
rpm=Round Per Minute
پس این تکینیک اشتباه است که با استفاده از دو تایمر ، یک دقیقه شمار و یک شمارنده پالس را بدست آوریم و سپس با استفاده از این دو تایمر ، برای محاسبه rpm استفاده کنیم
بله، تکنیکی که فرمودین بسیار ضعیف و با بازدهی بسیار پایین است
با سلام چطور میتونم delay_msرو تبدیل به دقیقه کنم؟البته ۱۰ دقیقه زمان لازم دارم و نوشتم( delay_ms(600000
ولی کار نکرد..
سلام.
توی تابع delay_ms مقدار آرگومان نمیتونه از یه حدی بیشتر بشه. شما باید خودتون یه تابع دیگه تعریف کنین و با فراخوانی اون تابع بیان این زمان رو با شکستن به زمانهای کوچیکتر بسازین
سلام
امکان داره فایل پروتئوس و کد ویژن و هگز همین پروژه رو به ایمیل من بفرستید
واقعا نیاز دارم و تو شبیه سازی هم یکم مشکل دارم
ممنونم …خواهش میکنم بفرستید
h73n94@yahoo.com
سلام
با شرکت تماس بگیرین.
واقعا عالی بود
سلام وقتتون بخیر این برنامه که اصلا تابع مین نداره و ارور میده.
لطفا راهنمایی کنید.
سلام و عرض ادب
من میخوام یک شمارنده یک ثانیه با تایمر ۱ میکروکنترلر اتمگا ۳۲ درست کنم و به صورت بالاشمار روی سون سگمنت نمایش داده بشه و میخوام از کریستال ۳۲.۷۶۸khz استفاده کنم تا دقیق باشه ، میشه راهنماییم کنید کد هاشو چطور باید بنویسم ؟