آموزش FPGA

نحوه رابط صفحه Mojo V3 FPGA با یک ماژول LCD 16×2

در این مقاله ، جزئیات رابط کاربری یک ماژول LCD 16×2 با FPGA مورد بحث قرار خواهد گرفت. در مقاله های قبلی ، بلوک های ساختمانی مورد نیاز برای رابط FPGA را با یک ماژول LCD 16×2 مشترک بررسی کردیم. ما دیدیم که بلوک های اصلی ساختمان ROM ، برخی DFF ها  چند برابر هستند. علاوه بر این ، برای کنترل این بلوک های ساختمانی به یک FSM (دستگاه محدود کننده حالت) احتیاج داشتیم. در این مقاله ، به جزئیات طراحی FSM خواهیم پرداخت. سپس ، کد Verilog را برای بلوک های مختلف خواهیم نوشت و از تابلوی Mojo V3 برای تأیید طراحی خود استفاده خواهیم کرد.

نمودار بلوک سیستم

نمودار بلوک رابط FPGA-LCD در شکل ۱ در زیر نشان داده شده است:

شکل ۱

همانطور که مشاهده می کنید ، FSM دارای دو ورودی (addr_reg و cnt_reg) و پنج خروجی (s1، s2، RS، RW و E). ورودی های FSM به ما امکان می دهد وضعیت بلوک های “مسیر ۱” و “مسیر ۲” را کنترل کنیم. خروجی “” ” s1مسیر ۱″ را کنترل می کند و به تبع آن داده های روی پین های DB7-DB0  اعمال می شوند. خروجی “” s2بلوک “مسیر ۲” را کنترل می کند و می تواند برای تولید تاخیر زمانی لازم مورد استفاده قرار گیرد. خروجی های “” RS ، “RW” و “” E شکل موجهای مناسبی را برای پین های کنترل LCD ایجاد می کنند.

طراحی FSM

طراحی اولیه برای FSM در شکل ۲ نشان داده شده است. FSM دارای سه حالت است: “آماده به کار” ، “” lcd_init و “” lcd_print .

آموزش FPGA

شکل ۲

حالت “آماده به کار”

در حالت “آماده به کار” ، به خروجی ها مقدار دهی اولیه داده می شود. بلوک ASM ( دستگاه حالت الگوریتمی) برای این حالت در شکل ۳ نشان داده شده است.

آموزش FPGA

شکل ۳

در حالت “آماده به کار” ، خروجی های “” RW ، “RS” و “” E در  مقدار دهی های استارت می زنند. خروجی های “” s1 و “” s2 برابر با ۲ هستند به طوری که DFF های “مسیر ۱” و “مسیر ۲” در لبه ساعت بعدی تنظیم مجدد شوند (شکل ۱). توجه داشته باشید ورودی اضافی (“شروع”) برای FSM است.  این به یک دکمه فشار روی نمونه متصل خواهد شد. تنظیم ورودی “” start روی منطق بالا ، روند چاپ روی LCD را آغاز می کند.

حالت  “” lcd_init

در این حالت ، ماژول LCD اولیه سازی می شود. برای این منظور ، چهار فرمان (x38  ۰،  ۰x0C ، ۰x06 و۰x01) که در آدرس های ۰ تا ۳ رام ذخیره می شوند، باید روی پین های داده LCD قرار گیرند. به همین دلیل است که نمودار حالت شکل ۲، عبارت addr_reg = 3 را به عنوان شرط انتقال از “” lcd_init به حالت بعدی درج می کند (“lcd_print”).

اصطلاح دیگر برای شرایط انتقال حالت cnt_reg = 3،۵۵۰،۰۰۰ است. هر بایت از ROM باید برای مدت زمان کافی (۷۱ مایل در این طراحی) روی پین های داده LCD استفاده شود. شرط cnt_reg = 3،۵۵۰،۰۰۰ اطمینان می دهد که LCD زمان کافی (۷۱ میلی ثانیه) برای خواندن پین های داده دارد. بنابراین ، شرایط addr_reg = 3 && cnt_reg = 3،۵۵۰،۰۰۰ بدان معنی است که چهارمین دستور ذخیره شده در ROM برای حدود (   ms71) روی LCD اعمال می شود. وقتی این شرایط برآورده شود ، LCD با موفقیت آغاز می شود و می توانیم داده های پیام را روی DB7-DB0 قرار دهیم.

بلوک ASM برای حالت “” lcd_init در شکل ۴ نشان داده شده است.

آموزش FPGA

شکل ۴

قبل از بررسی بلوک ASM بالا ، ببینیم که چگونه شماره آستانه برای cnt_reg تعیین می شود. نمودار زمان بندی برای نوشتن ماژول LCD در شکل ۵ نشان داده شده است.

آموزش FPGA

شکل ۵٫ از روش HITACHI استفاده شده

توجه داشته باشید که سیگنال “” E باید پس از tAS به منطق بالا برود. برای PWEH در منطق بالا باقی مانده و سپس انتقال به منطق پایین tH قبل از عملیات نوشتن بعدی انجام شود. در این مقاله ، tAS ، PWEH و tH به ترتیبms 10 ، ۵۸ ms  و ۳ ms هستند. شکل موج برای سیگنال “” E همانطور که در شکل ۶ نشان داده شده است.

آموزش FPGA

شکل ۶

این شکل همچنین تعداد معادل شمارش برای هر تأخیر زمانی را نشان می دهد. توجه داشته باشید که فرکانس ساعت صفحه Mojo V3 50 مگاهرتز (مدت زمان = ۲۰ نانومتر) است. همانطور که در شکل ۴ نشان داده شده است ، مقدار “” cnt_reg را بررسی می کنیم تا یک مقدار مناسب برای  E تنظیم شود. برای مثال ، هنگامی که سیگنال “” cnt_reg از ۵۰۰۰۰۰ بزرگتر و کمتر از ۴،۴،۰۰۰،۰۰۰ باشد ، سیگنال E باید منطقی باشد.

باز هم ، خروجی های “” s1 و “” s2 بر اساس مقدار سیگنال “” cnt_reg تعیین می شوند. اگر “” cnt_reg کمتر از ۳۵۵۰،۰۰۰ (معادل ۷۱ ms) باشد ، ما به انتهای عملیات نوشتن نرسیده ایم (شکل ۶ را ببینید). بنابراین، داده های اعمال شده بر روی LCD نباید تغییر کنند (s1 = 0) و شمارنده باید حساب شود (s2 = 1). اما ، وقتی “” cnt_reg بیشتر از ۳۵۵۰،۰۰۰ (معادل ۷۱ ms) باشد ، ما به پایان عملیات نوشتن فعلی رسیده ایم. در این حالت ، داده های آدرس بعدی ROM باید بر روی LCD (s1 = 1) اعمال شود و شمارنده در ۰ (S2 = 2)  مجددا تنظیم شوند. (شکل ۱ را ببینید).

همانطور که قبلاً بحث شد ، در  چهار دستور پیکربندی LCD داریم که در آدرس های ۰ تا ۳ رام ذخیره می شوند. هنگامی که دستور چهارم (addr_reg = 3) برای ۷۱ ms (cnt_reg = 3،۵۵۰،۰۰۰) روی LCD اعمال می شود ، باید به حالت “” lcd_print برویم که داده های پیام را به LCD ارسال می کند. این با آخرین شش ضلعی در بلوک ASM حاصل می شود.

توجه داشته باشید که ورودی “” RS  از ماژول LCD مشخص می کند که آیا DB7-DB0 باید به عنوان یک کد دستورالعمل (RS = 0) یا به عنوان داده (RS = 1) رفتار شود. از این رو ، در حالت “” lcd_init ، پین RS باید از نظر منطقی کم باشد. پین RW مشخص می کند که آیا ما به ماژول می نویسیم (RW = 0) یا از آن می خوانیم (RW = 1). در هر دو حالت “” lcd_init و “” lcd_print ، ما یک عملیات نوشتن را انجام می دهیم و RW باید منطقی باشد.

حالت “” lcd_print

حالت ” ” lcd_print کاملاً شبیه حالت ” ” lcd_init است با این تفاوت که RS باید منطقی باشد (زیرا اکنون DB7-DB0 باید به عنوان یک داده به جای یک کد دستورالعمل رفتار شود). علاوه بر این ، مقادیر آستانه بررسی شده برای سیگنال addr_reg باید تغییر کند زیرا این پیام در آدرس های ۴ تا ۱۹ رام ذخیره می شود. با این تغییرات ، بلوک ASM را در شکل ۷ نشان می دهیم.

آموزش FPGA

شکل ۷

سرانجام ، با اتصال همه این بلوکهای ASM ، نمودار ASM را که در شکل ۸ نشان داده شده است ، بدست می آوریم.

کد Verilog

اگر نمودار بلوک شکل ۱ و نمودار ASM فوق را داشته باشیم ، ایجاد توصیف Verilog از سیستم، کار ساده ای است. بیایید نگاهی به کد بلوک های ساختمانی مختلف بیندازیم:

مسیر ۱

برای بلوک “مسیر ۱” ، به رام ۸✕۲۰ نیاز داریم:

//Path 1: ROM

wire [7:0] rom_data [19:0];

assign rom_data[0] = 8’h38;

assign rom_data[1] = 8’h06;

assign rom_data[2] = 8’h0C;

assign rom_data[3] = 8’h01;

assign rom_data[4] = ” “;

assign rom_data[5] = ” “;

assign rom_data[6] = “H”;

assign rom_data[7] = “E”;

assign rom_data[8] = “L”;

assign rom_data[9] = “L”;

assign rom_data[10] = “O”;

assign rom_data[11] = ” “;

assign rom_data[12] = “W”;

assign rom_data[13] = “O”;

assign rom_data[14] = “R”;

assign rom_data[15] = “L”;

assign rom_data[16] = “D”;

assign rom_data[17] = “!”;

assign rom_data[18] = ” “;

assign rom_data[19] = ” “;

assign data = rom_data[addr_reg];

این مشخص می کند که “” rom_data یک آرایه ی دو بعدی از سیم است. توجه داشته باشید که در Verilog، بُعد دوم آرایه پس از نام آرایه آمده است. مقادیر مورد نظر به آرایه اختصاص داده می شود و سرانجام ، خروجی ROM به “داده” اختصاص می یابد. “داده” خروجی طراحی است و به DB7-DB0 ماژول LCD وصل خواهد شد.

رجیسترها و مولتی پلکسر “مسیر ۱” را می توان با کد زیر شرح داد:

مسیر ۲

بلوک “مسیر ۲” به شرح زیر است:

eg [21:0] cnt_reg, cnt_next;

//Path 2: Registers

[email protected](posedge clk, posedge rst)

begin

            if(rst)

                    cnt_reg <= 21’h0;

             else

                    cnt_reg <= cnt_next;

              end

//Path 2: Mux

always @*

           case(s2)

                ۲’b00:

                      cnt_next = cnt_reg;

                 ۲’b01:

                       cnt_next = cnt_reg + 1’b1;

                ۲’b10:

                        cnt_next = 21’h0;

                 default:

                        cnt_next = cnt_reg;

                endcase

FSM

برای توصیف FSM در Verilog HDL ، می توانیم از عبارت “” localparam برای تعریف ثابت های نمادین که نمایانگر حالت های FSM هستند استفاده کنیم. FSM ما سه حالت دارد. این حالت را می توان با

“” localparam زیر شرح داد:

localparam [1:0]                                idle      = ۲’b00,

                                                                 lcd_init  = ۲’b01,

                                                                 lcd_print = 2’b10;

برای ذخیره حالت سیستم ، یک ثبات دو بیتی تعریف می کنیم:

eg [1:0] state_reg, state_next;

//State Registers

[email protected](posedge clk, posedge rst)

begin

         if(rst)

                  state_reg <= idle;

          else

                 state_reg <= state_next;

          end

سپس ، باید مدار ترکیبی را تعیین کنیم که وضعیت بعدی FSM را تعیین کند. این قسمت از کد را می توان بر اساس شش ضلعی های نمودار ASM در شکل ۸ نوشت:  توجه داشته باشید که کد زیر شرایط انتقال حالت را که قبلاً از آن گرفته شده ساده کرده است.

//Next State Logic

always @*

begin

           case(state_reg)

                idle:

                       if(start)

                               state_next = lcd_init;

                        else

                                state_next = idle;

           lcd_init:

                     if(addr_reg == 5’h03 && cnt_reg == 3550000)

                           state_next = lcd_print;

                     else

                            state_next = lcd_init;

             lcd_print:

                    if(addr_reg == 5’h19 && cnt_reg == 3550000)

                             state_next = idle;

                       else

                             state_next = lcd_print;

                    default:

                           state_next = idle;

                      endcase

                    end

سرانجام ، ما باید کد Verilog را برای خروجی های FSM بنویسیم. این قسمت از کد را می توان بر اساس بیضی شکل ۸ نوشت ، که نشان دهنده تکالیف شرطی FSM است.

//Output Logic

always @*

begin

                    case(state_reg)

                                idle:

                                       begin

                                               s1 = 2’b10;

                                               s2 = 2’b10;

                                               RW = 0;

                                               RS = 0;

                                               E = 0;

                                                end

lcd_init:

begin

s1 = 2’b00;

s2 = 2’b01;

RS = 0;

RW = 0;

E = 0;

        if (cnt_reg >= 500000)

E = 1;

         if (cnt_reg >= 3400000)

E = 0;

if (cnt_reg == 3550000)

begin

s1 = 2’b01;

s2 = 2’b10;

   end

   end

lcd_print:

begin

s1 = 2’b00;

s2 = 2’b01;

RS = 1;

RW = 0;

E = 0;

if (cnt_reg >= 500000)

E = 1;

if (cnt_reg >= 3400000)

E = 0;

if (cnt_reg == 3550000)

begin

s1 = 2’b01;

s2 = 2’b10;

    end

   end

default:

begin

s1 = 2’b10;

s2 = 2’b10;

RW = 0;

RS = 0;

E = 0;

end

endcase

end

پروژه Mojo

اکنون می توانید نسخه ای از پروژه Mojo Base را بگیرید و بخش های کد بالا را به آن اضافه کنید. به یاد داشته باشید که باید ورودی ها و خروجی های ماژول سطح بالا Verilog را تغییر دهید.

کد نهایی خواهد بود:

module mojo_top(

    // ۵۰MHz clock input

    input clk,

    // Input from reset button (active low)

    input rst_n,

    // cclk input from AVR, high when AVR is ready

    input cclk,

    // Outputs to the 8 onboard LEDs

    output[7:0]led,

    // AVR SPI connections

    output spi_miso,

    input spi_ss,

    input spi_mosi,

    input spi_sck,

    // AVR ADC channel select

    output [3:0] spi_channel,

    // Serial connections

    input avr_tx, // AVR Tx => FPGA Rx

    output avr_rx, // AVR Rx => FPGA Tx

    input avr_rx_busy, // AVR Rx buffer full

//My Inputs and Outputs

                                                     input start,

                                                     output [7:0] data,

                                                     output reg RS, RW, E

                                                     );

wire rst = ~rst_n; // make reset active high

// these signals should be high-z when not used

assign spi_miso = 1’bz;

assign avr_rx = 1’bz;

assign spi_channel = 4’bzzzz;

assign led[7:0] = 5’h00;

localparam [1:0] idle      = ۲’b00,

                                                                                                              lcd_init  = ۲’b01,

                                                                                                              lcd_print = 2’b10;

reg [1:0] state_reg, state_next;

reg [4:0] addr_reg, addr_next;

reg [21:0] cnt_reg, cnt_next;

reg [1:0] s1, s2;

//State Registers

[email protected](posedge clk, posedge rst)

begin

                                                                 if(rst)

                                                                                    state_reg <= idle;

                                                                 else

                                                                                    state_reg <= state_next;

end

//Next State Logic

always @*

begin

                                                                 case(state_reg)

                                                                                    idle:

                                                                                    if(start)

                                                                                                state_next = lcd_init;

                                                                                    else

                                                                                                state_next = idle;

                                                                                    lcd_init:

                                                                                    if(addr_reg == 5’h03 && cnt_reg == 3550000)

                                                                                                state_next = lcd_print;

                                                                                    else

                                                                                                state_next = lcd_init;

                                                                                    lcd_print:

                                                                                    if(addr_reg == 5’h19 && cnt_reg == 3550000)

                                                                                                state_next = idle;

                                                                                    else

                                                                                                state_next = lcd_print;

                                                                                     default:

                                                                                                state_next = idle;

                                                                                    endcase

end

//Output Logic

always @*

begin

                                                                                    case(state_reg)

                                                                                    idle:

                                                                                                begin

                                                                                                s1 = 2’b10;

                                                                                                s2 = 2’b10;

                                                                                                RW = 0;

                                                                                                RS = 0;

                                                                                                E = 0;

                                                                                                end

                                                                                    lcd_init:

                                                                                                begin

                                                                                                s1 = 2’b00;

                                                                                                s2 = 2’b01;

                                                                                                RS = 0;

                                                                                                RW = 0;

                                                                                                E = 0;

                                                                                                if (cnt_reg >= 500000)

                                                                                                            E = 1;

                                                                                                if (cnt_reg >= 3400000)

                                                                                                            E = 0;

                                                                                                if (cnt_reg == 3550000)

                                                                                                begin

                                                                                                            s1 = 2’b01;

                                                                                                            s2 = 2’b10;

                                                                                                end

                                                                                                end

                                                                                    lcd_print:

                                                                                                begin

                                                                                                s1 = 2’b00;

                                                                                                s2 = 2’b01;

                                                                                                RS = 1;

                                                                                                RW = 0;

                                                                                                E = 0;

                                                                                                if (cnt_reg >= 500000)

                                                                                                            E = 1;

                                                                                                if (cnt_reg >= 3400000)

                                                                                                            E = 0;

                                                                                                if (cnt_reg == 3550000)

                                                                                                begin

                                                                                                            s1 = 2’b01;

                                                                                                            s2 = 2’b10;

                                                                                                end

                                                                                                end

                                                                                    default:

                                                                                                begin

                                                                                                s1 = 2’b10;

                                                                                                s2 = 2’b10;

                                                                                                RW = 0;

                                                                                                RS = 0;

                                                                                                E = 0;

                                                                                                end

                                                                                    endcase

end

//Path 1: ROM

wire [7:0] rom_data [19:0];

  assign rom_data[0] = 8’h38;

  assign rom_data[1] = 8’h06;

  assign rom_data[2] = 8’h0C;

  assign rom_data[3] = 8’h01;

  assign rom_data[4] = ” “;

  assign rom_data[5] = ” “;

  assign rom_data[6] = “H”;

  assign rom_data[7] = “E”;

  assign rom_data[8] = “L”;

  assign rom_data[9] = “L”;

  assign rom_data[10] = “O”;

  assign rom_data[11] = ” “;

  assign rom_data[12] = “W”;

  assign rom_data[13] = “O”;

  assign rom_data[14] = “R”;

  assign rom_data[15] = “L”;

  assign rom_data[16] = “D”;

  assign rom_data[17] = “!”;

  assign rom_data[18] = ” “;

  assign rom_data[19] = ” “;

  assign data = rom_data[addr_reg];

//Path 1: Registers

[email protected](posedge clk, posedge rst)

begin

                                                                 if(rst)

                                                                                    addr_reg <= 5’b0;

                                                                 else

                                                                                    addr_reg <= addr_next;

end

//Path 1: Mux

always @*

                                                                 case(s1)

                                                                                    ۲’b00:

                                                                                    addr_next = addr_reg;

                                                                                    ۲’b01:

                                                                                    addr_next = addr_reg + 1’b1;

                                                                                    ۲’b10:

                                                                                    addr_next = 5’b0;

                                                                                    default:

                                                                                    addr_next = addr_reg;

                                                                 endcase

//Path 2: Registers

[email protected](posedge clk, posedge rst)

begin

                                                                 if(rst)

                                                                                    cnt_reg <= 21’h0;

                                                                 else

                                                                                    cnt_reg <= cnt_next;

end

//Path 2: Mux

always @*

                                                                 case(s2)

                                                                                    ۲’b00:

                                                                                    cnt_next = cnt_reg;

                                                                                    ۲’b01:

                                                                                    cnt_next = cnt_reg + 1’b1;

                                                                                    ۲’b10:

                                                                                    cnt_next = 21’h0;

                                                                                    default:

                                                                                    cnt_next = cnt_reg;

                                                                 endcase

endmodule

شماتیک و پرونده UCF

شکل ۹ اتصالات بین Mojo  و ماژول LCD را نشان می دهد.

 

شکل ۹

حال می توان محدودیت های جدیدی را، به محدودیت تعریف شده توسط کاربر (UCF) پروژه Mojo Base اضافه کرد تا پین های FPGA را که به ورودی ها یا خروجی های ماژول سطح بالا متصل هستند ، مشخص کنیم. چندین خط اول در پرونده UCF زیر در پروژه Mojo Base گنجانده شده است. با این وجود ، ۱۲ خط آخر پین های FPGA متصل به سیگنال های DB7-DB0 ، start ، RS ، RW و E را در این کد مشخص می کنند.

#Created by Constraints Editor (xc6slx9-tqg144-3) – 2012/11/05

NET “clk” TNM_NET = clk;

TIMESPEC TS_clk = PERIOD “clk” 50 MHz HIGH 50%;

# PlanAhead Generated physical constraints

NET “clk” LOC = P56 | IOSTANDARD = LVTTL;

NET “rst_n” LOC = P38 | IOSTANDARD = LVTTL;

NET “cclk” LOC = P70 | IOSTANDARD = LVTTL;

NET “led<0>” LOC = P134 | IOSTANDARD = LVTTL;

NET “led<1>” LOC = P133 | IOSTANDARD = LVTTL;

NET “led<2>” LOC = P132 | IOSTANDARD = LVTTL;

NET “led<3>” LOC = P131 | IOSTANDARD = LVTTL;

NET “led<4>” LOC = P127 | IOSTANDARD = LVTTL;

NET “led<5>” LOC = P126 | IOSTANDARD = LVTTL;

NET “led<6>” LOC = P124 | IOSTANDARD = LVTTL;

NET “led<7>” LOC = P123 | IOSTANDARD = LVTTL;

NET “spi_mosi” LOC = P44 | IOSTANDARD = LVTTL;

NET “spi_miso” LOC = P45 | IOSTANDARD = LVTTL;

NET “spi_ss” LOC = P48 | IOSTANDARD = LVTTL;

NET “spi_sck” LOC = P43 | IOSTANDARD = LVTTL;

NET “spi_channel<0>” LOC = P46 | IOSTANDARD = LVTTL;

NET “spi_channel<1>” LOC = P61 | IOSTANDARD = LVTTL;

NET “spi_channel<2>” LOC = P62 | IOSTANDARD = LVTTL;

NET “spi_channel<3>” LOC = P65 | IOSTANDARD = LVTTL;

NET “avr_tx” LOC = P55 | IOSTANDARD = LVTTL;

NET “avr_rx” LOC = P59 | IOSTANDARD = LVTTL;

NET “avr_rx_busy” LOC = P39 | IOSTANDARD = LVTTL;

#My Constraints

NET “start” LOC = P1 | IOSTANDARD = LVTTL;

NET “RS” LOC = P5 | IOSTANDARD = LVTTL;

NET “RW” LOC = P7 | IOSTANDARD = LVTTL;

NET “E” LOC = P9 | IOSTANDARD = LVTTL;

NET “data<0>” LOC = P11 | IOSTANDARD = LVTTL;

NET “data<1>” LOC = P14 | IOSTANDARD = LVTTL;

NET “data<2>” LOC = P16 | IOSTANDARD = LVTTL;

NET “data<3>” LOC = P21 | IOSTANDARD = LVTTL;

NET “data<4>” LOC = P23 | IOSTANDARD = LVTTL;

NET “data<5>” LOC = P26 | IOSTANDARD = LVTTL;

NET “data<6>” LOC = P29 | IOSTANDARD = LVTTL;

NET “data<7>” LOC = P32 | IOSTANDARD = LVTTL;

نتیجه

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

در این پروژه ، ما بلوک های ساختمان مورد استفاده برای رابط FPGA با یک ماژول LCD 16×2 مشترک را مورد بررسی قرار داده ایم. برای اجرای رابط FPGA-LCD ، یک رام ، برخی DFF ها و مالتی پلکسرها لازم است. علاوه بر این ، ما برای کنترل بلوک های ساختمان نیاز به یک FSM داریم. ما به جزئیات طراحی FSM پرداختیم و توضیحات Verilog را برای بلوک های ساختمانی مختلف طراحی پیدا کردیم. سرانجام ، ما کد خود را در صفحه Mojo V3 بارگذاری کردیم و “” HELLO WORLD! پیام بر روی LCD.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *