معرفی کتابخانه LVGL برای نمایش‌گرهای TFT LCD

دسته‌بندی: آموزش الکترونیک
بدون دیدگاه
  • عنوان: معرفی کتابخانه LVGL برای نمایش‌گرهای TFT LCD

    کتابخانه‌ای همه‌کاره برای راه‌اندازی رابطِ کاربری گرافیکی(GUI)

  • نسخه: ویراست اول

  •  ذکر منبع، صرفا برای دسترسی به نسخه‌ی به‌روز الزامی است.

رابط کاربری(User Interface)

همه‌ی سیستم‌های کامپیوتری بخشی برای ارتباط با کاربر دارند. این بخش می‌تواند به سادگی قرار دادن تعدادی کلید و چراغ، تا اَشکال کامل‌تری چون نمایش‌گر رنگی و ورودی‌های اشاره‌گر مثل USB Mouse، ورودی و خروجی مورد نیاز دستگاه را تامین نماید. به‌طورکلی به این بخش از سیستم‌های کامپیوتری چه در سیستم‌های گسترده و چه در سیستم‌های نهفته (Embedded)، “رابط کاربری” یا “User Interface” می‌گویند.

رابط‌ کاربری از لحاظ ساختار داخلی شامل موارد زیر است:

  • بخش نمایش‌گر یا خروجی(مثل چراغ، buzzer، TFT LCD و …)

  • بخش ورودی(مثل کلید، Touchpad، Mouse و …)

از طرف دیگر انواع آن، به دو دسته‌ی کلی زیر تقسیم می‌شوند:

  • رابط کاربری غیرگرافیکی(Non Graphical User Interface[NGUI])

  • رابط کاربری گرافیکی(Graphical User Interface[GUI])

پرواضح است که در نوع GUI، ازآنجاکه نیاز به نمایش اطلاعات موردنیاز از طریق نمایش‌گر گرافیکی(ماژولی که تصویر دلخواهی را به نمایش می‌گذارد) و همچنین درنظرگرفتن اشاره‌گری مناسب به عنوان ورودی است، پیچیدگی بیشتر است. البته پیچیدگی این نوع رابط‌های کاربری مزایایی را برای محصول نهایی در بر دارند که به برخی از آن‌ها در زیر اشاره شده‌است:

  • انجام سریع تنظیمات پیکربندی از طریق خود دستگاه

  • نمایش اطلاعات آنلاین و بازنگری اطلاعات گذشته از طریق خود دستگاه

  • اضافه کردن قابلیت کاربرپسندی به دستگاه

  • سهم بازار بیشتر برای دستگاه

توجه: در این نوشته، نمایش‌گر گرافیکی به ماژولی اطلاق می‌شود که هر تصویر دلخواهی را به نمایش‌می‌گذارد. لذا شامل مواردی چون نمایش‌گر کاراکتری نمی‌شوند.

با پیشرفت روزافزون در فرآیند تولید ماژول‌های نمایش‌گر و تنوع‌بخشی به آن‌ها، هزینه‌ی تحمیلی به پروژه‌ها برای درنظرگرفتن آن‌ها در بخش رابط کاربری کاهش یافته‌است. از این لحاظ طراحی رابط کاربری به شکل گرافیکی اگر نگوییم به یک الزام در ساخت دستگاه‌های کامپیوتری، اقلا به یک مزیت قابل دسترس و معقول در اکثر پروژه‌ها بدل شده‌‌است.

بدون توجه به تکنولوژی ساخت ماژول‌های نمایش‌گر و نوع ورودی آن، می‌توان دسته‌بندی کلی زیر را برای رابط‌های کاربری گرافیکی درنظر گرفت:

  1. رابط کاربری گرافیکی با نمایش‌گر گرافیکی تک‌رنگ(Monochrome Display)

  2. رابط کاربری گرافیکی با نمایش‌گر گرافیکی رنگی(Color Display)

که پیچیدگی استفاده از آن‌ها به همان ترتیب بالا است.

یکی از مشکلات اساسی به‌کارگیری ماژول‌های نمایش‌گر در پروژه‌ها، پیچیدگی پیاده‌سازی و زمان لازم برای تطبیق پروژه تا ورود به بازار است. اصطلاحا زمان طراحی و ساخت تا ورود محصول به بازار زیاد شده و توجیه کاربرد آن‌ها را زیر سوال می‌برد. ازطرف‌دیگر، گاها استفاده از ادوات سخت‌افزاری و نرم‌افزاری یک رابط کاربری گرافیکی در یک پروژه، به راحتی برای پروژه‌های دیگر و نسخه‌های دیگر قابل استفاده نیست و عملا برای هر پروژه باید از نو همه چیز طراحی و برنامه‌نویسی شود.

برای رفع این مشکلات اساسی، تلاش‌های فراوانی شده‌است تا امکانات سخت‌افزاری(شامل به‌کارگیری واسط‌های سخت‌افزاری استاندارد در انواع و برندهای مختلف) و امکانات نرم‌افزاری سطح بالا(شامل کتابخانه‌های همه‌کاره‌ای که در زبان‌های برنامه‌نویسی مختلف قابل استفاده باشند) ایجاد شود. که البته که این تلاش‌ها در حال پیش‌رفت است و هر روز امکانات جدیدی برای ساده‌سازی استفاده از رابط‌های کاربر گرافیکی ارائه می‌شود.

 

در این نوشته قصد داریم تا به معرفی راه‌کار مناسب استفاده از ماژول نمایش‌گر گرافیکی  بپردازیم. نگاه این نوشته به پروژه‌هایی است که بر بستر سیستم‌های نهفته (Embedded systems) اجرا می‌شوند و از پردازنده‌هایی که واحد گرافیکی مستقل دارند استفاده نشده‌است. اجرا می‌شوند. از سوی دیگر ملاحظات سخت‌افزاری را در این متن بررسی نمی‌کنیم و تنها به امکانات نرم‌افزاری(کتابخانه‌هایی) برای برطرف‌کردن مشکل پیچیدگی راه‌اندازی بخش نمایش‌گر گرافیکی واسط‌های کاربری اشاره‌می‌کنیم و در نهایت دو مورد مناسب را برای نمایش‌گر‌های تک‌رنگ و رنگی، معرفی‌می‌کنیم.

 

اصول ارتباط سخت‌افزاری نمایش‌گر گرافیکی

بلوک دیاگرام ارتباط سخت‌افزاری میان یک نمایش‌گر و پردازنده‌ی اصلی  در شکل زیر مشخص شده‌است.

همان‌طور که در شکل مشخص شده‌است، شامل سه بخش اصلی است که در ادامه به توضیح مختصر هر یک می‌پردازیم.

  1. نمایش‌گر: شامل دو بخش اصلی چیپ درایور(Display Driver Chip) و مدار تغذیه است. البته بخشی که شامل سلول‌های نورانی است و معمولا از طریق تحریک ترانزیستورهای FET تصویر را به نمایش درمی‌آورند نشان داده‌نشده‌است. این سلول‌ها به تعداد Resolution افقی و عمودی در دو بعد صفحه قرارگرفته‌اند. وظیفه‌ی روشن، خاموش کردن این ترانزیستور‌ها با چیپ داریور است که معمولا به شکل Chip on Glass Package و در پشت صفحه‌ی نمایش‌گر تعبیه می‌شوند. مدارات تغذیه هم برای ایجاد سطوح مثبت و منفی مورد نیاز Backlight و سلول‌های نورانی طراحی می‌شوند. ارتباط ماژول نمایش‌گر از طریق واسط سخت‌افزاری که مثلا در ماژول‌های رنگی واسط موازی RGB(تعبیه‌شده در چیپ درایور) است، برقرار می‌گردد.

  2. بورد کنترلر: این بخش شامل چیپ کنترلر(Display Controller Chip) است که وظیفه‌ی آن شامل موارد زیر است:

    • داشتن بافر(حافظه‌ی RAM) لازم که دیتای pixelهای نمایش‌گر را در خود دارد.

    • تبدیل واسط ارتباطی پردازنده به واسط چیپ درایور(مثلا واسط RGB)

    • تولید سیگنال‌های زمانی مورد نیاز برای Refresh کردن ماژول نمایش‌گر با فرکانس مناسب.

  • استفاده از چیپ کنترلر، همان‌طور که از وظایف آن مشخص است، بار محاسباتی زیادی را از روی دوش پردازنده‌ی اصلی برمی‌دارد و همچنین از اشغال حافظه‌ی سیستم جلوگیری می‌کند. البته در پردازنده‌هایی که دارای واسط RGB هستند، استفاده از چیپ کنترلی الزامی نیست و پردازنده می‌تواند مستقیما برای کنترل ماژول نمایش‌گر پیکربندی شود. ازسوی‌دیگر در راه‌اندازی نمایش‌گرهای بزرگ که به حافظه‌ی زیادی برای نگه‌داری اطلاعات Frame نمایشی نیاز دارد، معمولا از چیپ حافظه‌ی خارجی استفاده می‌شود تا فضای حافظه‌ی داخلی میکروکنترلر برای کاربردهای دیگر حفظ شود.

  1. بورد اصلی(میکروکنترلر): برای ارتباط میکروکنترلرها با ماژول‌های نمایش‌گر رنگی و تک‌رنگ، برخی واسط‌های سخت‌افزاری استاندارد سریال و موازی در زیر آورده شده‌است:

    • واسط سریال SPI

    • واسط سریال I2C

    • واسط موازی RGB

    • واسط موازی Intel8080

    • واسط موازی Motorola6800

  • در طراحی سیستم واسط کاربری، بسته به تجهیز میکروکنترلر و نمایش‌گر به هر یک از این واسط‌ها، می‌توان بهینه‌ترین را انتخاب نمود و در صورت لزوم بخش بورد کنترلر را حذف کرد. در حالت کلی استفاده از واسط‌های سریال مزیت اشغال پین‌های کمتر و عیب سرعت ارتباطی کمتر را با خود دارند. این مقایسه برای واسط‌های موازی برعکس است.

توجه: چیپ درایور(Display Driver) و چیپِ کنترلر(Display Controller) وظایف کاملا متفاوتی دارند. لذا باید به درستی به هر یک در جایگاه خود اشاره کرد.

تا اینجا کلیتی از اصول سخت‌افزاری ماژول نمایش‌گر گرافیکی ارائه شد. هر یک از بخش‌های مورد اشاره دارای جزییاتی است که برای آشنایی بهتر با آن‌ها می‌توان به Application Note های مختلف مراجعه کرد. برای نمونه از لینک زیر استفاده کنید.

اصول نرم‌افزاری نمایش‌گر گرافیکی

باز هم با یک بلوک دیاگرام کلی برای ساده‌کردن مطلب آغاز می‌کنیم. در راه‌اندازی هر ماژول نمایش‌گر گرافیکی، می‌توان کدها و کتابخانه‌های مورد استفاده را در لایه‌بندی و دسترسی‌هایی شبیه نمودار پایین دسته‌بندی کرد. اگر از کتابخانه‌ها و لایه‌بندی کدنویسی استفاده نشود(مثلا با نوشتن مستقیم کد برای رجیسترها) قابلیت تعمیم‌پذیری و همه‌کاره بودن برنامه‌ای که می‌نویسیم از بین می‌رود و به هدفی که در ابتدای این نوشته بیان شد نمی‌رسیم. ازسوی‌دیگر، قابلیت‌ها و امکانات گرافیکی که از روش پیشنهادی بدست ‌می‌آید، به هیچ عنوان قابل قیاس با روش کدنویسی مستقیم نیست. شاید در خواب بتوان با روش مستقیم به امکانات معادلی رسید.

برنامه‌ی کاربر(User Application)

 برنامه‌ای است که طراح با زبان سطح بالا مثل C بر اساس نیاز پروژه می‌نویسد. این بخش شامل مواردی است که طراح به آن‌ها دسترسی دارد و برای تنظیمات پیکربندی میکروکنترلر و انجام وظایفی که در پروژه مشخص شده‌است، الگوریتم مورد نظر را پیاده‌سازی می‌کند.

 

کتابخانه‌ی گرافیکی(Graphical Library)

در مقدمه‌ی این نوشته اشاره به پیچیدگی راه‌اندازی نمایش‌گرهای گرافیکی کردیم. در واقع تلاش‌هایی که برای ایجاد بستر نرم‌افزاری یک‌پارچه و همه‌کاره(Versatile) شده‌است تا زمان رسیدن محصول به بازار از بابت راه‌اندازی واحد نمایش‌گر کاهش یابد، معطوف به این بخش است. انگیزه‌ی اصلی این نوشته، ارائه بسته نرم‌افزاری مفیدی است که در این قسمت قرار می‌گیرد. بسته نرم‌افزاری که طراح به کمک توابع آن، اجرای دستورات نمایش گرافیکی را عملی می‌سازد. این واحد وظیفه‌ی ساختن Frameهای نمایشی بر اساس خواسته طراح و ارسال آن به واحدهای پایین‌تر برای نمایش در نمایش‌گر را دارد. به عنوان مثال در یک نمونه‌ی ساده از این کتابخانه‌ی گرافیکی باید امکاناتی را برای نمایش یک خط در صفحه‌ی نمایش‌گر، در اختیار طراح قرار دهد که بدون درگیری با مشخصات چیپ کنترلر و درایور و صرفا با دادن نقطه‌ی ابتدا و انتهای خط، به مقصود خود برسد. در نمونه‌ی کامل‌تر آن، برای مثلا نمایش یک دکمه‌ی کاربر پسند در نمایشگر باید با دستوری ساده طراح را به مقصد خود بدون درگیری با مسایل دیگر برساند. عملا در این نوشته به دنبال ارائه‌ی کتابخانه‌ی مناسبی هستیم که طراح با استفاده از آن بتواند در سحطی هر چه بالاتر دستورات نمایشی خود را اجرا کند.

 

درایورِ چیپ کنترلر(Controller Chip’s Driver)

اگر در طراحی سیستم چیپ کنترلری در نظر گرفته شده‌باشد، این بخش شامل کتابخانه‌ای خواهد بود که توابع لازم برای ارتباط با کنترلر را در اختیار کتابخانه گرافیکی و در صورت لزوم برنامه‌ی کاربر قرار دهد. به عنوان مثال درایورِ نرم‌افزاری چیپِ کنترلرِ SSD1963 توابع لازم برای پیکربندی و نوشتن و خواندن روی این چیپ را مهیا می‌کند. منابع زیادی برای دسترسی به درایور نرم‌افزاری چیپ‌های کنترلر وجود دارند. البته گاها در کتابخانه‌های گرافیکی مجهز و همه‌کاره، این درایورها هم پیدا می‌شوند.

 

درایورِ لایه‌ی سخت‌افزار(HAL Driver)

 شامل همه‌ی توابع لازم برای دسترسی به رجیسترها و ادوات جانبی(Peripheral) میکروکنترلر است(Hardware Abstraction Layer Driver). عموما توسط شرکت‌های سازنده‌ی میکروکنترلرها ارائه می‌شوند. به عنوان مثال طراح توابعی سطح بالا برای نوشتن و خواندن توسط FSMC در میکروکنترلرهای شرکت ST در اختیار دارد که کتابخانه‌های لایه‌ی سخت‌افزار را فراخوانی می‌کند.

 

کتابخانه گرافیکی مناسب برای نمایش‌گر تک‌رنگ(Monochrome Display)

نمایش‌گر گرافیکی تک‌رنگ همان‌طور که از اسمش پیداست به ازای هر Pixel فقط یک رنگ نمایش می‌دهد. در عمل آن Pixel را خاموش یا روشن می‌کند و به این روش تصویر مورد نظر را در صفحه‌ی نمایش‌گر ایجادمی‌کند. اصطلاح تخصصی این‌چنین تصویری Black & White یا سیاه و سفید است. در واقع این نمایش‌گرها تصویرهای سیاه و سفید را فقط نمایش می‌دهند و حتی قابلیت نمایش تصویر Grayscale را هم ندارند. البته با به کار بستن تکنیک‌هایی می‌توان تصوری را از به تصویرکشیدن تصویری با لایه‌های خاکستری، ایجادکرد.

معمولا چیپ درایور و چیپ کنترلر بر روی ماژول نمایش‌گر تعبیه شده‌اند و لذا نیازی به استفاده از کنترلر خارجی نیست و ارتباط میان ماژول نمایش‌گر و میکروکنترلر از طریق واسط‌های سخت‌افزاری استاندارد(مثل SPI یا Intel8080) برقرار می‌گردد. باید دقت‌کرد که این ماژول‌ها عموما با نام چیپ کنترلرشان شناخته می‌شوند(به عنوان مثال نمایش‌گر گرافیکی ۱۲۸در۶۴ پیکسل با کنترلر ST7920).

یک کتابخانه‌ی گرافیکی بی‌نقص، کتابخانه‌ای است که به راحتی و به روشی استاندارد به هر پروژه Port یا وارد شود.

توجه: Port کردن شامل فرآیندی است که در آن تعدادی مشخص از توابع Gate یا دروازه برای ارتباط کل کتابخانه با بخش‌ها و کتابخانه‌های دیگر به روشی استاندارد معرفی شوند. به این روش کل کتابخانه‌ای که Port می‌شود دست نخورده باقی می‌ماند و بسته به نیاز هر پروژه فقط تغییر توابع دروازه‌ای برای تطبیق آن با کل پروژه کافی است.

کتابخانه‌های گرافیکی فراوانی به این منظور وجود دارند. اما همه‌ی آن‌ها دو قابلیت اساسیِ زیر را ندارند:

  • پشتیبانی و به‌روزرسانیِ فعال

  • منبع‌باز بودن کتابخانه برای تغییرات احتمالی مورد نیاز روی کتابخانه و مجوز استفاده‌ی رایگان

با درنظر گرفتن موارد بالا، می‌توان به جرات گفت که کتابخانه‌ی U8G2 که آقای Oliver Kraus بنیان‌گذار آن است و با همکاری حدود ۳۰ نفر Developer از سراسر دنیا آن را در دسترس عموم قرار داده‌است، اکثر موارد بالا را پوشش می‌دهد. کاملا منبع‌باز بوده و پشتیبانی فعال دارد. به راحتی و استاندارد Port می‌شود و شامل درایور نرم‌افزاریِ چیپ‌های کنترلر مرسوم است. اخیرا پشتیبانی از فونت‎های فارسی هم به آن اضافه‌شده که می‌تواند برای کاربران فارسی‌زبان قابلیت جذابی باشد. همچنین راهنمای بسیار جامعی دارد که کارکردن با آن را آسان کرده‌است. به زبان C استاندارد نوشته شده‌است و البته کتابخانه‌ی آماده‌ای برای Port کردن به Arduino هم شامل می‌شود. باید اشاره‌کرد که در حال حاضر این کتابخانه امکانات خیلی سطح بالا نظیر طراحی Tab Control یا Windows Manager را در خود ندارد و شاید در آینده به آن اضافه شود.

برای استفاده و خواندن مطالب بیشتر در مورد این ‎کتابخانه‌ی کم‌نظیر از لینک زیر استفاده کنید.

کتابخانه گرافیکی مناسب برای نمایش‌گر رنگی(Color Display)

هر Pixel نمایش‌گر رنگی برخلاف تک‌رنگ، قابلیت نمایش تعداد مشخصی رنگ‌ را دارد. هر چه تعداد رنگ‌هایی که یک pixel نمایش‌گر می‌تواند نمایش‌دهد بیشتر باشد، اصطلاحا قابلیت عمق رنگ آن نمایش‌گر بیشتر است. TFT LCDها نمونه‌ای از این نمایش‌گرها هستند که با چیپ‌های کنترلر مختلف (مانند SSD1963) یا واسط مستقیم RGB میکروکنترلر راه‌اندازی می‌شوند.

این مساله پیچیدگی کنترل نمایش‌گر را بیشتر کرده و علاوه بر آن حجم حافظه مورد نیاز را برای نگه‌داری اطلاعات یک Frame نمایشی، به اندازه‌ی قابل توجهی افزایش‌می‌دهد. ازسوی‌دیگر، زمان ارسال اطلاعات به نمایش‌گر را زیاد می‌کند. برای مدیریت بهینه‌ی این موارد علاوه بر ملاحظات سخت‌افزاری و بهره‌گیری از واسط سخت‌افزاری مناسب، کدنویسی درست برای پردازش و آماده‌سازیِ هرچه سریع‌ترِ داده‌های یک Frame و ارسال آن‌ها به نمایش‌گر هم اثری شگرف دارد. از دو آزمون مرسوم Stress Test و Benchmark برای بررسی سرعت پردازش و ارسال داده‌های گرافیکی یک ترکیب سخت‌افزار و نرم‌افزار استفاده‌می‌کنند. هرچه مشاهده‌ی پدیده‌ی Flickering و Tearing در آزمون Stress Test کم‌تر دیده‌شود و Frame Rate در بخش‌های مختلف آزمون Benchmark بیش‌تر باشد، سیستم طراحی‌شده قدرت گرافیکی بیش‌تری دارد.

کتابخانه‌ی گرافیکی مناسب باید شرایط بهینه بالا را ایجادکند و علاوه بر آن امکانات مستقلی را برای طراحی سریع صفحات گرافیکی در اختیار طراح بگذارد که بتواند بدون توجه به سخت‌افزار و دیگر کتابخانه‌ها، طراحی مورد نظر را به انجام برساند و به راحتی و با روشی استاندارد، کد خود را به هر پروژه‌ای Port کند. علاوه بر آن هرچه توابع پیشرفته‌ بیشتری برای ساختن Widgetهای گرافیکی و از پیش تعیین‌شده در کتابخانه موجود باشد، سرعت طراحی بیشتر شده و ارزش استفاده از آن بیشتر خواهدبود.

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

 

کتابخانه Total Cross

این کتابخانه منبع‌باز بوده و بر بستر Java نوشته شده‌است که البته Cross-Platform است و می‌تواند برای سیستم‌های Embedded به کار گرفته‌شود. ایراد عمده‌ی آن برای کاربردهای Embedded الزام استفاده از سیستم‌عامل‌های مشخصی بر روی پردازنده اصلی است که همانطور که می‌دانیم در بسیاری از پروژه‌ها امکان آن وجود ندارد. Port کردن آن برای برنامه‌نویسان سیستم‌های Embedded که عمدتا با زبان C آشنایی دارند ممکن است دردسر ایجادکند. علاوه بر آن در سیستم‌های Embedded که منابع سخت‌افزاری مثل حافظه محدودیتی در اندازه‌ی کیلوبایت دارند امکان اجرا ندارد. برای آشنایی بیشتر با Total Cross از لینک زیر استفاده‌کنید.

کتابخانه uGFX

کتابخانه نسبتا کم حجمی است که به زبان C نوشته شده و برای پروژه‌هایی Embedded که امکان استفاده از منابع سخت‌افزاری قدرتمند وجود ندارد هم مناسب است. منبع‌باز بوده و کد آن در درسترس است اما عیبش این است که برای کاربردهای تجاری نیاز به خرید مجوز استفاده دارد. برای آشنایی بیشتر با uGFX از لینک زیر استفاده‌کنید.

کتابخانه GUIslice

یک کتابخانه‌ی کم حجم مناسب برای پروژه‌هایی که سخت‌افزار و حافظه در محدودیت زیاد است. حتی بر روی میکروکنترلرهای ۸ بیتی هم اجرا می‌شود. کاملا رایگان است اما عیب آن نداشتن قابلیت‌های حرفه‌ای مانند Shadow و Style برای افزودن ظاهری حرفه‌ای به گرافیک تصویر نمایشی است. برای ایجاد منوهای رنگی با ظاهری ساده مناسب است و از فونت فارسی پشتیبانی نمی‌کند. برای خواندن بیشتر در مورد GUIslice از لینک زیر استفاده‌کنید.

کتابخانه GuiLite

یک کتابخانه‌ی بسیار کم حجم مناسب برای پروژه‌هایی که سخت‌افزار و حافظه در محدودیت زیاد است. کاملا رایگان است. از فونت فارسی پشتیبانی نمی‌کند. برای خواندن بیشتر در مورد GuiLite از لینک زیر استفاده‌کنید.

کتابخانه TouchGFX

یک کتابخانه‌ی مناسب برای پروژه‌هایی که منابع سخت‌افزار و حافظه کم است. کاملا رایگان است و با زبان ++C نوشته شده‌است. قابلیت‌های گرافیکی زیبایی در اختیار طراح قرار می‌دهد اما عیب آن این است که اختصاصی برای میکروکنترلرهای STM32 توسعه یافته‌است. برای خواندن بیشتر در مورد TouchGFX از لینک زیر استفاده‌کنید.

کتابخانه emWin

کتابخانه‌ا‌ی است مناسب برای پروژه‌هایی که منابع سخت‌افزار و حافظه کم است. طراحی‌های منحصربه‌فرد و زیبایی را در زمان کم ممکن می‌سازد. عیب آن این است که برای استفاده‌ی تجاری نیاز به خرید مجوز از شرکت SEGGER دارد و کد کتابخانه منبع‌بسته است. برای خواندن بیشتر در مورد emWin از لینک زیر استفاده‌کنید.

کتابخانه LVGL، مناسب‌ترین برای نیازهای گرافیکی پروژه

Light and Versatile Graphics Library کتابخانه‌ای است مناسب برای راه‌اندازی هر مدل نمایش‌گر گرافیکی رنگی و تک‌رنگ که در زبان C به شکل منبع باز و بر اساس استاندارد C99 نوشته شده‌است (در محیط ++C هم مطابقت دارد). تحت مجوز MIT در دسترس عموم قرار گرفته و کاملا رایگان است. کد کتابخانه در دسترس است. پشتیبانی فعال توسط حدود ۱۱۰ نفر از سراسر دنیا دارد که در هر ماه بر اساس برنامه‌ای از پیش تعیین‌شده نسخه‌ی جدید آن به هدایت آقای Gabor Kiss-Vamosi که نویسنده‌ی اصلی آن است، بیرون داده‌می‌شود. راهنمای جامعی دارد که می‌توان برای شروع قدم‌های محکم و سریعی با آن برداشت. همچنین شایان ذکر است که شرکت معتبر TI(Texas Instruments) برای راه‌اندازی بخش گرافیکی مرتبط با میکروکنترلر‌هایش استفاده از این کتابخانه را توصیه کرده‌است. برای خواندن این بخش در وب‌سایت TI از لینک زیر استفاده‌کنید.

حجم نسبتا کمی دارد و برای استفاده در سیستم‌های Embedded که منابع سخت‌افزاری و حافظه محدود است، مناسب است. در صورت محدودیت زیاد، با پیکربندی بافر حافظه می‌توان میزان استفاده از حافظه را کنترل کرد. همچنین کتابخانه‌ی آماده‌ی آن در زبان MicroPython هم منتشر می‌شود که برای استفاده در چیپ‌هایی چون ESP32 کار را بسیار آسان‌می‌کند. البته برای پیاده‌سازی در میکروکنترلرهای ۸ بیتی مناسب نیست.

امکان ایجاد بیش از ۳۰ نوع Widget آماده مثل دکمه، اسلایدر، نمودار و گراف، کیبورد و … را در styleهای دل‌خواه به سادگی برای طراح مهیا می‌کند. تنظیمات مربوط به Event برای هر Widget و نوشتن تابع Callback برای انجام کاری دل‌خواه در زمان وقوع Event به راحتی انجام می‌گیرد. ایجاد انیمیشن در تبدیل حالت Widget ها جذابیت حرفه‌ای به طراحی گرافیکی می‌دهد که کتابخانه‌ی LVGL این امکان را در اختیار طراح گذاشته‌است.

خواندن انواع ورودی‌های اشاره‌گر از کلید تا Mouse و Touchpad در این کتابخانه در نظر گرفته‌شده‌است و به سادگی با پیکربندی ابزار ورودی در هنگام Port کردن، نیاز طراح برای داشتن یک رابط کاربری گرافیکی رنگی اعم از ورودی و خروجی را مرتفع می‌سازد. حتی امکان پیکربندی خروجی صوتی برای ایجاد صداهای مختلف در شرایط وقوع Eventها را دارد. بنابراین می‌توان گفت که کتابخانه‌ی LVGL نه تنها برای راه‌اندازی نمایش‌گر، که به شکل کلی برای ایجاد رابط کاربری گرافیکی کامل مناسب و کارا است.

برای بخش نوشتن متن ابزارهای جامع و کاملی شبیه یک ویراش‌گر متن با توابع آماده در اختیار طراح است تا بتواند به سرعت امکانات ویرایش متن حرفه‌ای را در رابط کاربری بگنجاند. همچنین از زبان فارسی به‌طورکامل پشتیبانی می‌کند و ابزارهای آماده‌ای برای Port کردن قلم(Font Type) دل‌خواه به پروژه دارد. علاوه بر آن به سادگی می‌توان هر عکسی را با هر استاندارد رنگی به کد مناسب C تبدیل کرد و به حافظه انتقال و یا از آن فراخوانی کرد.

داشتن قابلیت styleهای از پیش طراحی شده، حفظ یک‌پارچگی را در طراحی رابط کاربری برای پروژه آسان می‌کند. همچنین این پروژه‌ی منبع‌باز، بخش شبیه‌سازی دارد که با فعال سازی آن امکان طراحی صفحات کاربری در شبیه‌ساز و تولید کد آماده و متناظر با آن مهیا می‌شود. این ابزار سرعت طراحی و اشکال‌یابی را به طرز چشم‌گیری افزایش می‌دهد. ازسوی‌دیگر می‎توان با فعال‌سازی حالت اشکال‌یابی(debug) در تنظیمات کتابخانه، به ردیابی برخطِ اشکالات احتمالی در زمان اجرای برنامه و مشاهده‌ی گزارش آن در فایل Log پرداخت.

یکی دیگر از قابلیت‌های مهم این کتابخانه، امکان استفاده از آن در مدل برنامه‌نویسی super loop و نیز سازگاری با اجرا در سیستم‌عامل‌های کوچکی چون FreeRTOS تا لینوکس می‌باشد که محدودیتی برای طراح در پروژه‌های مختلف ایجاد نمی‌کند.

 

اصول کار و Port کردن کتابخانه‌ی LVGL

اصول کار LVGL را می‌توان در خلاصه‌ای چند خطی زیر بیان کرد.

در ابتدا توسط تابع مقداردهی اولیه که طراح برای کتابخانه می‌نویسد، پیکربندی بافر حافظه‌ی مورد نیاز کتابخانه انجام می‌گیرد. بعد از آن، پیکربندی نمایش‌گر و درایور چیپ کنترلر صورت می‌گیرد. سپس در حلقه‌ی اصلی برنامه، با یک دوره‌ی زمانی ثابت و دل‌خواه (مثلا هر ۲۰ میلی‌ثانیه که می‌تواند توسط تایمر میکروکنترلر ایجاد شود)، تابع handler کتابخانه اجرا می‌شود. وظیفه‌ی تابع handler آن است که اگر Eventی اتفاق افتاده‌بود یا نیازی به Refresh کردن صفحه‌ی نمایش‌گر بود، آن را انجام داده و بافر حافظه را آماده‌ و به نمایش‌گر ارسال ‌کند.

جدای از روند بالا، تایمری دیگر از میکروکنترلر به شکل Tick Timer برای Synchronize کردن باید در نظر گرفته‌شود تا از طریق فراخوانی تابع lv_tick_inc(x)، زمان سپری‌شده را به اطلاع کتابخانه ‌برساند.

 

واردکردن(Porting) کتابخانه به پروژه‌ای در زبان C به سادگی ۹ مرحله‌ی زیر است.

 

کد کتابخانه‌ی به روز، مثال‌ها و درایورها از صفحه‌ی Github دریافت شود. اینجا کلیک کنید. پوشه‌ی lvgl به پروژه اضافه شود.

  1. کتابخانه یا فایل درایور نرم‌افزاری چیپِ کنترلر(مثلا SSD1963) باید نوشته یا از منبعی معتبر دریافت شود.

  2. در فایل Lv_conf.h تنظیمات مربوط به فعال‌سازی بخش‌های مختلف کتابخانه انجام شود. اگر بخشی مورد نیاز نیست، برای کاهش حافظه‌ی اشغالی حتما غیرفعال شود.

  3. حداقل ۳ مورد Define زیر در فایل Lv_conf.h بر اساس نیاز پروژه مقداردهی شود:

    • LV_HOR_RES_MAX: تعداد Pixel افقی نمایش‌گر

    • LV_VER_RES_MAX: تعداد Pixel عمودی نمایش‌گر

    • LV_COLOR_DEPTH: یکی از مقادیر ۸،۱۶ یا ۳۲

  1. مقداردهی اولیه(Initialize) کردن کتابخانه‌ی گرافیکی LVGL شامل مراحل زیر است:

    • فراخوانی تابع lv_init

    • مقداردهی اولیه‌ی درایور چیپ کنترلر

    • تخصیص بافر حافظه و register کردن درایورِ Display و Input Device (در مرحله ۶ و ۷ توضیح داده شده‌است)

    • در هر x میلی‌ثانیه تابع lv_tick_inc(x) فراخوانی شود.

    • تابع ()lv_task_handler در هر y میلی‌ثانیه برای انجام کارهای LVGL فراخوانی شود. مقدار y باید از x کمتر باشد.

  1. در فایل main، متغییر lv_disp_buf_t به شکل نشان داده‌شده در منوی زیر مقداردهی شود.

  2. در فایل main، متغییر lv_disp_drv_t به شکل نشان داده‌شده در منوی زیر مقداردهی شود. اعضای buffer و flush_cb حتما باید مقداردهی شوند. مقداردهی بقیه‌ی اعضا اختیاری است. سپس توابع lv_disp_drv_init(&disp_drv) و lv_disp_drv_register(&disp_drv) فراخوانی شوند.

  1. کتابخانه LVGL برای اطلاع از زمان سپری شده نیاز دارد تا تابع lv_tick_inc(tick_period) به شکل دوره‌ای در هر tick_Period فراخوانی شود. با راه‌اندازی یک زمان‌سنج(timer) می‌توان به این مقصود رسید. یا به عنوان مثال در FreeRTOS در تابع vApplicationTickHook می‌توان آن را فراخوانی کرد.

  2. کتابخانه LVGL برای انجام وظایف و تغییرات لازم در بافر حافظه نیاز دارد تا تابع ()lv_task_handler با دوره‌ای ثابت فراخوانی شود. زمان فراخوان دوره‌ای آن از فراخوانی تابع در مرحله قبل باید بیشتر باشد و همچنین اگر در Interrupt استفاده می‌شود، اولویت آن از مرحله ۸ باید کمتر باشد. با فراخوانی این تابع در حلقه‌ی while اصلی برنامه یا از طریق callback زمان‌سنجی دیگر به این مقصود می‌توان دست یافت.

/*A static or global variable to store the buffers*/
static lv_disp_buf_t disp_buf;

/*Static or global buffer(s). The second buffer is optional*/
static lv_color_t buf_1[MY_DISP_HOR_RES * 10];
static lv_color_t buf_2[MY_DISP_HOR_RES * 10];

/*Initialize `disp_buf` with the buffer(s) */
lv_disp_buf_init(&disp_buf, buf_1, buf_2, MY_DISP_HOR_RES*10);

lv_disp_drv_t disp_drv; /*A variable to hold the drivers. Can be local variable*/

lv_disp_drv_init(&disp_drv);            /*Basic initialization*/
disp_drv.buffer = &disp_buf;            /*Set an initialized buffer*/
disp_drv.flush_cb = my_flush_cb;        /*Set a flush callback to draw to the   display*/
/*Register the driver and save the created display objects*/
lv_disp_t * disp;disp = lv_disp_drv_register(&disp_drv);

void my_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
/*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
int32_t x, y;
for(y = area->y1; y <= area->y2; y++) {
for(x = area->x1; x <= area->x2; x++) {
put_px(x, y, *color_p)
color_p++;
}
}
/* IMPORTANT!!!         * Inform the graphics library that you are ready with the flushing*/
lv_disp_flush_ready(disp);
}

ذکر مراحل بالا برای آشنایی کلی با کارکرد کتابخانه‌ی LVGL آورده شده‌است. مسلما در نگاه اول ممکن‌است گویا نباشد. لذا توصیه می‌شود برای دسترسی به راهنمای جامع این کتابخانه از آدرس زیر استفاده کنید. بعد از کمی مطالعه‌ی با دقت و راه‌اندازی اولین پروژه با LVGL، شما هم در مورد سادگی Port کردن آن با ما هم نظر خواهید شد.

جمع‌بندی

آغاز مبحث، با معرفی رابط کاربری بود. توضیح داده‌شد که رابط کاربری چیست و استفاده از رابط کاربری گرافیکی چه مزایایی در بر دارد. نشان داده‌شد که برای رسیدن به این مزایا، با پیچیدگیِ راه‌اندازی نمایش‌گرهای گرافیکی مواجه هستیم. برای برآمدن بر این پیچیدگی‌ها، استفاده از بسته‌ی نرم‌افزاری جامعی که وابستگی به منابع و واسط‌های سخت‌افزاری نداشته‌باشد، پیشنهاد شد. در ادامه اصول ارتباطی نمایش‌گرها بررسی شد و برای راه‌اندازی نرم‌افزاری آن، راه‌‌کارهای موجود مورد بررسی اجمالی قرارگرفت.

در آخر به طور خلاصه می‌توان گفت که برای راه‌اندازی همه‌کاره و جامع یک رابط کاربری کامل گرافیکی اعم از پیکربندی ابزار ورودی و خروجی، مناسب‌ترین کتابخانه‌ای که در حال حاضر می‎توان استفاده‌کرد، کتابخانه‌ی LVGL است. البته در مورد راه‌اندازی نمایش‌گرهای تک‌رنگ، استفاده از کتابخانه‌ی U8G2 از آن‌جا که مصرف حافظه‌ی کمتری دارد بهینه‌تر است.

نمونه‌ی اجرای Demo

به عنوان یک نمونه، Demoی کتابخانه‌ی LVGL به پروژه‌ای با مشخصات زیر برای راه‌اندازی یک واحد کامل رابط کاربری گرافیکی، Port شده‌است.

مشخصات سخت‌افزاری پروژه
میکروکنترلر
STM32F407ZGT
حافظه‌ی خارجی(RAM)
ندارد
فرکانس Clock
۱۶۸Mhz
چیپِ کنترلر نمایش‌گر
SSD1963
واسط سخت‌افزار میکروکنترلر
FSMC
ماژول نمایش‌گر
INANBO-T43CHR-V18 TFT LCD [800x480px-4.3inches]
ماژول ورودی
USB Mouse
مشخصات نرم‌افزاری پروژه
Tool Chain
STM32CubeMX V5.6.1 & Keil V5.24.2.0
MiddleWare
ST_USB_HOST V1.0_Cube
Compiler
Keil V5.06 update 5
Optimization Level
Level 3
کتابخانه گرافیکی
LVGL V7.3.1

از compile پروژه با مقداردهی بافر lv_disp_buf_t به تعداد ۳۶۰۰۰ عدد(که حاصل‌ضرب رزولوشن افقی در تعدادِ دلخواه ۴۵ عدد است)، نتایج زیر بدست آمده‌است.

حجم مصرفی حافظه‌ی Flash و SRAM میکروکنترلر
Flash[Code+RO-data]
۲۰۰KB
SRAM[RW-data+ZI-data]
۱۴۵KB

از compile پروژه با مقداردهی بافر lv_disp_buf_t به تعداد ۸۰۰۰ عدد(که حاصل‌ضرب رزولوشن افقی در تعدادِ دلخواه ۱۰ عدد است)، نتایج زیر بدست آمده‌است.

حجم مصرفی حافظه‌ی Flash و SRAM میکروکنترلر
Flash[Code+RO-data]
۲۰۰KB
SRAM[RW-data+ZI-data]
۸۹KB

باید توجه‌داشت که بخشی از مصرف حافظه در این پروژه به راه‌اندازی USB Mouse اختصاص یافته‌است و همه‌ی آن مربوط به کتابخانه‌ی LVGL نیست. همچنین این پروژه بدون بهینه‌سازی Compile شده و متغییرهای Dummy از آن حذف نشده‌اند. 

ویدئوی اجرای برنامه در زیر آورده شده‌است.

  • نویسنده
    صابر یوسفی
  • تعداد بازدید
    424 بازدید
۰دیدگاه فرستاده شده است.
شما هم دیدگاه خود را بنویسید