به دلیل گسترده بودن این مطلب در حال تکمیل است .
سلام
شاید الان پیش خودتون بگید که خوب این چه کاریه آخه این همه کتابخانه مال ال سی دی کارکتری هست خوب با اون کار میکنیم میره دیگه خیلی هم راحت است چرا به خودمون زحمت بدیم .
عرض کنم خدمتتون که دوستان گرامی اگر با کسانی که بطور حرفه ای و تخصصی و صنعتی و نظامی با میکرو کنترلر ها ( کلا خانواده میکرو کنترلرها از مرحوم Z80 بگیر تا سرور ارجمند ARM11 ) کار کرده باشن صحبت کرده باشین و یا نگاهی به برنامه نویسیشون بندازین یه نکته که زیاد باهاش روبرو میشید این است که این دوستان اصلا از کتابخانه های آماده استفاده نمی کنند و برای کارهای خودشان بر حسب نیاز کتابخانه مینوسن .
اصلا هم کار سختی نیست و خیلی هم راحتته .
حالا حتما می پرسید چرا خوب چه کاریه مگه ؟؟؟؟
خوب جواب سوال شما رو با یک مثال خدمتتون عرض میکنم .
ببنید دوستان در میکرو کنترلر AVR یک بخشی وجود دارد به اسم تایمر نگهبان یا همون WATCH DOG که این بنده خدا تایمر گرامی میاد به برنامه نویس کمک میکنه که مثلا اگر بیشتر از د وثانیه میکرو سر یه دستوری ماند میکرو رو ریست میکند .
نمیدونم با این تایمر نگهبان کار کردین یا نه اما یه نکته خیلی مهم و اساسی در این تایمر وجود دارد و آن هم این نکته که توابع استفاده شده در این تایمر و توابع استفاده شده در تابع DELAY که به وفور در میکرو کنترلرها از آن استفاده میشود دو دشمن خونی هم هستند.
لابد میپرسید چرا ؟
جواب ساده تر از چیزی هست که فکر کنید .
تابع DELAY مثلا یه تابعی هست که با مقداری که ما به آن میدهیم یک تاخیری برای ما ایجاد میکند . خوب مشکل دقیقا همینجاست .اگر در کتابخانه DELAY نوشته شده درون کدویزن یا این قبیل برنامه ها کمی دقت کنیم میبینیم که با همر بار استفاده از این کتابخانه DELAY در واقع یک بار هم داریم تایمر نگهبان رو ریست میکنیم . و اگر در داخل برنامه اصلی نوشته شده خودمان از تایمر نگهبان هم استفاده کرده باشیم با این تابع DELAY همه چیز به هم میرزه چون ناخودآگاه ما خودمان هرجا که تابع DELAY رو فراخونی کردیم همونجا هم داریم تایمر نگهبان رو ریست میکنیم .
ازاین قبیل مسائل در داخل کتابخانه های اماده بسیار زیاد است . این یک نمونه واضح و مشهود بود .
برهمین دلیل و اساس معمولا اشخاص حرفه ای زیاد با این کتابخانه های اماده کار نمیکنن و خودشان معمولاسعی در نوشتن کتابخانه دارن .
یکی از قطعاتی که معمولا خیلی راحت میشه برای آن کتابخانه نوشت و بسیار پرکاربرد است ال سی دی کارکتری است .
خوب مواد لازم :
ال سی دی کارکتری
میکرو کنترلر
صبر ایوب
خوب اول یه نگاه به دیتا شیت بندازید . ما در اینجا به صفحات ۳۲ و ۳۳ این دیتا شیت بسیار احتیاج داریم؛ خوب ببیند حتما خودتون بهتر میدونید که پایه های این ال سی دی کارکتری ترتیبشون چطوری هست.
از چپ به راست به پایه ها نگاه کنید .
پایه اول GND – مشخصه دیگه توضیح نمیخواد
پایه دوم VCC – مشخصه دیگه توضیح نمیخواد
پایه سوم VEE – که وصل میشه یه سر وسطیه پتانسیومتر برای کنتراست ال سی دی هست
پایه RSS – پایه ارسال دستور
`پایه R/W – پایه تعیین وضعیت خواندن یا نوشتن که دیگه خواندن از ال سی دی منقرض شده فقط روش مینوسیم . میتوان آنرا زمین هم کرد.
پایهE – پایه ENABLE
پایه های D0 تا D7 – مربوط به ارسال دیتا می باشد .
پایه های LED+ و LED – هم که مبروطبه بک لایت ال سی دی هست.
در صفحات ۳۲ و ۳۳ دیتاشیت ال سی دی کارکتری توضیحاتی در مورد راه اندازی ال سی دی کارکتری در مد هشت بیت و چهار بیت داده شده است .
معمولا ال سی دی کارکتری را در مد ۴ بیتی راه اندازی میکنند چون لزومی ندارد که بیخود ۴ پایه دیگر میکرو را برای راه ندازی ال سی دی مصرف کنیم
خوب بریم سر اصل مطلب .
دستورات این بخش بر پایه میکرو کنترلر arm 2138 نوشته شده است . در مورد بقیه میکرو کنترلرها فقط نیاز به تغییر ساختار دستورات ورودی و خروجی کردن میکروی مورد نظر شما است .
خوب بریم سر اصل مطلب
خوب دوستان
در این فلو چارت مانندی که در صفحه ۳۳ دیتاشیت کارکتری ملاحظه میکنید دقیقا روند کار به وضوح توضیح داده شده است فقط کافی است که خط به خط این روند را ادامه بدهیم.
در ابتدای کار برای اینکه بتوان از این کتابخانه همه جا به راحتی استفاده کرد یک سری ثوابت تعریف میکنیم به شرح زیر :
1 2 3 4 5 6 |
#define rsclr IO1CLR=1<<28; #define rwclr IO1CLR=1<<29; #define enclr IO1CLR=1<<31; #define rsset IO1SET=1<<28; #define rwset IO1SET=1<<29; #define enset IO1SET=1<<31; |
((در مورد تعیین این ثباتها لازم به توضیح است که عبارت define که کلا در زبان سی ثابت است جلوش نام ثبات نوشته شده است مثلا rsclr نکته مهم که لازم به توضیح است بخش
1 |
IO1CLR=1<<28 |
میباشد عبارت ۲۸>>1 در واقع به این معنی است که یک را ۲۸ بار شیفت به شپ بده و در مورد عبارت IO1CLR لازم به توضیح است که در میکرو کنترلر ۲۱۳۸ دستور پاک کردن پورت است و همچین دستور IO1set برای ست کردن پورت ))
همانطورکه از دستورات بالا متوجه شدین ما پایه های
rs= p1.28
rw= p1.29
en =p1.31
متصل کرده ایم .
خوب ما وقتی بخواهیم بایان ال سی دی کار کنیم احتیاج به تعریف دو تابع اصلی برای ارسال دستورات و اطلاعات داریم .
دستورات در واقع همان رفتن به سطر وستون و پاک کردن و این قبیل فرامین است .
اطلاعات هم همان مطالبی است که ما میخواهیم چاپ کنیم روی ال سی دی .
پس دو تابع می سازیم
یکی به نام comm مخفف command به معنی دستورات
1 2 3 4 5 6 7 8 9 10 11 |
void comm(unsigned char c) { IO1CLR|=0xf<<24; IO1SET|=c<<24; rsclr; rwclr; enset; delaylcd(); enclr; delaylcd(); } |
و تابع datw مخفف data write به معنی
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
void datw(unsigned char c) { unsigned char ch,cl; ch=(c>>4); cl=c&0x0f; IO1CLR|=0xf<<24; IO1SET|=ch<<24; rsset; rwclr; enset; delaylcd(); enclr; delaylcd(); IO1CLR|=0xf<<24; IO1SET|=cl<<24; rsset; rwclr; enset; delaylcd(); enclr; delaylcd(); } |
خوب بخونیم ببینم چی نوشته
خط اول نوشته POWER ON کلا منظورش زمان روشن شدن برد است چون ما هیچ وقت روشن کردن ال سی دی خالی که بدردمون نمیخوه معمولا ال سی دی به میکرو متصل است .
در خط بعد نوشته شده که
1 |
wait more than 15 ms after vcc=4.5 v |
خوب در این خط هم امده است که از زمانی که ولتاژ منبع تغذیت به ۴٫۵ولت برسد باید ۱۵ میلی ثانیه صبر کنی . این صبر کردن برای زمان راه اندازی ال سی دی کارکتری است . اگرپشت ال سی دی رو دیده باشین دو تا میکروی کوچک داره این زمان مال راه اندازی ان دو میکرو است . اگر از ۱۵ میلی ثانیه هم بیشتر شد هیچ عیبی ندارد .
پس برای اطمینان بیشتر ما این کد را مینوسیم .
1 |
delay_ms (30); |
در خط بعد با کد زیر روبرو میشویم .
که درواقع معادل کد ۰x03 هگز میباشد .
1 |
comm(0x3); |
خط بعد نوشته شده است که بیشتر از ۴٫۱ میلی ثانیه صبر کنید .
1 |
delay_ms(5); |
در خط بعد با کد زیر روبرو میشویم .
که درواقع معادل کد ۰x03 هگز میباشد .
1 |
comm(0x3); |
خط بعد نوشته شده است که بیشتر از صد میکرو ثانیه صبر کنید .
خط بعد نوشته شده است که بیشتر از ۴٫۱ میلی ثانیه صبر کنید .
1 |
delay_ms(2); |
در خط بعد با کد زیر روبرو میشویم .
که درواقع معادل کد ۰x03 هگز میباشد .
1 |
comm(0x3); |
و سپس میرسیم به اصل مطلب که به میکروهای داخل lcd اطلاع بدهیم که قرار است با ال سی دی در مد ۴ بیت کار کنیم .
با دستور زیر :
که معادل کد دو هگز می باشد .
1 |
comm(0x2); |
بهتر است بعد از این کد باز هم کمی تاخیرایجاد کنیم .
1 |
delay_ms(2); |
تا انی بخش از مبحث ال سی دی کارکتری راه اندازی شد
در پایین صفحه ۳۳ با جدول زیر روبرو می شویم :
که انشالله به زودی در مورد این جدول توضیح میدم
تا اینجای کار دستورات نوشته شده به شرح زیراست.
فقط کافیست در مورد ورودی و خروجی کردن پورتها خودتان بر اساس میکروی مورد نظرتان تغییراتی در پایه ها و دستورات ورودی و خورجی انجام دهید .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
#define rsclr IO1CLR=1<<28; #define rwclr IO1CLR=1<<29; #define enclr IO1CLR=1<<31; #define rsset IO1SET=1<<28; #define rwset IO1SET=1<<29; #define enset IO1SET=1<<31; void delaylcd(void) { int j; for(j=0;j<0xfff;j++); } void comm(unsigned char c) { IO1CLR|=0xf<<24; IO1SET|=c<<24; rsclr; rwclr; enset; delaylcd(); enclr; delaylcd(); } void datw(unsigned char c) { unsigned char ch,cl; ch=(c>>4); cl=c&0x0f; IO1CLR|=0xf<<24; IO1SET|=ch<<24; rsset; rwclr; enset; delaylcd(); enclr; delaylcd(); IO1CLR|=0xf<<24; IO1SET|=cl<<24; rsset; rwclr; enset; delaylcd(); enclr; delaylcd(); } void lcd_init(void) { IO1DIR|=0xff<<24; delaylcd(); comm(0x3); delaylcd(); comm(0x3); delaylcd(); comm(0x3); delaylcd(); comm(0x2); delaylcd(); comm(0x2); delaylcd(); comm(0x8); delaylcd(); comm(0x0); delaylcd(); comm(0x6); delaylcd(); comm(0x0); delaylcd(); comm(0x1); delaylcd(); comm(0x0); delaylcd(); comm(0xe); delaylcd(); } void lcd_clear(void) { comm(0); comm(1); } void lcd_putchar(char c) { datw(c); } void lcd_putsf(char *s) { char k; while (k=*s++) lcd_putchar(k); } void lcd_puts(char *s) { char k; while (k=*s++) lcd_putchar(k); } void lcd_gotoxy(unsigned char x,unsigned char y) { if(y==0) comm(0x80+x); if(y==1) comm(0xc0+x); } |
دو مطلب باقی مانده که انشالله به زودی تکمیل میشود
یک مطلب ارسال اطلاعات به صورت چهار بیت چهار بیت به ال سی دی
مطلب دوم جدول اخر دیتا شیت.
به امید دیدار
التماس دعا
مهمان
سلام استاد وقت بخیر
من یه کدی دارم که در اون باید از lcd استفاده کنم مشکل اینجاست که در اول تابع main من lcd را راه اندازی میکنم و یه متن روی اون نمایش میدم ولی در وسط کد که می خوام یه متن دیگه نمایش بدم بعد اینکه lcd را پاک میکنم متن مورد نظر نمایش داده نمیشه و lcd همینطوری پاک شده میمونه و هیچ متنی را نمایش نمیده !!
مهمان
با سلام. با توجه به این که قسمت پایانی این مطلب ناتمام مانده یک ویدئو توسط بنده در خصوص این آموزش به طور کامل تهیه شده. اگر ادمین عزیز صلاح بدونن واسه کاربرا قرار بدن.
لینک ویدئو : https://www.aparat.com/v/cCai1
مهمان
با سلام خدمت دوستان. با توجه به این که این مطلب ناقص رها شده و مهمترین قسمت اون ذکر نشده لینک ویدئوی آموزش راه اندازی LCD بدون کتابخانه در حالت 4 بیتی در آپارات. (البته با اجازه ادمین محترم در صورت صلاحدید کامنت رو منتشر کنن)
https://www.aparat.com/v/cCai1
مهمان
با سلام. کاش پستی هم در خصوص مبانی نوشتن کلی کتابخانه برای ال سی دی های رنگی (5 اینچ به بالا) در سایت قرار داده شود.
مدیر سایت
سلام
کلا نوشتن کتابخونه چیز خاصی نداره – یه کتابخونه ساده برا یه قطعه بنویسی یعنی روال نوشتن کتابخونه دستت اومده – بعد باید بری سراغ دیتاشیت lcd یا سنسور و … مد نظرتون و طبق دستورالعمل های دیتاشیت براش تابع بنویسید.
برای هر قطعه متفاوت هستش و نمیشه برا همشون آموزش نوشتن کتابخونه گزاشت – منطقی نی
مهمان
سلام –
دوست عزیز ممنون از مطالبی که ارائه دادید
ولی شما که میگین خیلی هم راحته اگر حوصله ندارید لااقل اشاره ای کنید که دستوری که استفاده شده چه کاری انجام میده
مهمان
سلام تابع comm() چیه؟
مهمان
سلام خدا خیرتون بده
قسمت دوم رو کی میذارید؟
مدیر سایت
سلام
متاسفانه نویسنده مطلب این مطلب رو گزاشت و ادامه نداد دیگه…
مهمان
سلام
عالی بود!
مهمان
منتظر قسمت بعدی هستیم
مهمان
سلام ممنون بابت این آموزش جامع این مطالب به درد تمام کسانی که با arm یا avr یا هر میکرویی که کار میکنن میخوره منتظر قسمت دوم هم هستیم.
مهمان
واقعا ممنون از سایت خوبتون حرف نداره.
مهمان
سلام آقا مهدی دمرچیلو .
از بس که شما سرتون رو به دیوار کوبیدید من نگران تون شدم
بالاخره من هم دل دارم و از دیدن صحنه ی دل خراش قلبم به درد میاد .
موفق باشید انشاءالله .
مدیر سایت
سلام

مهمان
سلام بازم ممنون از توضیحاتت و وقتی که گذاشتی .
نویسنده این مطلب
بله اقا محسن کاملا حق با شماست
نویسنده سایت
سلام به دوستان.
تبریک میگم بابت شروع این روند تو سایت.
ببینید نوشتن یک کتابخونه از نظر من وابستگی به کامپایلر نداره. یعنی شما کافیه برای یک قطعه یا ماژول کتابخونه بنویسید، بعد از اون کافیه اصول زبان برنامه نویسی مد نظرتون رو بدونید و همه چی حله.
مثلا همین LCD کارکتری، شما بتونی برای AVR و به زبان C کتابخونه بنویسی، برای ARM هم خواهی تونست و برای FPGA هم همینطور. چون دید برنامه نویسی رو پیدا کردی.
نویسنده این مطلب
سلام علی جان دوست گرامی
ممنونم نظر لطف شماست
والامن خودم هم در زمینه آرم تازه کارم
اما کمر همت رو محکم بستم
منم با السیدی کارکتری گیرم شروع کردم نوشتن کتابخانه
در مورد ۲۸>>1 این مطلب که فرمودین عرض کنم که دوست گرامی والا کار کردن و برنامه نویسی با میکرو کنترلر ها بطور کلی گذشته از اینکه صبرو طاقت خیلی زیادی میخواد (( منظورم مطالع هست . لزوما نه خواندن کتابهای مختلف بیشتر منظورم این است که شما پروزه های که دوستان در سایتها گزاشتن رو بگیری و ببینی سورس کد چطوریه و چه مدلی نوشتن و خلاصه یه چیزایی دستت بیاد )) مهارت برنامه نویسی هم میخواد
من خودم خیلی دوست دارم یه برنامه نویس حرفه ای بشم ولی متاسفانه هنوز راه زیادی مونده
دوست عزیز من اطلاعتی که من تا این جا دارم در مورد دستور شیفت که فرمودین ممکن است سرعت برنامه رو کاهش بده عرض کنم که در زمانی که ما با مرحوم میکرو کنترلرهایی مثل z80 و خانواده 8051 کار میکردیم جدا ازبحث برنامه نویسی یک بحثی که مطرح بوذ بحث ماشین سیکل و محاسبه اون تو تاخیرات بود
حالا اگربخوام توضیحی درمرود ماشین سیکلبدم خیلی راحت و رون بگم در اون میکرو کنترلرهای مرحوم که عرض کردم برای دستورات یک ماشین سیکل گزاشته بودن مثلا میگفتن که دستورجمع در برنامه دو ماشین سیکل میخواهد که دستور انجام شود ((رجوع کنید به صفحات آخرین کتاب میکرو کنترلرهای 8051 استاد ارجمند قدرت سپید نام))
بعد که پرونده کار با این میکرو ها را بستیم و گزاشتیم کنار و رفتیم سراغ avr از استادی که در این زمینه داشتم چندین بار پرسیدم که آیا اون مبحث ماشین سیکل اینجا هم مطرح هست یا نه که همشون متفق القول گفتن خیر
دیگه منم زیاد دنبالش نرفتم ولی فکر کنم از avr به بعد همه دستورات در یک ماشین سیکل انجام میشوند . البته بگما علت دقیق رو هنوز خودم هم نمیدونم .
مورد بعد هم همانطور که بالاتر گفتم من خودم علاقه زیادی به خواندن سورس کد های نوشته شده توسط دوستان واساتید محترم دارم ((حداقل برای الهام گرفتن خیلی خوبه حتما اینکاررو انجام بدین )) در خیلی از برنامه های نوشته شده توسط بزرگان به وضوح برای مقدار دهی های اینچنینی شاهد این بودم که از دستور شیفت استفاده کردن
توجه شما را جلب میکنم به فیلمهای آموزشی avr استاد ارجمند جناب آقای کی نزاد دقیقا بخاطر دارم که ایشان در همان مباحث اولیه ذکر کردن که هم میتوان بطور مستقسم عدد داد هم میتوان اینطوری شیفت داد .و ذکر کردن که شیفت دادن حرفه ای تر است . و من هم مرید استادیم هستم و همان راه را میرویم.
در ضمن شما فکر کن که میخوای روی یک پورت سی و دو بیتی مثلا چند تا رو ورودی و چند تا رو خروجی کنی خوب پیدا کردن این عدد کمی سخت است اما شیفت خیلی راحت مشکل حل میشه .
قربان شما .
مدیر سایت
منم تو فکرش بودم ولی حیف که داشمون برا آرم داره چیز میکنه
…اگه برا FPGA بود منم مشتری مطالبش میشدم 

ولی در کل دمت گرم داش خسته نباشی
مهمان
سلام خیلی عالی بود.بی صبرانه منتظر بقیشم.کتابخونه هایی که واسه ارم هستش رو خیلی امتحان کردم و واقعا کندن و بدرد نخور.خیلی دوست داشتم سر یه فرصت خودم یدونه بنویسم.
یه سوال:وقتی دیفاین رو به صورت 28>>1 مینویسین این خودش سرعت برنامه رو کاهش نمیده ؟هربار که از اون ثابت استفاده میکنید این یک رو 28بار شیفت میده.به جاش عدد رو بذارید یه راست که بهتره.