پیش نیاز : دوره آموزشی AVR
دسترسی سریع به بخش های قبلی :
مقدمه
مهمترین تفاوت میان برنامه نویسی ARM7 و AVR یکی عدم وجود ابزاری همانند کدویزارد است که بخش مهم و رجیستری کدها را برای ما تولید کند و دیگری عدم وجود هدر فایل هایی نظیر delay.h ، lcd.h و … در کامپایلر KEIL است. در این فصل و فصل های بعدی توابع و هدر فایل هایی خواهیم ساخت که با استفاده از آن ها میتوان همانند برنامه نویسی که در AVR وجود داشت ، برای ARM7 نیز مشابه آنها استفاده کرد.
واحد GPIO سریع
این واحد یکی از ویژگی های بهبود یافته در پورت های میکروکنترلرهای ARM7 شرکت NXP می باشد. همان پورت های در دسترسی که به صورت GPIO استفاده می شوند ، میتوانند به صورت سریعتر عمل کنند. یعنی سرعت تغییر آنها از 0 به 1 و بالعکس در این واحد سریعتر می باشد. رجیسترهای تنظیمات این واحد یک F در ابتدای نام رجیسترهای GPIO تفاوت دارد. در حقیقت Fast GPIO و GPIO در عمل دو واحد مجزا هستند که هر دو از پورت های یکسان استفاده می کنند. شکل زیر تفاوت میان واحد ورودی/خروجی معمولی را با سریع نشان می دهد. واحد Fast GPIO به باس پرسرعت وصل است و نهایت سرعتی که دارد ، سرعت AHB است اما واحد GPIO به APB متصل است و بسته به ضریب تقسیم کننده APB معمولا سرعت کمتری دارد.
نتیجه گیری : برای استفاده از واحد Fast GPIO در پروژه هایی که به سرعت تغییر بالای پورت ها نیاز داریم ، به جای رجیسترهایی که داشتیم از FIODIR ، FIOPIN ، FIOCLR و FIOSET استفاده می کنیم.
نکته مهم : در صورتی که بیشتر از یک IO در میکروکنترلر داشته باشیم ، که برای میکروکنترلر LPC2138 دو واحد داریم ، بعد از FIO عدد 0 یا 1 گذاشته می شود. در نتیجه رجیسترهای فوق به صورت FIOXCLR ، FIOXPIN ، FIOXDIR و FIOXSET در می آید که به جای X در میکروکنترلر LPC2138 ، عدد 0 یا 1 بسته به پورت انتخابی قرار می گیرد.
تعریف توابع تاخیر ( delay ) در ARM7
همانطور که در بخش قبل گفتیم و دیدید ، در کامپایلر KEIL هدر فایلی برای delay وجود ندارد. اما می خواهیم خودمان با استفاده از دانش کلاک سیستم ، به طور تقریبی این delay ها را ایجاد کنیم. با اضافه کردن چند خط زیر به ابتدای برنامه میتوان از توابع delay_s ، delay_ms و delay_us در پروژه ها استفاده نمود.
نکته : این توابع از دقت کاملا نسبی برخوردار هستند و از آنها به حسب نیاز در راه اندازی کلید ، صفحه کلید و … میتوان استفاده نمود و برای داشتن تاخیر دقیق باید از واحد Timer میکرو استفاده کرد.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#define CCLK 12000000 void delay_s (unsigned int x) { x=x*CCLK; while(x--); } void delay_ms(unsigned int x) { x=x*(CCLK/1000); while(x--); } void delay_us(unsigned int x) { x=x*(CCLK/1000000); while(x--); } |
توضیح : در ابتدا مقدار کلاک کاری CPU را تعریف می کنیم. ( اگر از PLL استفاده کردیم باید مقدار دقیق CCLK را مشخص کنیم ) سپس سه تابع تعریف کردیم و آنها را delay_s ، delay_ms و delay_us تعریف کردیم. با فرض اینکه هر یک واحد کم شدن متغیر x ، یک سیکل کلاک طول می کشد ، میتوان گفت هر ثانیه تقریبا 12000000 کلاک طول می کشد.
نکته : در عمل نمیتوان دقیقا مشخص کرد که حلقه while برای اجرا چند سیکل کلاک طول می کشد اما معمولا بین 1 تا 4 سیکل برای آن میتوان در نظر گرفت. در نتیجه تخمین توابع تعریف شده فوق ، در خوشبینانه ترین حالت هستند و در پروژه های مختلف بسته به نیاز میتوانید خودتان آن ها را کم یا زیاد کنید.
راه اندازی کلید در LPC2138
راه اندازی کلید به عنوان ورودی در میکروکنترلرهای ARM کاملا شبیه میکروکنترلرهای AVR است با این تفاوت که به جای استفاده از رجیستر PINX از رجیستر IOXPIN استفاده می شود و دسترسی بیتی به رجیسترها در کامپایلر KEIL وجود ندارد.
نکته : دسترسی به بیت های رجیسترهای پورت در کامپایلر KEIL همانند میکروکنترلرهای AVR به صورت نقطه ای ممکن نیست ( مثلا نمیتوان نوشت IO0PIN.0 غلط است).
راهکار خواندن از رجیستر PIN :
فرض کنید که کلیدی به صورت پول آپ شده به یکی از پورت های میکرو متصل است. برای اینکه کلید زده شده است یا خیر باید منطق پورت را خواند. برای خواندن منطق پورت از رجیستر IOPIN استفاده می شود. چون دسترسی به یک بیت از این رجیستر وجود ندارد برای فهمیدن منطق یک بیت از این رجیستر از عملگر & استفاده می کنیم. عدد 1 را به اندازه بیت مورد نظر شیفت داده و با رجیستر AND ، IOPIN می کنیم.
برای مثال : برای خواندن منطق کلیدی که به صورت پول آپ به پورت P0.15 وصل شده است ، میتوان نوشت :
1 |
if( ( IO0PIN & (1<<15) ) == 0 ) ); |
نکته 1 : بهترین مقدار برای مقاومت پول آپ در میکروکنترلرهای ARM به علت اینکه تغذیه 3.3 ولت دارند ، 2.2K یا 3.3k است.
نکته 2 : پول آپ داخلی در میکروکنترلرهای ARM7 شرکت NXP وجود ندارد.
کلید نوع ۱ :
1 2 3 4 5 |
if( ( IO0PIN & (1<<15) ) == 0 ) ) { دستورات مربوط به بعد از زدن کلید delay_ms(200); } |
توضیح : به محض فشار دادن کلید توسط کاربر شرط if برقرار شده و دستورات مورد نظر اجرا می شود سپس به علت ایجاد تاخیر زیاد توسط تابع delay_ms ( در اینجا ۲۰۰ میلی ثانیه ) با این کار احتمال اینکه زمانی که برنامه در حلقه while به if می رسد و شرط برقرار باشد ، کاهش می یابد . مزیت این کلید این است که در صورتی که کاربر کلید را فشار داده و نگه دارد تقریبا در هر ۲۰۰ میلی ثانیه یکبار کار مورد نظر صورت می گیرد . عیب این روش نیز این است که هنوز احتمال دارد که زمانی که یکبار کلید زده شود ، دوبار کار مورد نظر انجام شود .
کلید نوع ۲ :
1 2 3 4 5 6 |
if( ( IO0PIN & (1<<15) ) == 0 ) ) { delay_ms(20); while(( IO0PIN & (1<<15)) == 0 )); دستورات مربوط به بعد از زدن کلید } |
توضیح : به محض فشار دادن کلید توسط کاربر شرط if برقرار شده و برنامه به مدت ۲۰ میلی ثانیه صبر می کند تا منطق کلید ثابت شود و از منطقه bounce عبور کند سپس توسط حلقه while با همان شرط برقراری کلید در این مرحله برنامه تا زمانی که کلید توسط کاربر فشرده شده است در حلقه گیر می کند و هیچ کاری انجام نمی دهد . به محض اینکه کاربر دست خود را بر می دارد ، شرط برقرار نبوده و خط بعدی یعنی دستورات مربوطه اجرا می شود . مزیت این روش این است که در هر بار فشردن کلید برنامه تنها یکبار اجرا می شود . معایب این روش این است که تا زمانی که کاربر کلید را نگه داشته اتفاقی نمی افتد و به محض رها کردن کلید کار مورد نظر انجام می شود .
کلید نوع ۳ :
1 2 3 4 5 6 |
if((( IO0PIN & (1<<15)) == 0 ) && (flag==0)) { flag=1; start=!start; } else if (( IO0PIN & (1<<15) ) == 0 ) flag=0; if(start){ دستورات مربوط به بعد از زدن کلید } |
توضیح : این کلید به صورت start/stop عمل می کند یعنی بار اولی که کاربر کلید را فشار می دهد دستورات مربوط به بعد از زدن کلید دائما اجرا می شود تا زمانی که کاربر دست خود را از روی کلید رها کرده و دوباره کلید را فشار دهد ، در این صورت دستورات دیگر اجرا نمی شود . دو متغیر از نوع bit با نام های flag و start با مقدار اولیه ۰ برای این کلید باید تعریف شود . زمانی که کاربر برای اولین بار کلید را فشار می دهد شرط if برقرار شده و flag=1 و start=1 می شود . در این صورت شرط if دوم برقرار بوده و دستورات مربوطه با هر بار چرخش برنامه درون حلقه نامتناهی while یکبار اجرا می شود . زمانی که کاربر دست خود را از روی کلید بر می دارد و منطق ۱ وارد میکرو می شود flag=0 شده و برنامه دوباره آماده این می شود که کاربر برای بار دوم کلید را فشار دهد . زمانی که کاربر بار دوم کلید را می فشارد start=0 شده و دستوراط مربوطه اجرا نخواهد شد سپس با برداشته شدن دست کاربر از روی کلید، همه چیز به حالت اول بر میگردد . این کلید طوری نوشته شده است که bounce در آن کمترین تاثیر مخرب ممکن را دارد .
مثال عملی شماره 3 : با استفاده از یک کلید و 8 عدد LED متصل به میکروکنترلر LPC2138 برنامه ای بنویسید که با هر بار فشار دادن کلید ، شمارنده های حلقوی و جانسون اجرا شود.
لینک دانلود سورس مثال عملی شماره 3
راه اندازی سون سگمنت
یکی از نمایشگرهای پرکاربرد سون سگمنت است که می توان توسط آن اعداد و برخی از حروف ها را نشان داد. روش های متفاوت و مختلفی برای راه اندازی سون سگمنت وجود دارد که ساده ترین آن استفاده از مداری به شکل زیر است.
تذکر : در نرم افزار proteus بیت هشتم سون سگمنت که پایهdigit می باشد، وجود ندارد.
برای نشان دادن اعداد روی سون سگمنت کافی است پایه مربوطه را پس از خروجی کردن یک کنیم برای مثال برای نشان دادن عدد یک باید سگمنت های b و c روشن شود ، در نتیجه باید P0.4 و P0.5 را 1 نمود. بنابراین دستور زیر عدد یک را روی سون سگمنت نمایش می دهد.
1 |
IO0SET |= (3<<4); |
برای بقیه اعداد نیز این کار را تکرار کرده و دستور مورد نظر برای آن را می یابیم. سپس تمامی این مقادیر را درون یک آرایه ریخته تا بتوان راحت تر از آن استفاده نمود.
برای بدست آوردن راحت تر این مقادیر میتوان ابتدا فرض نمود که سون سگمنت به پایه های P0.0 تا P0.6 میکرو متصل شده باشد. سپس با این فرض مقادیر را بدست آورده و در نهایت به مقداری که مورد نیاز است شیفت اعمال شود.
با فرض فوق آرایه زیر برای سون سگمنت کاتد مشترک بدست می آید :
1 |
unsigned char seg[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; |
هر عددی که بخواهیم روی سون سگمنت نمایش دهیم کافی است داخل [ ] قرار دهیم و به اندازه مورد نیاز شیفت دهیم تا به کد سون سگمنت تبدیل شود. یعنی :
1 |
IO0SET |= (seg[ i ]<<4); |
همانطور که مشاهده می کنید در این روش علاوه بر تعریف یک آرایه و اشغال شدن شش پایه از میکرو ، مشکل دیگری نیز وجود دارد و آن روشنایی کم سگمنت ها در هنگام پیاده سازی مدار است. این موضوع به علت جریان دهی کم پایه های میکرو می باشد. چرا که برای روشنایی مناسب هر سگمنت به 20 میلی آمپر جریان نیاز دارد در حالی که میکرو توانایی تامین 10 میلی آمپر جریان را دارد.
مثال عملی شماره 4 : با استفاده از یک سون سگمنت متصل به میکروکنترلر LPC2138 برنامه ای بنویسید که اعداد 0 تا 9 را به ترتیب روی آن نشان دهد.
لینک دانلود سورس مثال عملی شماره 4
راه اندازی سون سگمنت مالتی پلکس
زمانی که تعداد بیشتری سون سگمنت در پروژه مورد نیاز باشد ، بهتر است از سون سگمنت های مالتی پلکس شده استفاده نمود. تنها تفاوت این نوع سون سگمنت در این است که ۸ بیت دیتا ( a ،b ، c و…) برای همه سگمنت ها با هم یکی شده است ( مشترک هستند ). در شکل زیر یک سون سگمنت مالتی پلکس چهار تایی را مشاهده می کنید.
پایه های سون سگمنت مالتی پلکس شده ۴ تایی را در شکل زیر مشاهده می کنید. در صورت اتصال پایه های Com سون سگمنت مربوطه روشن می شود .
بنابراین مدار مورد نظر در این طراحی به صورت زیر است. وجود ترانزیستور npn در این طراحی به علت جریان بالای روشن شدن سون سگمنت است. زیرا در هر سون سگمنت روشن جریانی در حدود ۱۰۰ میلی آمپر به زمین وارد می شود در حالی که هر پایه میکرو توانایی عبور 10 میلی آمپر جریان را دارد. همچنین در این طراحی از آی سی 7448 برای ساخت کدهای سون سگمنت استفاده شده است. با استفاده از این آی سی علاوه بر این که نیازی به تعریف آرایه کدهای سون سگمنت نداریم ، به علت تغذیه 5 ولت آی سی ، سون سگمنت ها نور مطلوبی خواهند داشت.
مثال عملی شماره 5 : با استفاده از سون سگمنت مالتی پلکس شده چهارتایی و میکروکنترلر LPC2138 برنامه یک شمارنده از 0000 تا 9999 را بنویسید. ( بدون 7448 )
مثال عملی شماره 6 : به مثال قبلی یک آی سی 7448 و یک کلید اضافه نمایید سپس برنامه را طوری تغییر دهید که با فشردن کلید شمارش آغاز شود و با فشردن مجدد کلید شمارش متوقف شود.
لینک دانلود سورس مثال عملی شماره 5 و 6
راه اندازی LCD کاراکتری
ال سی دی های کارکتری اغلب دارای ۱۴ پایه هستند که ۸ پایه برای انتقال اطلاعات ۳ پایه برای کنترل نرم افزاری یک پایه برای کنترل سخت افزاری و دو پایه تغذیه می باشد در جدول زیر اطلاعات پایه ها را مشاهده می کنید:
پایه | نام | عملکرد |
1 | VSS | زمین |
2 | VCC | 5V+ |
3 | VEE | کنترل درخشندگی (می توانید با یک مقاومت 1 کیلو آن را زمین کنید) |
4 | RS | اگر این پایه 0 باشد اطلاعات روی DB0-DB7 به عنوان فرمان و اگر 1 باشد به عنوان کاراکتر پذیرفته می شود |
5 | R/W | اگر این پایه 0 باشد LCD برای نوشتن آماده می شود و اگر 1 باشد برای خواندن آماده می شود |
6 | E | فعال سازی LCD که با یک لبه پایین رونده می باشد |
7 | DB0 | خطوط دیتا |
8 | DB1 | |
9 | DB2 | |
10 | DB3 | |
11 | DB4 | |
12 | DB5 | |
13 | DB6 | |
14 | DB7 | |
15 | A | 5V+ از پایه 15 و 16 برای روشن کردن LED پس زمینه استفاده می شود |
16 | K | زمین |
LCD ها را میتوان با ۸ خط دیتا یا ۴ خط دیتا راه اندازی کرد اما معمولا آن را با ۴ خط دیتا راه اندازی می کنند که در این نوع راه اندازی تنها پایه های RS ، R/W ، E و D4 تا D7 به پورت دلخواه از میکرو متصل می شود. تنها تفاوت راه اندازی با ۴ خط دیتا در این است که داده های ۸ بیتی LCD به جای یکبار ، در دو مرحله ۴ بیتی ارسال می شوند. مزیت راه اندازی با 4 خط دیتا در این است که اتصال LCD به میکروکنترلر تنها 7 پایه از میکرو را اشغال می کند. این 7 خط دیتا را میتوان به هر پایه دلخواهی از میکرو متصل نمود اما بهتر است در این اتصال از پورت های کنار هم استفاده نمود. در اینجا ما LCD را به صورت شکل زیر متصل کردیم.
نحوه استفاده از LCD کاراکتری :
تعریف این توابع کاملا شبیه به توابع در AVR هستند با این تفاوت که کامپایلر KEIL هیچگونه تنظیمات و هدر فایلی در این خصوص ندارد و هدر فایلی که به پروژه اضافه می کنیم توسط خودمان نوشته شده است.
برای اضافه کردن قابلیت استفاده از LCD کاراکتری به برنامه کافی است فایل lcd.h و نیز فایل lcd.c را بعد از دانلود در کنار فایل اصلی پروژه ( main.c ) در پوشه اصلی پروژه کپی کرد و در ابتدای برنامه به صورت زیر این هدر فایل را به برنامه اضافه کرد.
1 |
include "lcd.h" |
اگر به درون دو فایل موجود یعنی lcd.h و lcd.c نگاهی بیاندازیم ، مشاهده می کنیم که در lcd.h تعاریف پایه های اتصال LCD به میکرو و نیز اعلان توابع وجود دارد. در درون فایل lcd.c نیز بدنه همان توابع اعلان شده در lcd.h وجود دارد.
تذکر : در صورتی که بخواهید LCD را به صورتی به جز شکل نشان داده شده در بالا متصل کنید ، یعنی بخواهید از پایه های دیگر میکرو برای راه اندازی LCD استفاده نمایید ، باید عدد پایه های تعریف شده در هدر فایل lcd.h را از پایه های موجود به پایه های دلخواه تغییر دهید.
توابع کار با LCD کاراکتری در ARM
1- تابع راه اندازی LCD کاراکتری ( بدون ورودی ) :
1 |
lcd_init(); |
این تابع LCD را راه اندازی می کند و همیشه قبل از حلقه while نوشته می شود.
2- تابع پاک کردن تمام LCD ( بدون ورودی ) :
1 |
lcd_clear(); |
این تابع lcd را پاک کرده و مکان نما را در سطر و ستون صفر قرار می دهد.
3- تابع رفتن به ستون x و سطر y ام :
1 |
lcd_gotoxy(x , y ); |
تابع فوق مکان نمای ال سی دی را در سطر x و ستون y قرار می دهد و باید به جای x و y عدد سطر و ستون مورد نظر جا گذاری شود.
4- تابع چاپ یک کاراکتر:
1 |
lcd_putchar(‘ کاراکتر ‘); |
5- تابع چاپ یک رشته یا یک متغیر رشته ای :
1 2 |
lcd_print(“ رشته “); lcd_print(نام متغیر رشته ای ); |
مثال عملی شماره 7 : یک LCD کاراکتری 2 در 16 را به صورت 4 بیتی به میکروکنترلر LPC2138 متصل کرده و برنامه ای بنویسید که یک عدد را روی LCD شمارش کند. با استفاده از راه اندازی واحد PLL سرعت شمارش را افزایش دهید و تغییرات را مشاهده نمایید.
مثال عملی شماره 8 : برنامه مثال قبل را برای وقتی که LCD به صورت 8 بیتی به میکروکنترلر متصل می شود بازنویسی کنید.
لینک دانلود سورس مثال عملی شماره 7 و 8
راه اندازی صفحه کلید در LPC2138
راه اندازی انواع صفحه کلیدها با استفاده از میکروکنترلرهای ARM7 کاملا شبیه به AVR می باشد با تفاوت اینکه مقاومت پول آپ داخلی وجود ندارد و نیز در برنامه برای مقدار دهی رجیسترهای واحد GPIO ، دسترسی با عملگر Shift و AND میسر است. برای مثال می خواهیم صفحه کلید 4 در 4 را به میکرو متصل کنیم. 4 سطر و 4 ستون را به هر پایه دلخواه ( ترجیحا کنار هم ) متصل می کنیم و سپس با استفاده از مقاومت های 3.3K ، ستون های صفحه کلید را پول آپ می کنیم. همانطور که در شکل زیر مشاهده می کنید ، در اینجا ما صفحه کلید را به پایه های P1.20 تا P1.27 متصل کردیم.
تابع خواندن از صفحه کلید :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
char keyboard (void) { char code[16]={'7','8','9','/','4','5','6','*','1','2','3','-','c','0','=','+'}; int i=0,j=0; for(i=0;i<4;i++) { IO1CLR|=(1<<(20+i)); delay_ms(2); if((IO1PIN & 0x00f00000)!=0x00f00000) { for(j=0;j<4;j++) if((IO1PIN & (1<<(j+24)))!=(1<<(j+24))) return code[i*4+j]; delay_ms(2); } IO1SET|=(1<<(20+i)); } return 20; } |
توضیح : یک آرایه به نام code برای اصلاح اعداد صفحه کلید در نظر گرفته شده است. در صورتی که این آرایه نباشد با زدن مثلا کلید ۷ عدد ۰ نمایش داده می شود ! بنابراین به جای اینکه i*4+j به خروجی فرستاده شود ، [code[i*j+j به خروجی فرستاده می شود تا بدین وسیله اعداد اصلاح شود. حلقه for اول وظیفه 0 کردن یکی یکی سطر ها را برعهده دارد. اگر کلیدی توسط کاربر فشار داده شده باشد ، رجیستر در بیت های بین 24 تا 27 از رجیستر IO1PIN تغییر ایجاد می شود. حلقه if اولی تشخیص می دهد که آیا یکی از ستون ها 0 است یا خیر. حلقه for دومی تشخیص می دهد که کدام ستون زده شده است. در آن ستونی که کاربر کلید را فشار داده است ، شرط if دوم برابر شده و داخل آن می شود.در درون if دوم هم ، [code[i*j+j به خروجی فرستاده می شود.تابع keyboard در صورتی که هیچ کلیدی زده نشده باشد مقدار ۲۰ را بر می گرداند.
مثال عملی شماره 9 : با اتصال یک صفحه کلید 4 در 4 و یک LCD کاراکتری 2 در 16 به میکروکنترلر LPC2138 برنامه ای بنویسید که با زدن هر کلید کاراکتر مربوط به آن را روی LCD نمایش دهد.
لینک دانلود سورس مثال عملی شماره 9
راه اندازی LCD گرافیکی
نوع دیگری از LCD ها وجود دارند که به آنها Graphic LCD یا GLCD گفته می شود. این LCD ها نسبت به LCD های کاراکتری دارای ابعاد بزرگتری هستند و برخلاف LCD های کاراکتری که تنها کاراکترها را نشان می دهند ، GLCD ها با روشن و خاموش کردن نقاط کوچک ، هر نوع تصویر سیاه و سفیدی را میتوانند نمایش دهند. از مزایای دیگر این LCD ها میتوان به تفکیک پذیری بالاتر و امکان ساخت منو و واسط کاربری را اشاره کرد. GLCD ها سایز و انواع متفاوتی دارند که شکل زیر GLCD با کنترلر KS0108 در ابعاد 64*128 را مشاهده می کنید.
در نرم افزار پروتئوس این GLCD را با تایپ کردن LGM126 میتوان به پروژه اضافه نمود.
در شکل زیر بلوک دیاگرام LCD گرافیکی که در این آموزش از آن استفاده شده است را مشاهده می کنید. این GLCD که دارای 128*64 پیکسل سیاه و سفید است ، دارای دو عدد کنترلر KS0108B می باشد.
پایه های این GLCD و عملکرد هر پایه به صورت زیر می باشد. ( برخی از پایه ها در پروتئوس وجود ندارد )
این GLCD دو کنترلر جداگانه دارد ، به طوری که نیمه سمت چپ از LCD با یک کنترلر ( در زمانی که CS1=1 و CS2=0 ) و نیمه دیگر آن با کنترلر دیگر ( در زمانی که CS2=1 و CS1=0 ) راه اندازی می شود.
سه رجیستر X ، Y و Z برای راحتی در این GLCD تعبیه شده است که به صورت زیر تعریف می شود :
رجیستر X : هر 8 سطر یک صفحه ( page ) نامیده می شود. بنابراین تعداد 8 صفحه در هر چیپ وجود دارد. رجیستر X مشخص می کند که کدام صفحه فعال و آماده به کار می باشد. آدرس اولین صفحه 0XB8 و آدرس آخرین صفحه 0XBF می باشد.
رجیستر Y : این رجیستر مشخص می کند که کدام ستون از 64 ستون هر چیپ فعال است. آدرس اولین ستون 0X40 و آخرین ستون 0X7F می باشد.
رجیستر Z : این رجیستر مشخص می کند که هر صفحه از کدام ستون شروع شود. در نتیجه با تغییر این رجیستر میتوان به صورت افقی تصویر را حرکت داد. آدرس این رجیستر از 0XC0 تا 0XFF متغیر می باشد.
برای راه اندازی و استفاده از رجیسترها دستورات زیر مورد استفاده قرار می گیرند.
راه اندازی LCD گرافیکی با LPC2138
برای راه اندازی LCD گرافیکی ابتدا مدار را به صورت شکل زیر به میکرو متصل می کنیم.
برای اضافه کردن قابلیت استفاده از LCD گرافیکی به برنامه کافی است فایل glcd.h و نیز فایل glcd.c را در کنار فایل اصلی پروژه ( main.c ) در پوشه اصلی پروژه کپی کرد و در ابتدای برنامه به صورت زیر این هدر فایل را به برنامه اضافه کرد.
1 |
#include "glcd.h" |
اگر به درون دو فایل موجود یعنی glcd.h و glcd.c نگاهی بیاندازیم ، مشاهده می کنیم که در glcd.h تعاریف پایه های اتصال LCD به میکرو و نیز اعلان توابع وجود دارد. در درون فایل glcd.c نیز بدنه همان توابع اعلان شده در glcd.h وجود دارد.
تذکر : در صورتی که بخواهید LCD را به صورتی به جز شکل نشان داده شده در بالا متصل کنید ، یعنی بخواهید از پایه های دیگر میکرو برای راه اندازی LCD استفاده نمایید ، باید عدد پایه های تعریف شده در هدر فایل glcd.h را از پایه های موجود به پایه های دلخواه تغییر دهید.
توابع کار با GLCD در ARM
1- تابع راه اندازی LCD کاراکتری ( بدون ورودی – بدون خروجی ) :
1 |
glcd_init(); |
این تابع LCD را راه اندازی می کند و همیشه قبل از حلقه while نوشته می شود.
2- تابع پاک کردن تمام LCD ( بدون ورودی – بدون خروجی ) :
1 |
glcd_clear(); |
این تابع lcd را پاک کرده و مکان نما را در سطر و ستون صفر قرار می دهد.
3- تابع رفتن به صفحه x ( یک ورودی – بدون خروجی ) :
1 |
glcd_gotox (x); |
تابع فوق مکان نمایش ال سی دی را به صفحه ( Page ) که به جای x قرار می گیرد ، جابجا می کند.
4- تابع رفتن به ستون y ( یک ورودی – بدون خروجی ) :
1 |
glcd_gotoy (y); |
تابع فوق مکان نمایش ال سی دی را به ستون ( Column ) که به جای y قرار می گیرد ، جابجا می کند.
5- تابع رفتن به خط z ( یک ورودی – بدون خروجی ) :
1 |
glcd_gotoz (z); |
تابع فوق مکان نمایش ال سی دی را به خط ( Line ) که به جای z قرار می گیرد ، جابجا می کند.
6- تابع چاپ یک تصویر روی LCD گرافیکی ( یک ورودی – بدون خروجی ) :
1 |
glcd_display(*image); |
این تابع میتواند تصویری سیاه سفید ( monochrome ) به ابعاد 128*64 را روی LCD گرافیکی نمایش دهد به طوری که ابتدا تصویر در نرم افزارهای دیگر نظیر Paint ویندوز ساخته شده و با فرمت bitmap ذخیره می گردد. سپس این تصویر توسط نرم افزارهای دیگر نظیر GLCD editor به کدهای هگز تبدیل می شود و در یک آرایه ای از نوع char قرار می گیرد. سپس در ورودی تابع glcd_display می بایست به این آرایه اشاره کرد تا روی LCD به نمایش درآید. مراحل ساخت و تبدیل تصویر را در شکل های زیر مشاهده می کنید.
مثال عملی شماره 10 : یک LCD گرافیکی 64 در 128 را به میکروکنترلر LPC2138 متصل کرده و برنامه ای بنویسید که یک تصویر دلخواه را روی آن نمایش دهد.
لینک دانلود سورس مثال عملی شماره 10
برای ادامه آموزش ARM روی تصویر زیر کلیک کنید.
در صورتی که این مطلب مورد پسندتان بود لایک و اشتراک گذاری فراموش نشود
دیدگاه (14)
سلام!
آموزش هاتون خیلی عالین!
لطفا راه اندازی usb رو هم بزارید!
سلام ممنونم دوست عزیز حتما در آینده قرار خواهم داد
سلام و ممنون لطفا در صورت امکان برای توابع نوشته شده یک برنامه نمونه هم قرار دهید با تشکر.
سلام دوست و همراه عزیز حتما قرار خواهم داد اما نه به صورت رایگان
ضمن عرض سلام و تشکر در تابع نوشته شده برای pwm رجیستر PWMTCR دو بار تکرار شده و PWMMCR جا افتاده و یه سوال هم از خدمتتون داشتم که در تابع TIMER رجیستر PCLK در کجا باید تعریف شود؟
ممنون
سلام دوست عزیز ممنونم از توجه و حسن نظرتون
میتوان دو خط مربوط به PWMTCR را با هم ترکیب کرد و در یک مرحله نوشت تفاوتی ندارد. رجیستر PWMMCR هم چون در حالت PWM رجیستر PWMTC نباید ریست شود برابر 0 می باشد. در صورت فعالسازی وقفه در هنگام تطبیق باید این رجیستر را مقدار دهی کرد.
بله حق با شماست ممنونم
سلام
آموزش در مورد usb lpc2148 هم دارید?
سلام دوست عزیز این میکروکنترلر LPC2138 هست که واحد USB نداره در آینده حتما در مورد واحد USB هم مطلب قرار خواهم داد
سلام .در این صورت چه مقداری به flag داده میشه
;=Flag
سلام.من میخواستم یه lcd کاراکتری رو راه اندازی کنم. فایل های lcd.c و lcd.h که توی توضیحاتتون گفتید رو از کجا باید download کنم؟
سلام دوست عزیز لطفا برای تهیه این دو فایل و زحماتی که کشیده شده به فروشگاه مراجعه نمایید و بسته آموزشی ARM7 رو با هزینه بسیار مناسب تهیه فرمایید
سلام وقت بخیر
در در توضیح کد صفحه کلید نوشته شده تغیرات در IO0PIN ایجاد میشود در صورتی که باید IO1PIN باشه
خیلی مهم نیست ولی بهتره که اصلاح بشه
سلام دوست عزیز ممنون از تیزبینی شما اصلاح شد