در بخش قبلی یک LCD Nokia را به کمک واحد SPI را راهاندازی کردیم و یک تصویر را روی آن نمایش دادیم. در این بخش قصد داریم یک فونت برای نوشتن در LCD تعریف کنیم و پیامهای موردنظرمان را روی LCD نمایش دهیم.
قبل از هر چیز، نیاز به یک فونت داریم که ما برای نمونه یک فونت 5×8 در نظر گرفتیم که هدر فایل آن با جستوجوی عبارت font 5×8.h قابلدسترسی است. چگونگی استفاده از این هدر فایل در ادامه کار شرح داده میشود.
ابتدا مانند قبل روند ساخت پروژه را طی میکنیم. تنظیم کلاک، دیباگ، واحد SPI و همچنین پایههای خروجی را مانند بخش قبل تنظیم میکنیم و کد پروژه را ایجاد میکنیم تا وارد محیط Keil شویم.
نوشتن کد پروژه
در ابتدا باید هدر فایلی که در ابتدا گفتیم را به پروژه اضافه کنیم، بدین منظور، هدرفایل را در مسیری که پروژه را ایجاد کردهایم و در پوشه Core و سپس Inc کپی میکنیم. اکنون در محیط Keil، از نوارابزار یا از منوی Project و سپس Manage، Project Items را انتخاب میکنیم. از پنجره باز شده از طریق کلید Add files… به مسیر پروژه میرویم و هدرفایل کپی شده را انتخاب میکنیم تا به پروژه اضافه شود و در آخر OK را میزنیم. حالا باید در ابتدای فایل main.c نیز هدرفایل را اضافه کنیم. بدین منظور از دستور زیر استفاده میکنیم:
1 | #include "font.h" |
اکنون نیاز به تعریف تأخیرهای موردنیاز داریم. توجه کنید برای اینکه دستورات تغییر موقعیت نوشتن و فرستادن کاراکترها بهدرستی توسط LCD اجرا شوند، باید از تأخیر استفاده کنیم. سه تأخیر بهصورت زیر تعریف میکنیم:
1 2 3 | #define X_NOP() {__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();} #define Y_NOP() X_NOP();X_NOP();X_NOP();X_NOP();X_NOP();X_NOP();X_NOP();X_NOP();X_NOP();X_NOP(); #define Z_NOP() Y_NOP();Y_NOP();Y_NOP();Y_NOP();Y_NOP();Y_NOP();Y_NOP();Y_NOP();Y_NOP();Y_NOP(); |
مانند بخش قبلی، تابع send_SPI که از قبل نوشتیم را در این پروژه نیز تعریف میکنیم:
1 2 3 4 5 6 7 | void send_SPI(uint8_t data) { while(!LL_SPI_IsActiveFlag_TXE(SPI1)); LL_SPI_TransmitData8(SPI1, data); while(!LL_SPI_IsActiveFlag_RXNE(SPI1)) {} } |
به وسیله این تابع، دو تابع برای فرستادن اطلاعات دستوری و نمایشی مینویسیم؛
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /// send command to the LCD void LCD_SendCmd(uint8_t cmd) { LL_GPIO_ResetOutputPin(LCD_GPIO, CE_pin); //put CE to Low state LL_GPIO_ResetOutputPin(LCD_GPIO, DC_pin); //LCD Command Mode send_SPI(cmd); //X address Z_NOP();Z_NOP();Z_NOP();Z_NOP();Z_NOP();Z_NOP();Z_NOP();Z_NOP(); LL_GPIO_SetOutputPin(LCD_GPIO, DC_pin); //LCD exit from Command Mode LL_GPIO_SetOutputPin(LCD_GPIO, CE_pin); //put CE to High state } /// send data to the LCD void LCD_SendData(uint8_t data) { LL_GPIO_ResetOutputPin(LCD_GPIO, CE_pin); //put CE to Low state send_SPI(data); X_NOP();X_NOP();X_NOP();X_NOP();Z_NOP(); LL_GPIO_SetOutputPin(LCD_GPIO, CE_pin); //put CE to High state } |
توجه کنید که در این دو تابع، پایه فعالسازی چیپ را در شروع و پایان دستورات، فعال و غیرفعال کردهایم. همچنین بعد از فرستادن دستور و دادههای نمایشی تأخیر قرار دادهایم. در پروژه ما تأخیر مناسب برای فرستادن دستور حدود 90 میکروثانیه و برای فرستادن دادهها حدود 10 میکروثانیه بود که بهوسیله تأخیرهای تعریفشده در ابتدای پروژه، این دو تأخیر موردنیاز را ایجاد کردهایم (کلاک این پروژه 72 مگاهرتز تنظیم شده است).
برای استفاده از LCD مانند پروژه قبل نیاز به یک فعالسازی اولیه داریم که این بار میخواهیم بهوسیله یک تابع این عمل را انجام دهیم؛
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 | /// LCD initialization void LCD_init(void) { LL_GPIO_SetOutputPin(LCD_GPIO, CE_pin); //LCD Enable LL_GPIO_SetOutputPin(LCD_GPIO, DC_pin); //LCD Data Mode ////configure LCD : LL_GPIO_ResetOutputPin(LCD_GPIO, Reset_pin); LL_mDelay(10); LL_GPIO_SetOutputPin(LCD_GPIO, Reset_pin); LL_mDelay(10); /// LCD_SendCmd(0x21); //Function set(extended instruction set) LCD_SendCmd(0x90); //VOP LCD_SendCmd(0x07); //temperature coefficient LCD_SendCmd(0x13); //Voltage bias /// LCD_SendCmd(0x20); //Function set(basic instruction set) LCD_SendCmd(0x0C); //Display Configuration LCD_SendCmd(0x40); //Y address LCD_SendCmd(0x80); //X address } |
برای کنترل نوشتن، دو تابع تغییر موقعیت و پاک کردن صفحهنمایش را تعریف میکنیم:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | /// x&y position void LCD_goto_xy(int x, int y) { uint8_t xh = 0x80 | (x & 0x7F); uint8_t yh = 0x40 | (y & 0x07); LCD_SendCmd(xh); LCD_SendCmd(yh); } /// clear screen void LCD_cls(void) { LCD_goto_xy(0,0); for(int i=0;i<=(48*84/8);i++) { LCD_SendData(0x00); } } |
اکنون باید بهوسیله تعریف یک تابع، از کاراکترهایی که در هدرفایل تعریف شده، برای نوشتن استفاده کنیم. بهعبارتدیگر، میخواهیم تابعی بنویسیم که یک کاراکتر را دریافت کند، این کاراکتر را در بافر فونت تعریف شده پیدا کند و آن را روی LCD نمایش دهد. تابع مذکور را به صورت زیر مینویسیم:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /// send single character to the LCD void LCD_send_char (char ch) { ch = ch - ' '; int index = ch * 5; for(int i=0;i<5;i++) { LCD_SendData(font5x8[index++]); } LCD_SendData(0x00); } |
اکنون با استفاده از تابع LCD_send_char میتوانیم تابع دیگری بنویسیم که بتواند یک رشته را روی LCD نمایش دهد:
1 2 3 4 5 6 7 8 | /// send string to the LCD void LCD_puts (char *ch) { while(*ch) { LCD_send_char(*ch++); } } |
حالا همه کدهای مورد نیاز را نوشتهایم. میتوانیم به وسیله کدهای نوشته شده اطلاعات دلخواهمان را روی LCD بنویسیم.
مانند قبل، واحد SPI را فعال میکنیم (قبل از حلقه while(1)) :
1 | LL_SPI_Enable(SPI1); |
دستورات زیر را در ادامه مینویسیم:
1 2 3 4 5 6 | LL_mDelay(10); LCD_init(); LCD_cls(); LCD_goto_xy(25,3); LCD_puts("Salam"); |
اگر تمامی مراحل به درستی انجام شده باشند، در موقعیت تعیین شده روی LCD Nokia، اطلاعات نمایش داده میشود.
نکته: باید توجه کرد که آرایه نوشته شده برای فونت، با طرز نمایش اطلاعات روی LCD، از نظر افقی یا عمودی بودن انطباق داشته باشد.
ریدایرکت کردن Printf برای نمایش اطلاعات روی LDC Nokia
میتوانیم مانند آموزش قسمت ریدایرکت کردن Printf توسط واحد USART، در این پروژه نیز تابع Printf را برای نمایش اطلاعات روی LCD Nokia ریدایرکت کنیم. بدین منظور ابتدا باید تنظیمات Run-Time Environment که در آموزش مذکور گفته شد را به همان شکل انجام دهیم. سپس تابع stdout_putchar را به صورت زیر تعریف میکنیم:
1 2 3 4 5 | int stdout_putchar (int ch) { LCD_send_char(ch); return (ch); } |
اکنون میتوانیم از دستور printf برای نمایش اطلاعات روی LCD Nokia استفاده کنیم.
در دو بخش گذشته در مورد نحوه راهاندازی LCD Nokia و نمایش عکس و اطلاعات نوشتاری روی آن صحبت کردیم. در بخش بعدی با چگونگی نمایش یک انیمیشن روی LCD آشنا خواهیم شد.
سلام ببخشید چطور کد رو از گیتهاب دانلود کنیم هرکار کردم نشد قفلش کردید؟
نه چیزی رو قفل نکردیم !!!
روی دکمه دانلود بالا سمت راست کلیک کنید باید دانلود بشه
سلام و خسته نباشد
این یه تیکه کد چه کاری انجام میده متوجه نشدم
CH = CH – ‘ ‘ ;
چون خودم جوابش رو بدست اوردم میفرستم شاید برای بقیه هم که تازه کار هستن همچین سوالی براشون پیش بیاد.
برای اینکه تو کتابخانه فونت ،اولین خانه space هست و هر کارکتر را با space کم کنیم شماره همون کارکتر در ارایه فونت بدست میاد.مطابق با جدول اسکی که نگاهی بهش بندازن بیشتر متوجه میشن.
سلام خدمت شما با تشکر از سایت خوبتون
من نتونستم فایل font 5×8.h را پیدا کنم امکانش هست لینک دانلود این فایل رو به اشترک بزارید
ممنون
سلام دوست عزیز
فونت های متنوعی رو میتونید از لینک زیر پیدا کنید
LCD Font
سلام خدمت شما با تشکر از سایت خوبتون دنبال یادگیری avr هستم کمکم کنید ..باتشکر
سلام دوست عزیز. برای آموزش avr منابع زیادی وجود داره. شما میتونید از آموزش جامع avr که روی سایت خودمون هست هم استفاده کنید.
لینک :
https://sisoog.com/avr-microcontroller-training/