Real Time Clock

یکی از پروژه های فوق العاده مهم و کاربردی در ضمینه AVR ( یه سرچ بزنید کلی از این پروژه ها پیدا میکنید) همین RTC یا ساعت است که برای زمان سنجی ازش استفاده میشود .

دانلود الگوریتم و فلوچارت doc1259.pdf (حجم در حدود 67KB)
دانلود سورس کد همراه با شماتیک Proteus  و RTC.rar PCB  (حجم در حدود 82KB)

مثل همیشه بحث من روی Mega8 هست ولی منطق کار برای دیگر قطعات همینه .Mega8 سه تا تایمر/کانتر دارد که از صفر شروع میشوند و از آنها برای تولید موج در مد های مختلف و سنجش دقیق فواصل زمانی استفاده میشود .

تایمر شماره 2 یک تایمر هشت بیتی است و برای استفاده به صورت آسنکرون جهت اتصال کریستال ساعت 32.768 kHz  بهینه شده .هر تایمر برای کار کردن نیاز به تنظیم شدن دارد برای این کار باید رجیستر های تایمر را مقدار دهی کرد .رجیستر های Timer/Counter Interrupt Mask Register و Timer/Counter Interrupt Flag Register بین تمام تایمر ها مشترک است .علاوه بر این رجیستر ها  این تایمر دارای رجیستر های Timer/Counter Control Register و Timer/Counter Register و Output Compare Register و Asynchronous Status Register  نیز هست .برخی بیتها استفاده نشده هستند که هنگام خواندن معمولا صفر خوانده میشوند .

– رجیستر TIMSK برای تنظیمات وقفه ی تایمر ها بکار میرود .با Set کردن بیت مربوط به هر تایمر ، در صورت وقوع وقفه ، روتین همان وقفه اجرا میشود .

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

– رجیستر TCCR2  برای انتخاب منابع clock و تنظیم موج  خروجی تایمر استفاده میشود .

– مقدار تایمر در هر لحظه توسط رجیستر TCNT2 قابل دسترسی مستقیم CPU است . CPU هم میتواند مقادیر را بر روی رجیستر بنویسد هم از آن بخواند .

– محتوای رجیستر OCR2 همواره با  مقدار شمارنده (در رجیستر TCNT2) مقایسه میشود در صورت برابری میتواند باعث ایجاد وقفه Output Compare شود یا در پین OC2 موج خروجی تولید کند .

– رجیستر ASSR شامل تنظیمات مد آسنکرون میشود . هنگامی که مقدار صفر روی رجیستر نوشته شود تایمر از کلاک IO سیستم پالس دریافت میکند ولی زمانی که مقدار 1 روی رجیستر نوشته شود میتواند از کریستال متصل به پینهای TOSC1,2 کلاک بگیرد .

برای راه اندازی تایمر باید این تنظیمات صورت گیرد :

– تعیین Prescaler 128 – تنظیم کار کردن در مد آسنکرون – فعال کردن وقفه سرریز – فعال کردن وقفه عمومی .

تمام این کارها بااستفاده از CodeWizard با چند کلیک انجام میشود .بعد از انتخاب گزینه های مورد نظر طبق تصویر از منوی فایل گزینه Generate,Save and Exit را بزنید وپروژه را ذخیره کنید .کد ها به صورت خود کار نوشته میشوند .

برنامه به صورت خلاصه به این صورت میشود من قسمت هایی که نیازی نیست رو پاک کردم.
چند نکته در مورد سرویس وقفه :
نوع بازگشتی باید حتما void باشد و سرویس وقفه پارامتری در یافت نمیکند .
در روتین وقفه فقط مقادیر ثانیه ، دقیقه و ساعت به روز میشوند .
روتین وقفه باید تا حد امکان کوتاه باشد و فقط کار های اساسی در آن انجام شود .اگر سرویس وقفه طولانی شود مجبورید از وقفه های تودرتو استفاده کنید یا اینکه وقفه هایی منتظر اجرا میمانند که هیچ کدام شرایط خوبی نیستند .در صورتی که نیاز دارید تا کار های طولانی انجام دهید ، چند فلگ را در سرویس وقفه Set کنید و به سرعت از وقفه خارج شوید ودر برنامه main باتوجه به مقادیر فلگ ها آنها را انجام دهید .

 #include <mga8.h>
  #include <delay.h>
  #include <stdio.h>
  //define states
  #define NORMAL 0
  #define MINUTE 1
  #define HOUR 2
  // Alphanumeric LCD Module functions
  #asm (".equ __lcd_port=0x12 ")//PORTD
  #include <lcd.h>
  // Declare your global variables here
  char second,minute,hour,state;
  unsigned char strTime[8]; //"00:00:00"
  bit changed=0;
  // Timer 2 overflow interrupt service routine
  interrupt [TIM2_OVF] void timer2_ovf_isr(void)
  {
  // Place your code here
  if(++second >= 60)
  {
  second=0;
  if(++minute >= 60)
  {
  minute=0;
  if(++hour >= 24)
 hour=0;
  }
  }
  changed=1;
  }
  void Update(void)
  {
  changed=0;
  lcd_clear();
  sprintf(strTime,"%d:%d:%d",hour,minute,second);
  lcd_puts(strTime);
  }
  void CheckStates(void)
  {
  delay_ms(100);
  if(state!=NORMAL)
  {
  if(state==MINUTE)
  lcd_putsf(" Minute");
  else
 lcd_putsf(" Hour");
  delay_ms(200);
  Update();
  }
  if(PINB.0==0)
  {
  state=(state+1)%3;
  if(state==NORMAL)
  TCCR2=0x05; //Start Timer
  else TCCR2=0; //Stop Timer
  }
  if(state!=NORMAL && PINB.1==0)
  {
  if(state==MINUTE)
  {
  changed=1;
  minute=(minute+1)%60;
  }
  else
  {
  changed=1;
  hour=(hour+1)%24;
  }
  }
  }
  void main(void)
  {
  // Input/Output Ports initialization
  PORTB=0x03;
  DDRB=0x00;
  // Timer/Counter 2 initialization
  // Clock source: TOSC1 pin
  // Clock value: PCK2/128
  ASSR=0x08;
  TCCR2=0x05;
  // Timer(s)/Counter(s) Interrupt(s) initialization
  TIMSK=0x40;
  // LCD module initialization
  lcd_init(16);
  // Global enable interrupts
  #asm("sei")
  while (1)
  {
  // Place your code here
  if(changed)  Update();
  CheckStates();
  };
  } 

برنامه ای که برای دانلود گذاشتم با این برنامه فرق میکنه و حجمش کمتره چون توابع low level ارتباط با LCD رو خودم براش نوشتم و از توابع high level مثل sprintf استفاده نکردم که در حدود 10 تا 15 درصد حجمش کمتر از این برنامه شده .

عید همه مبارک .

Advertisements

دربارهٔ DeltaCode

Somewhere near the sky Far away from people Far away from noise Somewhere near yourself

Posted on مارس 20, 2011, in AVR. Bookmark the permalink. 2 دیدگاه.

  1. آخر سالی حسابی با AVR ترکوندی دلتا

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

    یه چیزی که یادم رفت اینه که برای اینکه در Mega8 از مد آسنکرون استفاده کنید باید منبع کلاک رو روی RC داخلی تنظیم کنید . موفق باشید .

پاسخی بگذارید

در پایین مشخصات خود را پر کنید یا برای ورود روی شمایل‌ها کلیک نمایید:

نشان‌وارهٔ وردپرس.کام

شما در حال بیان دیدگاه با حساب کاربری WordPress.com خود هستید. بیرون رفتن / تغییر دادن )

تصویر توییتر

شما در حال بیان دیدگاه با حساب کاربری Twitter خود هستید. بیرون رفتن / تغییر دادن )

عکس فیسبوک

شما در حال بیان دیدگاه با حساب کاربری Facebook خود هستید. بیرون رفتن / تغییر دادن )

عکس گوگل+

شما در حال بیان دیدگاه با حساب کاربری Google+ خود هستید. بیرون رفتن / تغییر دادن )

درحال اتصال به %s

%d وب‌نوشت‌نویس این را دوست دارند: