摘要:支持顯示控制器,,,,,,,,,,,,,,,,,,,,,,等。和的功能包括包括所有圖形程序線框圓畫。支持很豐富的字體庫。僅文本輸出字符設(shè)備。僅允許使用每個字符固定大小像素的字體。直接寫到顯示屏上,無需微控制器中的緩沖需要消耗較少的空間資源。
1.U8g2 是用于嵌入式設(shè)備的單色圖形庫。
2.U8g2 還包括 U8x8 庫。U8g2 和 U8x8 的功能包括:
U8g2圖形庫使用技巧(硬件驅(qū)動接口部分的分析和選擇):
? ? ? ? U8g2圖形庫的驅(qū)動接口主要取決于所選用的lcd屏幕的驅(qū)動芯片方案,目前常用的驅(qū)動接口多為spi和i2c兩種串行總線,如果需要較高的刷新幀率,spi的驅(qū)動方式是比較好的選擇,spi的驅(qū)動時鐘頻率一般可以達到8Mbit,而i2c的方式一般只能達到400Kbit,但是使用spi方式驅(qū)動的時候,需要比較多的io管腳資源,一般最少需要3個io(三線spi方式),而i2c方式一般只需要2個io就可以滿足,考慮到~~呆萌的瓦力平衡機器人~~包含了兩路對時序要求很高的foc電機控制,所以果斷選擇了比較高效的spi方式(選用的oled模組的驅(qū)動方案采用的是SSD1306,該方案既支持i2c方式,也支持spi的方式);
?U8g2圖形庫使用技巧(軟件驅(qū)動程序分析和記錄):
? ? ? ? U8g2圖形庫的代碼框架寫得非常的完善,只需要實現(xiàn)底層幾個讀寫接口函數(shù),就可以把整個圖形庫驅(qū)動起來,它的幾乎所有的初始化函數(shù)接口都定義在u8g2_d_setup.c源文件中,該源文件實現(xiàn)了u8g2圖形庫所有支持lcd驅(qū)動方案的初始化方法,通過函數(shù)名來區(qū)分,初始化函數(shù)的名字包含了很多硬件相關(guān)的信息,就拿我在使用的oled模組的初始化函數(shù)來作為例子,模組驅(qū)動方案為SSD1306,分辨率為128x64,驅(qū)動接口為三線spi方式,所以可選的初始化方法如下:
u8g2_Setup_ssd1306_128x64_noname_1 /*芯片SSD1306,分辨率128x64,128字節(jié)頁大小*/u8g2_Setup_ssd1306_128x64_noname_2 /*芯片SSD1306,分辨率128x64,256字節(jié)頁大小*/u8g2_Setup_ssd1306_128x64_noname_f /*芯片SSD1306,分辨率128x64,1024字節(jié)頁大小*/
?考慮到esp32的ram資源比較充足的,果斷選擇了u8g2_Setup_ssd1306_128x64_noname_f方法,到這里了就結(jié)束了!spi的驅(qū)動方式體現(xiàn)在哪里呢?
接著往里扒--->
void u8g2_Setup_ssd1306_i2c_128x64_noname_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
該函數(shù)需要傳入四個參數(shù)--->
u8g2_t *u8g2; /*u8g2圖形庫結(jié)構(gòu)體指針*/const u8g2_cb_t *rotation; /*u8g2圖形庫ui旋轉(zhuǎn):U8G2_R0(無旋轉(zhuǎn)),U8G2_R1(順時針90°),U8G2_R2(順時針180°)......*/u8x8_msg_cb byte_cb; /*u8g2圖形庫字節(jié)交互回調(diào)函數(shù)*/u8x8_msg_cb gpio_and_delay_cb; /*u8g2圖形庫gpio和延時回調(diào)函數(shù)*/
所以和spi部分相關(guān)的就是--->
u8x8_msg_cb byte_cb; /*u8g2圖形庫字節(jié)交互回調(diào)函數(shù)*/
這個callback函數(shù)需要我們自己實現(xiàn)如下的方法--->
uint8_t u8x8_byte_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr){ uint8_t max_transfer_sz = 0; switch(msg) { case U8X8_MSG_BYTE_SEND: //ESP_LOGI(TAG, "U8X8_MSG_BYTE_SEND:%d,%d", arg_int ,spi_device_max_transfer_sz(u8g2_spi)); max_transfer_sz = spi_device_max_transfer_sz(u8g2_spi); if (arg_int <= max_transfer_sz) { u8g2_tran.length = arg_int*8, u8g2_tran.tx_buffer = (const void *)arg_ptr, u8g2_tran.rxlength = 0, u8g2_tran.rx_buffer = NULL, spi_device_polling_transmit(u8g2_spi, &u8g2_tran); } else { int packet_num = arg_int/max_transfer_sz; int packet_remain = arg_int%max_transfer_sz; uint8_t *data_prt = (uint8_t *)arg_ptr; if (packet_num > 0) { for (int i=0;i 0) { u8g2_tran.length = packet_remain*8, u8g2_tran.tx_buffer = (const void *)data_prt, u8g2_tran.rxlength = 0, u8g2_tran.rx_buffer = NULL, spi_device_polling_transmit(u8g2_spi, &u8g2_tran); } } break; case U8X8_MSG_BYTE_SET_DC: u8g2_ssd1306_set_dc(arg_int); break; default: return 0; } return 1;}
?而剩下的u8x8_msg_cb gpio_and_delay_cb這個callback主要是用來做輸入相關(guān)功能的回調(diào)接口(瓦力ui配合rc遙控器實現(xiàn)的輸入交互就是通過該接口實現(xiàn)的),u8g2庫可以通過該接口來讀取硬件按鍵輸入的狀態(tài)信息然后進行處理--->
uint8_t u8x8_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, U8X8_UNUSED void *arg_ptr){ case U8X8_MSG_GPIO_MENU_SELECT: u8x8->gpio_result = u8g2_gpio_menu_select(); vTaskDelay(3); break; case U8X8_MSG_GPIO_MENU_NEXT: u8x8->gpio_result = u8g2_gpio_menu_next(); vTaskDelay(3); break; case U8X8_MSG_GPIO_MENU_PREV: u8x8->gpio_result = u8g2_gpio_menu_prev(); vTaskDelay(3); break; case U8X8_MSG_GPIO_MENU_HOME: u8x8->gpio_result = u8g2_gpio_menu_home(); vTaskDelay(3); break; case U8X8_MSG_GPIO_MENU_UP: u8x8->gpio_result = u8g2_gpio_menu_up(); vTaskDelay(3); break; case U8X8_MSG_GPIO_MENU_DOWN: u8x8->gpio_result = u8g2_gpio_menu_down(); vTaskDelay(3); break; case U8X8_MSG_GPIO_RESET: u8g2_ssd1306_set_rst(arg_int); break; default: break; } return 1;}
到此底層相關(guān)的工作基本做完,接下來就是一些基于上層API接口的花活了--->
void u8g2_ssd1306_init(spi_device_handle_t handle){ u8g2_spi = handle; //Initialize non-SPI GPIOs gpio_set_direction(PIN_NUM_DC, GPIO_MODE_OUTPUT); gpio_set_direction(PIN_NUM_RST, GPIO_MODE_OUTPUT); //Reset the display gpio_set_level(PIN_NUM_RST, 0); vTaskDelay(100 / portTICK_RATE_MS); gpio_set_level(PIN_NUM_RST, 1); vTaskDelay(100 / portTICK_RATE_MS); u8g2_Setup_ssd1306_128x64_noname_f( &u8g2, U8G2_R0, u8x8_byte_hw_spi, u8x8_gpio_and_delay); // init u8g2 structure ESP_LOGI(TAG, "u8g2_InitDisplay"); u8g2_InitDisplay(&u8g2); // send init sequence to the display, display is in sleep mode after this, ESP_LOGI(TAG, "u8g2_SetPowerSave"); u8g2_SetPowerSave(&u8g2, 0); // wake up display ESP_LOGI(TAG, "u8g2_ClearBuffer"); u8g2_ClearBuffer(&u8g2); ESP_LOGI(TAG, "u8g2_SetFont"); u8g2_SetFont(&u8g2, u8g2_font_6x10_mf); ESP_LOGI(TAG, "u8g2_DrawStr"); u8g2_DrawStr(&u8g2, 20, 14, "esp32 foc +-x%/"); ESP_LOGI(TAG, "u8g2 init all done!");}
雖然是花活,其中也有一些需要注意的地方,例如在設(shè)置字庫的時候,如果選擇了一些精簡字庫,會導(dǎo)致字符刷新出現(xiàn)字符像素殘留的現(xiàn)象,特別是在動態(tài)刷新一些數(shù)字的情景下,效果很差,十分影響顯示效果;
小結(jié):
?????????這次主要記錄了為~~呆萌的瓦力平衡機器人~~選擇ui圖像庫的心路歷程以及在開始使用該圖形庫時所需要做的一些前期分析和實操過程中需要注意的技術(shù)要點;
以下是一些和本文相關(guān)的文章鏈接和U8g2的wiki鏈接:
一、~~呆萌的瓦力平衡機器人~~鏈接:
? ? ? ? 1.基于ESP32雙無刷FOC電機的瓦力平衡機器人(1);
????????2.基于ESP32雙無刷FOC電機的瓦力平衡機器人(2);
二、U8g2 wiki鏈接:
? ? ? ? 1.U8g2_wiki;
后續(xù)的計劃:
? ? ? ?下一期準(zhǔn)備記錄在做U8g2界面刷新和兩路foc電機驅(qū)動遇到的沖突問題,以及我的解決思路;
???????????????? ? ??大家如果也感興趣,可以加qun交流學(xué)習(xí)(群里提供了豐富的esp32資料):
????????????????????????????????????????????????????????燥起來吧,sao年!!!!!!?
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/119239.html
摘要:新公司已經(jīng)呆了一個多月,目前著手一個數(shù)據(jù)可視化的項目,數(shù)據(jù)可視化肯定要用到圖形庫如等,經(jīng)決定我的這個項目用阿里旗下螞蟻金服所開發(fā)的圖表庫。數(shù)據(jù)提示框內(nèi)提示的信息還可以通過格式化函數(shù)動態(tài)指定。 新公司已經(jīng)呆了一個多月,目前著手一個數(shù)據(jù)可視化的項目,數(shù)據(jù)可視化肯定要用到圖形庫如D3、Highcharts、ECharts、Chart等,經(jīng)決定我的這個項目用阿里旗下螞蟻金服所開發(fā)的G2圖表庫。...
摘要:十開放模式識別項目開放模式識別項目,致力于開發(fā)出一套包含圖像處理計算機視覺自然語言處理模式識別機器學(xué)習(xí)和相關(guān)領(lǐng)域算法的函數(shù)庫。 一、開源生物特征識別庫 OpenBROpenBR 是一個用來從照片中識別人臉的工具。還支持推算性別與年齡。使用方法:$ br -algorithm FaceRecognition -compare me.jpg you.jpg二、計算機視覺庫 OpenCVOpenC...
摘要:在文末,我會附上一個可加載的模型方便學(xué)習(xí)中文藝術(shù)字渲染用原生可以很容易地繪制文字,但是原生提供的文字效果美化功能十分有限。 showImg(https://segmentfault.com/img/bVWYnb?w=900&h=385); WebGL 可以說是 HTML5 技術(shù)生態(tài)鏈中最為令人振奮的標(biāo)準(zhǔn)之一,它把 Web 帶入了 3D 的時代。 初識 WebGL 先通過幾個使用 Web...
閱讀 2073·2021-11-15 17:57
閱讀 739·2021-11-11 16:54
閱讀 2588·2021-09-27 13:58
閱讀 4067·2021-09-06 15:00
閱讀 950·2021-09-04 16:45
閱讀 3505·2019-08-30 15:56
閱讀 1784·2019-08-30 15:53
閱讀 1603·2019-08-30 14:12