چرا ماژول ساعت؟
جهت ساخت یک ساعت دیجیتال دقیق می توان از RTC داخلی میکروکنترلر استفاده کرد. ولی مشکلی اساسی در این است که با قطع شدن تغذیه مدار یا ریست شدن میکروکنترلر، ساعت خاموش و متوقف خواهد شد.
اگر بخواهیم یک میکرو را به صورت همیشه روشن نگه داریم نیاز به باتری نیز خواهیم داشت و مشکل آنجا جدی می شود که با توجه به مصرف میکرو این باتری باید توان بالا و ظرفیت ذخیره زیاد نیز داشته باشد .
در این موارد که ما نیاز به ساعت دقیق داریم می توان از IC هایی مانند DS1307 استفاده کرد که علاوه بر ساعت دارای تقویم نیز می باشد و ورودی برای باتری بک آپ دارند که می تواند با یک باتری ۳ ولت سکه ای به مدت ۱۰ سال کار کند .
اصل این ماژول بر پایه آیسی ساعت DS1307 هست. که استفاده ازش رو ساده کرده و در صورت تمایل میتونید از خود آیسی استفاده کنید. و مدار زیر رو ببندید، ماژول DS1307 یسری قابلیت بیشتر داره، مثل راه اندازی سنسور دما که شاید بعضی از مدارات به دردتون بخوره. ولی خب اصل کاربردش ، ساعت و تاریخ هست که با آیسی هم میشه انجام داد.
مدار مورد نیاز برای راه اندازی آیسی DS1307
با ۴ تا از پایه های اصلی ماژول کار داریم و مابقی رو به جایی متصل نکنید!!!
- پایه Vcc به ۵ ولت مدار متصل بشه
- پایه Gnd به زمین یا منفی مدار متصل بشه
- پایه SCL به یکی از پایه های میکرو
- پایه SDA به یک پایه دیگر از میکرو
نکته: هر دو پایه متصل شده به میکرو باید از یک پورت باشد!!!
خب سخت افزار تکمیل هست و فقط باتری ماژول رو فراموش نکنید نصب کنید که ساعت و تاریخی که تنظیم میکنیم، زمان قطع برق مدار، ساعت و تاریخ رو حفظ کنه و از بین نره.
تنظیمات کدویزارد
حالا وارد کدویژن بشید و از قسمت کدویزارد تنظیمات زیر رو انجام بدید.
ابتدا تمامی تنظیمات اعم از میکرو و کلاک و دیگر تنظیمات پروژتون رو انجام بدید و در آخر به این قسمت برید.
- وارد تنظیمات پروتکل I2C شوید.
- پورت متصل به ماژول رو انتخاب کنید.
- پایه های SCL و SDA متصل شده به ماژول رو انتخاب کنید. (شماره پورت میکرو)
- مرحله آخر ماژول DS1307 رو پیدا کنید و فعالش کنید.
مابقی تنظیمات رو تغییر ندید و به حالت پیش فرض بذارید بمونه.
پس از انجام تنظیمات به جزئیات کد نویسی میپزدازیم، حتما مطمئن بشید که کتابخانه (ds1307.h) اول برنامه فراخوانی شده باشد.
نکته بعدی، باید قبل از حلقه اصلی برنامه یعنی WHILE (1) حتما پروتکل I2C و تابع RTC فراخوانی شده باشند.
توابع ماژول ساعت DS1307
rtc_init (0,0,0); RTC راه اندازی کتابخانه
rtc_get_time (ثانیه, دقیقه, ساعت); دریافت ساعت
rtc_set_time(ثانیه, دقیقه, ساعت); تنظیم ساعت
rtc_get_date(سال, ماه, روز, روز هفته); دریافت تاریخ و روز هفته
rtc_set_date(سال, ماه, روز, روز هفته); تنظیم تاریخ و روز هفته
نمایش ساعت
برای راه اندازی ساعت ابتدا توسط تابع (rtc_set_time) ساعت رو تنظیم میکنیم و پس از یکبار اجرا توسط میکرو کد را حذف میکنیم که دیگ تنظیممون بهم نخوره.
حالا کافیه با استفاده از تابع (rtc_get_time) زمان رو دریافت کنید و در متغییر ذخیره کنید و نمایش بدید و استفاده کنید، مانند کد زیر بر روی LCD ساعت و دقیقه و ثانیه رو نمایش میدیم.
#include
#include
#include
#include
#include
#include
char h=0,m=0,s=0;
i2c_init();
rtc_init(0,0,0);
lcd_init(16);
while (1)
{
rtc_get_time(&h,&m,&s);
lcd_clear();
lcd_gotoxy(0,0);
sprintf(buffer,%d:%d:%d" ,h,m,s);
lcd_puts(buffer);
delay_ms(20);
}
نمایش تاریخ میلادی و روز هفته
برای راه اندازی تاریخ ابتدا توسط تابع (rtc_set_date) تاریخ و روز هفته را تنظیم میکنیم و پس از یکبار اجرا توسط میکرو کد را حذف میکنیم که دیگ تنظیممون بهم نخوره.
حالا کافیه با استفاده از تابع (rtc_get_date) تاریخ رو دریافت کنید و در متغییر ذخیره کنید و نمایش بدید و استفاده کنید، مانند کد زیر بر روی LCD سال و ماه و روز و روز هفته رو نمایش میدیم.
#include
#include
#include
#include
#include
#include
char w , d, mo, y;
i2c_init();
rtc_init(0,0,0);
lcd_init(16);
while (1)
{
rtc_get_date(&w,&d,&mo,&y);
lcd_clear();
lcd_gotoxy(0,0);
sprintf(buffer,%d/%d/%d - %d",y+2000,mo,d,w);
lcd_puts(buffer);
delay_ms(20);
}
نمایش تاریخ شمسی
برای اینکه تاریخ میلادی به شمسی تبدیل بشه، از تابع زیر استفاده میکنیم.
flash unsigned char mi_table[6][12]={ //تابعي اعداد براي تبديل ميلادي به شمسي
{20,19,19,19,20,20,21,21,21,21,20,20},
{10,11,10,12,11,11,10,10,10,9,10,10},
{19,18,20,20,21,21,22,22,22,22,21,21},
{11,12,10,11,10,10,9,9,9,8,9,9},
{20,19,20,20,21,21,22,22,22,22,21,21},
{10,11,9,11,10,10,9,9,9,8,9,9}};
void MI_TO_SH(unsigned int ym,unsigned char mm,unsigned char dm)
{ //تابع تبديل سال و ماه و روز ميلادي به شمسي
unsigned int k,t1,t2;
//ym=(0x000f & ym);
k=ym%4;
if(k==3) k=2;
k*=2;
t1=mi_table[k][mm-1];
t2=mi_table[k+1][mm-1];
if(mm<3 || (mm==3 && dm<=mi_table[k][mm-1])) y=ym + 78;
else y=ym + 79;
if(dm<=t1)
{ //تبديل روز و ماه
d=dm+t2;
mo=(mm+8)%12+1;
}
else
{
d=dm-t1;
mo=(mm+9)%12+1;
}
}
پس از اضافه کردن متغییر (flash unsigned char mi_table) به ابتدا برنامه و تابع (void MI_TO_SH) به قبل از تابع اصلی main برنامه، میتوانید در هر جای کدتون ازش استفاده کنید. این تابع در کامپایلر های مبتنی بر زبان C مانند کدویژن یا آردوینو قابل استفاده است!
به کد زیر توجه کنید، دقیقا مانند تاریخ میلادی عمل میکنیم و فقط پس از دریافت تاریخ توسط تابع (rtc_get_date) مقادیر رو به تابع جدید میدیم تا تبدیل کنه و پس از اون مقدار های جدید رو نمایش میدیم.
#include
#include
#include
#include
#include
#include
char w , d, mo, y;
i2c_init();
rtc_init(0,0,0);
lcd_init(16);
while (1)
{
rtc_get_date(&w,&d,&mo,&y);
MI_TO_SH(y,mo,d);
lcd_clear();
lcd_gotoxy(0,0);
sprintf(buffer,%d/%d/%d - %d",y+1300,mo,d,w);
lcd_puts(buffer);
delay_ms(20);
}
نکته: تاریخ در ماژول ساعت به صورت ۲ رقمی هست. یعنی برای سال میلادی باید از ۲۱ استفاده کنید (۲۰۲۱) و برای تاریخ شمس از ۱۰۰ (۱۴۰۰). اگر توجه کرده باشید تاریخ میلادی ۲۰۰۰ و تاریخ شمسی ۱۳۰۰ کمتره پس این رو هنگام نمایش میتونید اضافه کنید.
دوباره به کد ها بالا دقت کنید تا بهتر این موضوع رو متوجه بشید
تمامی بخش های راه اندازی ماژول ساعت DS1307 رو با هم برسی کردیم و امیدوارم براتون مفید و کاربردی باشه، اگر در هر قسمت مشکلی داشتید و یا سوالی بود حتما در قسمت دیدگاه ها بنویسید تا سریع جواب بدم، نظرات و توجهتون به مطالب باعث انگیزه ما میشه
آقا خیلی عالی و مفید
سلام مهندس جان راجب این تابع ست دیتا که فرمودید برای تنظیم ساعت هست میشه بیشتر توزیح بدید ؟
یعنی منظورم اینه که این تابع رو فقط یکبار خونده شه خودش ست میکنه یا باید مقدار بهش داده بشه؟
ممنون میشم اگه راهنمایی کنید.
سلام در بخش توابع ماژول توضیح دادم؛ تابع تنظیم تاریخ و ساعت هم در ابتدای راه اندازی باید انجام شود، چون آیسی اطلاعاتی ندارد و هم در صورت نیاز به تغییر زمان، مجدد از این تابع برای ست کردن تاریخ و ساعت صحیح استفاده کنید!
سلام خداقوت
روزای هفته با عدد نشون میده
جمعه و شبه رو با چه عددی نمایش میده؟
سلام خروجی روز های هفته متغییری بین 0 تا 6 است که 0 شنبه و 6 جمعه می باشد. از 1 تا 5 هم روز های یکشنبه الی پنجشنبه هست!
آقا دمت گرم
کارت عالیه مهندس جان
ممنون از نظرتون 🙂
سلام
مرسی بابت آموزشی که گذاشتید ،برای درک بهتر این آموزش توسط ما کارآموزان،پیشنهاد میکنم زحمت بکشید و سورس برنامه رو هم بذارید،ممنون موفق باشید
سلام در انتها آموزش نمونه برنامه این پروژه قرار داده شده که به سادگی میتونید تست کنید!
ممنون میشم سورس کدتونو بزارین چون من داخل تبدیل تاریخ میلادی به شمسی گیر کردم
سلام حتما فایل زیپ کامل کد هاشو میذارم
سلام خسته نباشید
من با استفاده از اموزشتون این برنامه و نوشتم ولی ازم دوتا ارور میگیره میگه buffer تغریف نکردید
میشه لطفا بگید باید چیکار کنم
سلام واتساپم عکس ارور رو بفرستید ببینم
۰۹۱۴۰۳۶۰۸۳۶
عجب پروژه ایی بود مهندس یک