Working with C/C++
This chapter contains the following sections. Please read as needed:
Setting Up Development Environment
Please refer to the Install and Configure Pico C/C++ Development Environment Tutorial to download and install the Pico VSCode.
Example
The C/C++ examples are located in the examples\C directory of the example package.
| Example | Basic Program Description | Dependency Library |
|---|---|---|
| 01_FatFs | FAT file system, TF card supports SPI/SDIO communication | - |
| 02_ES8311 | Development board audio test program | - |
| 03_GUI | LCD GUI display program | - |
| 04_LVGL | LCD LVGL display program | LVGL V8.4 |
| 05_WS2812 | WS2812 LED cycle display | - |
01_FatFs
Example Description
- Uses SPI or PIO-emulated SDIO to communicate with the TF card, implementing a command-line interface similar to busybox or DOS.
Hardware Connection
- Insert a TF card
- Connect the board to the computer using a USB cable
Code Analysis
sd_init_driver(): Initializes the TF card driver.getchar_timeout_us(): Gets UART input.process_stdio(): Processes UART input.
Operation Result
-
Use a terminal tool like putty or mobaxterm to open the corresponding USB serial port of the development board.
-
Press the Enter key to start the command-line interface (CLI). You should see a prompt similar to this:
> -
Enter help command to get the available commands as follows
> helpsetrtc <DD> <MM> <YY> <hh> <mm> <ss>:Set Real Time ClockParameters: new date (DD MM YY) new time in 24-hour format (hh mm ss)e.g.:setrtc 16 3 21 0 4 0date:Print current date and timelliot <drive#>:!DESTRUCTIVE! Low Level I/O Driver Teste.g.: lliot 1format [<drive#:>]:Creates an FAT/exFAT volume on the logical drive.e.g.: format 0:mount [<drive#:>]:Register the work area of the volumee.g.: mount 0:unmount <drive#:>:Unregister the work area of the volumechdrive <drive#:>:Changes the current directory of the logical drive.<path> Specifies the directory to be set as current directory.e.g.: chdrive 1:getfree [<drive#:>]:Print the free space on drivecd <path>:Changes the current directory of the logical drive.<path> Specifies the directory to be set as current directory.e.g.: cd 1:/dir1mkdir <path>:Make a new directory.<path> Specifies the name of the directory to be created.e.g.: mkdir /dir1ls:List directorycat <filename>:Type file contentssimple:Run simple FS testsbig_file_test <pathname> <size in bytes> <seed>:Writes random data to file <pathname>.<size in bytes> must be multiple of 512.e.g.: big_file_test bf 1048576 1or: big_file_test big3G-3 0xC0000000 3cdef:Create Disk and Example FilesExpects card to be already formatted and mountedstart_logger:Start Data Log Demostop_logger:Stop Data Log Demo
02_ES8311
Example Description
- Uses PIO-emulated I2S to communicate with ES8311, enabling audio input and output.
Hardware Connection
- Connect the speaker
- Connect the board to the computer using a USB cable
Code Analysis
Es8311_Init(): Initializes ES8311.Es8311_Sample_Frequency_Config(): Configures sampling rate.Es8311_Microphone_Config(): Configures the microphone.Es8311_Microphone_Gain_Set(): Sets microphone gain.Es8311_Voice_Volume_Set(): Sets volume.Sine_440hz_Out(): Outputs a 440 Hz sine wave.Happy_Birthday_Out(): Outputs a 440 Hz sine wave.Loopback_Test(): Audio recording and playback test.Music_Out(): Plays music.
Operation Result
- Use VS Code to import and compile the 02_ES8311 project. After compilation is complete, flash the uf2 file in the
builddirectory, or directly flash the uf2 file in the02_ES8311\uf2directory for quick verification.
03_GUI
Example Description
- Uses SPI to communicate with the LCD and implements functions like displaying text and images via GUI.
Hardware Connection
- Connect the board to the computer using a USB cable
Code Analysis
Underlying Hardware Interface
We have encapsulated the hardware operations at a low level. Due to differences in hardware platforms, the internal implementations vary. If you need to understand the internal implementation, you can check the corresponding directory. Many definitions can be seen in DEV_Config.c(.h) under the directory: lib\Config.
-
Module initialization and exit handling
void DEV_Module_Init(void);void DEV_Module_Exit(void);tipThis handles GPIO operations before using the LCD and after finishing use.
-
GPIO read/write
void DEV_Digital_Write(uint_16 Pin, uint_8 Value);uint_8 DEV_Digital_Read(uint_16 Pin); -
SPI write data
void DEV_SPI_WriteByte(uint_8 Value);
Upper Layer Applications
For the screen, what if you need to paint, display Chinese and English characters, display pictures, etc., these are all done by the upper layer applications. Many users have asked about graphical processing. We provide some basic functionalities in the GUI, located in the directory: lib\GUI\GUI_Paint.c(.h).
The character fonts that the GUI depends on are located in the directory: lib\Fonts.
-
Create Image Attribute: Create a new image attribute, which includes the name, width, height, rotation angle, and color of the image cache.
void Paint_NewImage(uint16_t *image, uint16_t Width, uint16_t Height, uint16_t Rotate, uint16_t Color)Parameters:image: The name of the image cache, which is essentially a pointer to the starting address of the image cache;Width: The width of the image cache;Height: The height of image cache;Rotate: The rotation angle of the image;Color: The initial color of the image; -
Select Image Cache: Selects an image cache. The purpose of this selection is to allow you to create multiple image attributes. Since multiple image caches can exist, you can select each image you have created.
void Paint_SelectImage(uint8_t *image)Parameters:image: The name of the image cache, which is essentially a pointer to the starting address of the image cache; -
Image Rotation: Set the rotation angle for the selected image. It is best to use this after
Paint_SelectImage(). You can choose rotation angles of 0, 90, 180, or 270 degrees.void Paint_SetRotate(uint16_t Rotate)Parameters:Rotate: The image rotation angle. You can choose ROTATE_0, ROTATE_90, ROTATE_180, ROTATE_270 corresponding to 0, 90, 180, 270 degrees respectively.tipThe starting pixel for coordinates differs under different rotation angles. Taking 1.14 as an example, the four images correspond to 0°, 90°, 180°, and 270° in order. This is for reference only.

-
Image Mirroring: Set mirroring for the selected image. You can choose no mirroring, horizontal mirroring, vertical mirroring, or mirroring about the image center.
void Paint_SetMirroring(uint8_t mirror)Parameters:mirror: The mirroring method for the image. You can choose MIRROR_NONE, MIRROR_HORIZONTAL, MIRROR_VERTICAL, MIRROR_ORIGIN corresponding to no mirroring, horizontal mirroring, vertical mirroring, and mirroring about the image center respectively. -
Set Pixel Display Position and Color in Cache: This is one of the core GUI functions, handling the display position and color of a pixel within the cache.
void Paint_SetPixel(uint16_t Xpoint, uint16_t Ypoint, uint16_t Color)Parameters:Xpoint: The X-coordinate of the point within the image cache;Ypoint: The Y-coordinate of the point within the image cache;Color: The display color of the point; -
Fill Image Cache with Color: Fills the image cache with a specific color, typically used to clear the screen to white.
void Paint_Clear(uint16_t Color)Parameters:Color: The filled color -
Fill Partial Window in Image Cache with Color: Fill a specific window area within the image cache with a color, often used to clear a window to white, such as when updating time displays to clear the previous second.
void Paint_ClearWindows(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend, uint16_t Color)Parameters:Xstart: The X starting coordinate of the window;Ystart: The Y starting coordinate of the window;Xend: The X ending coordinate of the window;Yend: The Y ending coordinate of the window;Color: The filled color -
Draw Dot: Draw a dot at (Xpoint, Ypoint) in the image cache. You can choose the color, the size, and the style of the dot.
void Paint_DrawPoint(uint16_t Xpoint, uint16_t Ypoint, uint16_t Color, DOT_PIXEL Dot_Pixel, DOT_STYLE Dot_Style)Parameters:Xpoint: The X-coordinate of the dot;Ypoint: The Y-coordinate of the dot;Color: The filled colorDot_Pixel: The size of the dot, with 8 default sizes provided:typedef enum {DOT_PIXEL_1X1 = 1, // 1 x 1DOT_PIXEL_2X2 , // 2 X 2DOT_PIXEL_3X3 , // 3 X 3DOT_PIXEL_4X4 , // 4 X 4DOT_PIXEL_5X5 , // 5 X 5DOT_PIXEL_6X6 , // 6 X 6DOT_PIXEL_7X7 , // 7 X 7DOT_PIXEL_8X8 , // 8 X 8} DOT_PIXEL;Dot_Style: The style of the dot, defining the method to expand the size of the dot is that, whether to expand from the dot as the center or from the dot as the lower left corner to the upper right.typedef enum {DOT_FILL_AROUND = 1,DOT_FILL_RIGHTUP,} DOT_STYLE; -
Draw Line: Draw a line from (Xstart, Ystart) to (Xend, Yend) in the image cache. You can select the color, line width, and line style.
void Paint_DrawLine(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend, uint16_t Color, LINE_STYLE Line_Style , LINE_STYLE Line_Style)Parameters:Xstart: The X starting coordinate of the line;Ystart: The Y starting coordinate of the line;Xend: The X ending coordinate of the line;Yend: The Y ending coordinate of the line;Color: The filled colorLine_width: The width of the line, with 8 default widths provided:typedef enum {DOT_PIXEL_1X1 = 1, // 1 x 1DOT_PIXEL_2X2 , // 2 X 2DOT_PIXEL_3X3 , // 3 X 3DOT_PIXEL_4X4 , // 4 X 4DOT_PIXEL_5X5 , // 5 X 5DOT_PIXEL_6X6 , // 6 X 6DOT_PIXEL_7X7 , // 7 X 7DOT_PIXEL_8X8 , // 8 X 8} DOT_PIXEL;Line_Style: The line style, choosing between solid line connection or dotted line connectiontypedef enum {LINE_STYLE_SOLID = 0,LINE_STYLE_DOTTED,} LINE_STYLE; -
Draw Rectangle: Draw a rectangle from (Xstart, Ystart) to (Xend, Yend) in the image cache. You can select the color, line width, and whether to fill the interior of the rectangle.
void Paint_DrawRectangle(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend, uint16_t Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill)Parameters:Xstart: The X starting coordinate of the rectangle;Ystart: The Y starting coordinate of the rectangle;Xend: The X ending coordinate of the rectangle;Yend: The Y ending coordinate of the rectangle;Color: The filled colorLine_width: The width of the rectangle's four sides, with 8 default widths provided:typedef enum {DOT_PIXEL_1X1 = 1, // 1 x 1DOT_PIXEL_2X2 , // 2 X 2DOT_PIXEL_3X3 , // 3 X 3DOT_PIXEL_4X4 , // 4 X 4DOT_PIXEL_5X5 , // 5 X 5DOT_PIXEL_6X6 , // 6 X 6DOT_PIXEL_7X7 , // 7 X 7DOT_PIXEL_8X8 , // 8 X 8} DOT_PIXEL;Draw_Fill: Fill option, determining whether to fill the interior of the rectangle:typedef enum {DRAW_FILL_EMPTY = 0,DRAW_FILL_FULL,} DRAW_FILL; -
Draw Circle: Draw a circle with center at (X_Center, Y_Center) and a radius of Radius in the image cache, and you can choose the color. You can select the color, line width, and whether to fill the interior of the circle.
void Paint_DrawCircle(uint16_t X_Center, uint16_t Y_Center, uint16_t Radius, uint16_t Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill)Parameters:X_Center: The X-coordinate of the circle's center;Y_Center: The Y-coordinate of the circle's center;Radius: The radius of the circle;Color: The filled colorLine_width: The width of the circle's arc, with 8 default widths provided:typedef enum {DOT_PIXEL_1X1 = 1, // 1 x 1DOT_PIXEL_2X2 , // 2 X 2DOT_PIXEL_3X3 , // 3 X 3DOT_PIXEL_4X4 , // 4 X 4DOT_PIXEL_5X5 , // 5 X 5DOT_PIXEL_6X6 , // 6 X 6DOT_PIXEL_7X7 , // 7 X 7DOT_PIXEL_8X8 , // 8 X 8} DOT_PIXEL;Draw_Fill: Fill option, determining whether to fill the interior of the circle:typedef enum {DRAW_FILL_EMPTY = 0,DRAW_FILL_FULL,} DRAW_FILL; -
Draw Ascii Character: Draw an Ascii character in the image cache with (Xstart, Ystart) as the top-left vertex. You can select the Ascii visible character font, foreground color, and background color.
void Paint_DrawChar(uint16_t Xstart, uint16_t Ystart, const uint8_t Ascii_Char, sFONT* Font, uint16_t Color_Foreground, uint16_t Color_Background)Parameters:Xstart: The X-coordinate of the number's top-left vertex;Ystart: The Y-coordinate of the number's top-left vertex;Ascii_Char: The Ascii character;Font: The Ascii visible character font. The following fonts are provided in the Fonts folder:font8: 5*8 fontfont12: 7*12 fontfont16: 11*16 fontfont20: 14*20 fontfont24: 17*24 fontColor_Foreground: The font color;Color_Background: The background color; -
Draw English String: Draw a string of English characters in the image cache with (Xstart, Ystart) as the top-left vertex. You can select the Ascii visible character font, foreground color, and background color.
void Paint_DrawString_EN(uint16_t Xstart, uint16_t Ystart, const uint8_t * pString, sFONT* Font, uint16_t Color_Foreground, uint16_t Color_Background)Parameters:Xstart: The X-coordinate of the number's top-left vertex;Ystart: The Y-coordinate of the number's top-left vertex;pString: The string, which is a pointer;Font: The Ascii visible character font. The following fonts are provided in the Fonts folder:font8: 5*8 fontfont12: 7*12 fontfont16: 11*16 fontfont20: 14*20 fontfont24: 17*24 fontColor_Foreground: The font color;Color_Background: The background color; -
Draw Chinese String: Draw a string of Chinese characters in the image cache with (Xstart, Ystart) as the top-left vertex. You can select the GB2312 encoded character font, foreground color, and background color.
void Paint_DrawString_CN(uint16_t Xstart, uint16_t Ystart, const uint8_t * pString, cFONT* font, uint16_t Color_Foreground, uint16_t Color_Background)Parameters:Xstart: The X-coordinate of the number's top-left vertex;Ystart: The Y-coordinate of the number's top-left vertex;pString: The string, which is a pointer;Font: The GB2312 encoded character font. The following fonts are provided in the Fonts folder:font12CN: Ascii character 11*21 font, Chinese 16*21 fontfont24CN: Ascii character 24*41 font, Chinese 32*41 fontColor_Foreground: The font color;Color_Background: The background color; -
Draw Number: Draw a number string in the image cache with (Xstart, Ystart) as the top-left vertex. You can select the Ascii visible character font, foreground color, background color, and decimal places.
void Paint_DrawNum(uint16_t Xpoint, uint16_t Ypoint, uint32_t Nummber, sFONT* Font, uint16_t Digit,uint16_t Color_Foreground, uint16_t Color_Background);Parameters:Xstart: The X-coordinate of the number's top-left vertex;Ystart: The Y-coordinate of the number's top-left vertex;Number: The displayed number, here is stored in a 32-bit long int type, which can be displayed up to 2147483647.Font: The Ascii visible character font. The following fonts are provided in the Fonts folder:font8: 5*8 fontfont12: 7*12 fontfont16: 11*16 fontfont20: 14*20 fontfont24: 17*24 fontDigit: The number of decimal places to displayColor_Foreground: The font color;Color_Background: The background color; -
Display Time: Display a time period in the image cache with (Xstart, Ystart) as the top-left vertex. You can select the Ascii visible character font, foreground color, and background color.
void Paint_DrawTime(uint16_t Xstart, uint16_t Ystart, PAINT_TIME *pTime, sFONT* Font, uint16_t Color_Background, uint16_t Color_Foreground)Parameters:Xstart: The X-coordinate of the number's top-left vertex;Ystart: The Y-coordinate of the number's top-left vertex;pTime: The time to display, using a predefined time structure; simply pass the hour, minute, and second digits to the parameters;Font: The Ascii visible character font. The following fonts are provided in the Fonts folder:font8: 5*8 fontfont12: 7*12 fontfont16: 11*16 fontfont20: 14*20 fontfont24: 17*24 fontColor_Foreground: The font color;Color_Background: The background color;
Operation Result
- Import and compile the 03_GUI project using VS Code. After compilation, flash the .uf2 file from the
builddirectory, or directly flash 03_GUI.uf2 from thefirmware\Cdirectory for quick verification.
04_LVGL
Example Description
- Uses SPI to communicate with the LCD and implements functions like displaying text and images via LVGL.
Hardware Connection
- Connect the board to the computer using a USB cable
Code Analysis
Source Code Structure
-
The source code of the LVGL library is located in
lib\lvglof the project folder, version 8.4. For secondary development, please refer to the corresponding version's development documentation. -
LVGL library related settings are in
examples\inc\lv_conf.hof the project folder, where you can set display refresh rate, system data usage, etc. -
The application code for the LVGL library is located in
main.c,lv_port\lv_port_disp.c, andlv_port\lv_port_indev.cin the project folder.
LVGL Initialization
Before using the LVGL graphics library, you need to initialize LVGL.
-
LVGL Library Initialization Function
Code location:
main.cFunction: Mainly used to initialize the hardware and structure variables required by LVGL.
LVGL_Init(); -
LVGL Core Initialization
Code location:
main.c/*2.Init LVGL core*/lv_init();
LVGL Run
The LVGL library periodically calls the heartbeat interface function lv_tick_inc to notify LVGL of the elapsed time, allowing LVGL to update its internal time state and handle time-related tasks such as animations, timers, and more. In the main function loop, the lv_task_handler function must also be called so that LVGL can process events and tasks in a timely manner, ensuring the responsiveness and refresh of the user interface.
-
LVGL heartbeat interface
Code location:
main.cImplementation: Ensure the priority of
lv_task_handleris lower than that oflv_tick_inc. In this example,lv_tick_incis called in the timer callback function.//Timer callback function is called every 5msadd_repeating_timer_ms(5, repeating_lvgl_timer_callback, NULL, &lvgl_timer);static bool repeating_lvgl_timer_callback(struct repeating_timer *t){lv_tick_inc(5);return true;} -
LVGL task handler
Location:
examples\src\LCD_XinXX_LVGL_test.cImplementation: To handle LVGL tasks,
lv_timer_handler()needs to be called periodically. In this example, it's called in the main function loop.int main(){...while (1){lv_task_handler();DEV_Delay_ms(5);...}}
LVGL Display
To enable LVGL display, a display driver must be initialized and its various properties configured, such as color format, draw buffer, rendering mode, and display callback function. At each LV_DISP_DEF_REFR_PERIOD (set in lv_conf.h), LVGL detects if something has happened on the UI that needs to be redrawn. For example, a button is pressed, a chart is changed, an animation occurs, etc. When redrawing is needed, LVGL calls the display callback function to complete the drawing of the image in the refresh area.
-
LVGL Display Refresh Rate Setting
Location:
examples\inc\lv_conf.hSetting: You can also set the refresh period time for the display buffer in
lv_conf.h. Modify this definition to change the screen refresh time.#define LV_DISP_DEF_REFR_PERIOD 10 // Unit: ms, here is 10ms -
LVGL Display Color Setting
Location:
examples\inc\lv_conf.hPurpose: Since the pixel color storage method constructed by the
lv_color_tstructure by default is inconsistent with the data format required for transmission in this example, direct transmission would cause color differences in the displayed image.#define LV_COLOR_16_SWAP 1 -
LVGL display-related variable definitions
Code location:
lv_port\lv_port_disp.cFunction: Defines the display driver
disp_drvand the draw bufferdisp_buf. In this example, the draw bufferbuf0is set to the entire screen display area, which effectively improves the screen refresh rate while reducing aliasing during large-area screen refreshes.static lv_disp_drv_t disp_drv;static lv_disp_draw_buf_t disp_buf;static lv_color_t *buf0; -
LVGL display device registration
Code location:
lv_port\lv_port_disp.cFunction: according to design requirements, complete the core structure variables of the LVGL library, initialize the display driver
disp_drv, and set the draw buffers. The draw buffers are simple arrays used by LVGL to render screen content. Once rendering is ready, the content of the draw buffer is sent to the display using thedisp_drv_flush_cbfunction set in the display driver.lv_disp_draw_buf_init(&draw_buf_dsc_1, buf_1, buf_2, MY_DISP_HOR_RES * MY_DISP_VER_RES * 2); /*Initialize the display buffer*/lv_disp_drv_init(&disp_drv); /*Basic initialization*//*Set up the functions to access to your display*//*Set the resolution of the display*/disp_drv.hor_res = MY_DISP_HOR_RES;disp_drv.ver_res = MY_DISP_VER_RES;/*Used to copy the buffer's content to the display*/disp_drv.flush_cb = disp_flush;disp_drv.user_data = NULL;/*Set a display buffer*/disp_drv.draw_buf = &draw_buf_dsc_1;/*Required for Example 3)*/#if 1disp_drv.full_refresh = 1;#endif/*Finally register the driver*/lv_disp_drv_register(&disp_drv); -
LVGL display callback function
Code location:
lv_port\lv_port_disp.cFunction: mainly completes the drawing of the image in the refresh area.
void disp_flush( lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p )Parameters:lv_disp_drv_t *disp_drv: Displays driver structure pointers, which contain information about the display and function pointers. This parameter is often used to notify you that the refresh is completeconst lv_area_t *area : Region structure pointer, containing the position information of the area to be refreshed. In this example, you can use it for creating TFT display window.lv_color_t *color_p : Color structure pointer, indicating the color data to be displayed in the refresh area. In this example, it reads the address as DMA input to transmit data to the SPI bus and completes the image drawing -
LVGL display callback function implementation
Code location:
lv_port\lv_port_disp.cstatic void disp_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_p){UWORD *image_data = (UWORD *)color_p;#if 1LCD_0IN85_Display(image_data);#elseLCD_0IN85_DisplayWindows(area->x1,area->y1,area->x2,area->y2,image_data);#endiflv_disp_flush_ready(drv);} -
LVGL Refresh Completion Notification Implementation
Code location:
lv_port\lv_port_disp.cFunction: After each image refresh is complete, the LVGL core needs to be notified so that LVGL can prepare to render the next refresh image.
lv_disp_flush_ready(drv);
LVGL Input
In LVGL, users can register input devices such as touchpads, mice, keyboards, or encoders, etc. Users can control the user interface through these input devices to achieve better interaction.
-
Frequency of calling the input device callback in LVGL
Location:
examples\inc\lv_conf.hSetting: LVGL calls the input device callback function every 30ms by default to update events triggered by the input device. This can be set in
lv_conf.h.#define LV_INDEV_DEF_READ_PERIOD 30 // Unit: ms, here is 30ms -
LVGL input device registration
Code location:
lv_port\lv_port_indev.cSetting method: Define the keypad device
indev_drvand initialize it.void lv_port_indev_init(void){static lv_indev_drv_t indev_drv;keypad_init();lv_indev_drv_init(&indev_drv);indev_drv.type = LV_INDEV_TYPE_KEYPAD;indev_drv.read_cb = keypad_read;indev_keypad = lv_indev_drv_register(&indev_drv);} -
LVGL input device callback function
Code location:
lv_port\lv_port_indev.cFunction: mainly used to update input events.
static void keypad_read(lv_indev_drv_t * drv, lv_indev_data_t*data);Parameters:lv_indev_drv_t *indev_drv: Pointer to the input device driver structure in LVGL. In this example, this structure serves as the keypad input device driver.lv_indev_data_t *data : Pointer to the input device data structure in LVGL. In this example, this structure is used to store the status and data of the input device, including the current keypad state (pressed or released).
LVGL Widget Layout
In LVGL, we can create various user interfaces. The basic components of the interface are objects, also called widgets, such as buttons, labels, images, lists, charts, or text areas. In a interface, we can create multiple widgets simultaneously and set their positions, sizes, parent objects, styles, and event handlers and other basic properties.
-
Alignment and positioning of LVGL widgets
Code location:
main.cFunction: allows a widget to be offset‑positioned relative to a reference point. The reference point for alignment offset is the center of the widget.
Alignment standard: LVGL supports both internal and external alignment. By default, the upper-left corner is the origin, the leftward as the positive horizontal direction, and the downward as the positive vertical direction.
//Position the btn widget at the center point, offset 45 pixels to the leftlv_obj_align(sw, LV_ALIGN_CENTER, -45, 0); -
Changing font size in LVGL widgets
Code location:
examples\inc\lv_conf.h,main.cFunction: in practice, a screen may need multiple font sizes. You can enable multiple font sizes in
lv_conf.hand set the default font size. To set the font size, you need to style the widget so that it renders according to the set style. Using thelv_obj_add_stylefunction, different parts of the widget can be rendered in different states.#define LV_FONT_MONTSERRAT_16 1 // Enable 16pt font#define LV_FONT_MONTSERRAT_18 1 // Enable font 18#define LV_FONT_DEFAULT &lv_font_montserrat_18 // Set the default font size as 18static lv_style_t style_label;lv_style_init(&style_label); // Initialize stylelv_style_set_text_font(&style_label, &lv_font_montserrat_16); // Set font size to 16ptlv_obj_add_style(label,&style_label,0); // Set label theme style -
LVGL widget event handling
Code location:
main.cFunction: in LVGL, you can add event callback functions to widgets so that when events such as clicking, scrolling, or redrawing occur, the event triggers and the callback function is executed. In the program, call the
lv_obj_add_event_cb(obj, event_cb, filter, user_data)function to add the event handlerevent_cbfor the eventfilterto the widgetobj. When the widgetobjtriggers thefilterevent, the system automatically calls theevent_cbfunction. The last parameter is a pointer to any custom data available in the event.//Add an event handler sw_event_cb for the LV_EVENT_VALUE_CHANGED event to the sw widgetlv_obj_add_event_cb(sw, sw_event_cb,LV_EVENT_VALUE_CHANGED,NULL);
Operation Result
-
Import and compile the 04_LVGL project using VS Code. After compilation, flash the .uf2 file from the
builddirectory, or directly flash 04_LVGL.uf2 file from thefirmware\Cdirectory for quick verification.
05_WS2812
Example Description
- Uses PIO‑emulated WS2812 signaling to cycle colors on RGB LEDs.
Hardware Connection
- Connect the board to the computer using a USB cable
Code Analysis
WS2812_init();: Initializes WS2812.WS2812_show2(r, g, b): Sends color data and lights the LED.
Operation Result
-
Import and compile the 05_WS2812 project using VS Code. After compilation, flash the .uf2 file from the
builddirectory, or directly flash 05_WS2812.uf2 file from thefirmware\Cdirectory for quick verification.