基於以7920為核心的點陣型LCD12864成熟代碼工程u8g2的移植——stm32單片機


0、前言

     一直以來都在尋找一個方便的、可靠的、豐富的點陣型LCD驅動庫 ,因為大型的GUI解決方案並不適合像12864(基於7920)這種資源緊缺型的顯示模組使用,而網絡上充斥代碼的資源都是簡單實現了一個字符輸出功能,達不到預期的目的。直到無意中看到了u8g2。通過學習后發現該顯示庫支持很多種字體 fonts (英文和數字),而且具有完整的驅動函數庫(直線、圓形、斜線、字符旋轉鏡像反白、bitmap一應俱全)和豐富的演示demo。特別適合應用在嵌入式mcu上面。於是把它移植到了stm32上面,因此才有了這篇blog。

github地址:https://github.com/olikraus/u8g2 

U8g2: Library for monochrome displays, version 2

U8g2 is a monochrome graphics library for embedded devices. U8g2 supports controller based (for example SSD1306) monochrome OLEDs and LCDs (See the U8g2/U8x8 setup guide for a complete list of supported display controller). The Arduino library U8g2 can be installed from the library manager of the Arduino IDE. U8g2 also includes U8x8 library:

U8g2

  • Includes all graphics procedures (line/box/circle draw).
  • Supports many fonts. (Almost) no restriction on the font height.
  • Requires some memory in the microcontroller to render the display.

U8x8

  • Text output only (character) device.
  • Only fonts allowed with fixed size per character (8x8 pixel).
  • Writes directly to the display. No buffer in the microcontroller required.

     Setup Guide and Reference Manual

通過介紹(readme.md)可以知道u8g2是一個支持嵌入式設備的顯示驅動庫,它包含了兩種驅動,其中u8g2支持像12864這種常見的點陣型LCD,u8x8支持像1602這種字符型LCD,此外它所支持的所以驅動IC如下所示:

Supported Display Controller: SSD1305, SSD1306, SSD1309, SSD1322, SSD1325, SSD1327, SSD1329, SSD1606, SSD1607, SH1106, T6963, RA8835, LC7981, PCD8544, PCF8812, UC1601, UC1604, UC1608, UC1610, UC1611, UC1701, ST7565, ST7567, ST7588, ST75256, NT7534, IST3020, ST7920, LD7032, KS0108, SED1520, SBN1661, IL3820, MAX7219 (see here for a full list)

查閱后確認:LCD ST7920 128X64 在支持的范圍內,但是作者提供的demo都是基於Arduino使用,並沒有直接在stm32上直接調用的實例。“U8g2 works nicely without C++/Arduino --by olikraus”。自己動手,豐衣足食,既然沒有,那么接下來就自己動手移植!~

1、環境准備

 

  • Windows7 sp1
  • Keil MDK 5.24(armcc v5.06 update5)+ Jlink
  • MCU : STM32F103C8T6  (64k flash 、20k ram)
  • LCD :  ZXM12864F4 (controller st7920)
  • u8g2:  2017-12-09 v2.20.13
  • STM32Cube_FW_F1_V1.6.0  (STM32F1xx HAL Drivers v1.1.1  2017-5-12)

2、移植

      根據作者提供的移植說明《Porting-to-new-MCU-platform》,需要我們實現的函數主要有兩個:

 

  • The "uC specific" GPIO and Delay callback (the last argument of the setup function)
  • The u8x8 byte communication callback (the second to last argument of the setup function)
     這兩個函數主要被一個初始化setup函數調用,其函數原型(例子)如下所示:
     u8g2_Setup_st7920_s_128x64_f(  u8g2,   rotation,   u8x8_byte_4wire_sw_spi,   uC specific)
 
1、第一個參數 ,u8g2 : Pointer to an empty u8g2 structure 
     指向一個包含所有顯示參數的結構體    a structure which will contain all the data for one display
     其定義方式如:u8g2_t u8g2;  具體成員說明,請參閱u8g2.h文件。
2、第二個參數 ,rotation:Rotation procedure
      用於處理字符旋轉或者鏡像的句柄,在顯示庫中已被定義,直接調用即可。
Rotation/Mirror Description
U8G2_R0 No rotation, landscape
U8G2_R1 90 degree clockwise rotation
U8G2_R2 180 degree clockwise rotation
U8G2_R3 270 degree clockwise rotation
U8G2_MIRROR No rotation, landscape, display content is mirrored (v2.6.x)
3、第三個參數 ,u8x8_byte_4wire_sw_spi:Byte communication procedure
     字節傳輸控制,mcu(stm32)和lcd控制芯片(ST7920)的通訊函數,也是需要移植實現的函數之一。
 
     如果使用mcu片上外設(硬件SPI、I2C)的話,需要自行實現該函數的功能。
     函數的藍本:
   typedef uint8_t (*u8x8_msg_cb)(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
     函數需要的處理的Message:
Message Description
U8X8_MSG_BYTE_INIT Send once during the init phase of the display.
U8X8_MSG_BYTE_SET_DC Set the level of the data/command pin. arg_intcontains the expected output level. Use u8x8_gpio_SetDC(u8x8, arg_int) to send a message to the GPIO procedure.
U8X8_MSG_BYTE_START_TRANSFER Set the chip select line here. u8x8->display_info->chip_enable_level contains the expected level. Use u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level) to call the GPIO procedure.
U8X8_MSG_BYTE_SEND Send one or more bytes, located at arg_ptrarg_intcontains the number of bytes.
U8X8_MSG_BYTE_END_TRANSFER Unselect the device. Use the CS level from here: u8x8->display_info->chip_disable_level.
     函數的樣本(硬件SPI方式):
[cpp]  view plain  copy
 
  1. uint8_t u8x8_byte_arduino_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)   
  2. {  
  3.   uint8_t *data;  
  4.   uint8_t internal_spi_mode;   
  5.   switch(msg)   
  6.   {  
  7.     case U8X8_MSG_BYTE_SEND:  
  8.       data = (uint8_t *)arg_ptr;  
  9.       while( arg_int > 0 )   
  10.       {  
  11.         SPI.transfer((uint8_t)*data);  
  12.         data++;  
  13.         arg_int--;  
  14.       }    
  15.       break;  
  16.     case U8X8_MSG_BYTE_INIT:  
  17.       u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);  
  18.       SPI.begin();  
  19.       break;  
  20.     case U8X8_MSG_BYTE_SET_DC:  
  21.       u8x8_gpio_SetDC(u8x8, arg_int);  
  22.       break;  
  23.     case U8X8_MSG_BYTE_START_TRANSFER:  
  24.       internal_spi_mode =  0;  
  25.       switch(u8x8->display_info->spi_mode)   
  26.       {  
  27.         case 0: internal_spi_mode = SPI_MODE0; break;  
  28.         case 1: internal_spi_mode = SPI_MODE1; break;  
  29.         case 2: internal_spi_mode = SPI_MODE2; break;  
  30.         case 3: internal_spi_mode = SPI_MODE3; break;  
  31.        }  
  32.       SPI.beginTransaction(SPISettings(u8x8->display_info->sck_clock_hz, MSBFIRST, internal_spi_mode));  
  33.       u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);    
  34.       u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);  
  35.       break;  
  36.     case U8X8_MSG_BYTE_END_TRANSFER:        
  37.       u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);  
  38.       u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);  
  39.       SPI.endTransaction();  
  40.       break;  
  41.     default:  
  42.       return 0;  
  43.   }    
  44.   return 1;  
  45. }  
 
      如果使用者是用軟件模擬串行協議的話,顯示庫提供以下幾種模擬協議,可以直接使用。
    In order to interface to the communication port of the display controller you need to have a byte orientated interface i.e. SPI, I2C, etc. This interface may either be implemented as a bit-banged software interface or using the MCU specific hardware. Several software bit-banged interface are provided as part of the U8X8 library in u8x8_byte.c:
Byte Procedure Description
u8x8_byte_4wire_sw_spi Standard 8-bit SPI communication with "four pins" (SCK, MOSI, DC, CS)
u8x8_byte_3wire_sw_spi 9-bit communication with "three pins" (SCK, MOSI, CS)
u8x8_byte_8bit_6800mode Parallel interface, 6800 format
u8x8_byte_8bit_8080mode Parallel interface, 8080 format
u8x8_byte_sw_i2c Two wire, I2C communication
u8x8_byte_ks0108 Special interface for KS0108 controller
     上面列表中的函數還將調用第四個參數uC specific:gpio and delay functions。
4、第四個參數, uC specific:The "uC specific" GPIO and Delay callback
     函數的藍本為:
   typedef uint8_t (*u8x8_msg_cb)(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
     該函數的功能在於:提供mcu的GPIO操作接口,用於實現軟件模擬串行協議。需要處理來自HAL層的3種消息任務(message)。(注:如果使用mcu片上外設(硬件SPI、I2C),則不需要實現該函數,直接返回1即可)
  1. Delay messages of the form "U8X8_MSG_DELAY_". These messages are used to provide delay for the software implementation of I2C, SPI etc.
    In order for the software (aka. bit-banged) interfaces to work you need to implement the MCU specific busy-wait loop to provide a correct amount of delay.
    For the example implementation I used the Cypress PSoC specific delay functions of the form CyDelay*

  2. GPIO messages of the form "U8X*_MSG_GPIO". These messages are used to write 1s and 0s to the GPIOs which are being used to interface to the device. i.e. the SCL/SDA or Reset or CS etc.
    For the example implementation I used the Cypress pin write functions which all take the form of "pinname_Write()".

  3. GPIO menu pins are used to get the state of an input pin. These messages are only required for the build in menu function and can be ignored, if the U8G2/U8X8 menu functions are not used.

     函數的樣板為:
[cpp]  view plain  copy
 
  1. uint8_t u8x8_gpio_and_delay_template(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)  
  2. {  
  3.   switch(msg)  
  4.   {  
  5.     case U8X8_MSG_GPIO_AND_DELAY_INIT:  // called once during init phase of u8g2/u8x8  
  6.       break;                // can be used to setup pins  
  7.     case U8X8_MSG_DELAY_NANO:       // delay arg_int * 1 nano second  
  8.       break;      
  9.     case U8X8_MSG_DELAY_100NANO:<span style="white-space:pre;"> </span>// delay arg_int * 100 nano seconds  
  10.       break;  
  11.     case U8X8_MSG_DELAY_10MICRO:    // delay arg_int * 10 micro seconds  
  12.       break;  
  13.     case U8X8_MSG_DELAY_MILLI:      // delay arg_int * 1 milli second  
  14.       break;  
  15.     case U8X8_MSG_DELAY_I2C:        // arg_int is the I2C speed in 100KHz, e.g. 4 = 400 KHz  
  16.       break;<span style="white-space:pre;">             </span>// arg_int=1: delay by 5us, arg_int = 4: delay by 1.25us  
  17.     case U8X8_MSG_GPIO_D0:      // D0 or SPI clock pin: Output level in arg_int  
  18.   //case U8X8_MSG_GPIO_SPI_CLOCK:  
  19.       break;  
  20.     case U8X8_MSG_GPIO_D1:      // D1 or SPI data pin: Output level in arg_int  
  21.   //case U8X8_MSG_GPIO_SPI_DATA:  
  22.       break;  
  23.     case U8X8_MSG_GPIO_D2:      // D2 pin: Output level in arg_int  
  24.       break  
  25.     case U8X8_MSG_GPIO_D3:      // D3 pin: Output level in arg_int  
  26.       break;  
  27.     case U8X8_MSG_GPIO_D4:      // D4 pin: Output level in arg_int  
  28.       break;  
  29.     case U8X8_MSG_GPIO_D5:      // D5 pin: Output level in arg_int  
  30.       break;  
  31.     case U8X8_MSG_GPIO_D6:      // D6 pin: Output level in arg_int  
  32.       break;  
  33.     case U8X8_MSG_GPIO_D7:      // D7 pin: Output level in arg_int  
  34.       break;  
  35.     case U8X8_MSG_GPIO_E:       // E/WR pin: Output level in arg_int  
  36.       break;  
  37.     case U8X8_MSG_GPIO_CS:      // CS (chip select) pin: Output level in arg_int  
  38.       break;  
  39.     case U8X8_MSG_GPIO_DC:<span style="white-space:pre;">       </span>// DC (data/cmd, A0, register select) pin: Output level in arg_int  
  40.       break;  
  41.     case U8X8_MSG_GPIO_RESET:       // Reset pin: Output level in arg_int  
  42.       break;  
  43.     case U8X8_MSG_GPIO_CS1:     // CS1 (chip select) pin: Output level in arg_int  
  44.       break;  
  45.     case U8X8_MSG_GPIO_CS2:     // CS2 (chip select) pin: Output level in arg_int  
  46.       break;  
  47.     case U8X8_MSG_GPIO_I2C_CLOCK:   // arg_int=0: Output low at I2C clock pin  
  48.       break;                // arg_int=1: Input dir with pullup high for I2C clock pin  
  49.     case U8X8_MSG_GPIO_I2C_DATA:    // arg_int=0: Output low at I2C data pin  
  50.       break;                // arg_int=1: Input dir with pullup high for I2C data pin  
  51.     case U8X8_MSG_GPIO_MENU_SELECT:  
  52.       u8x8_SetGPIOResult(u8x8, /* get menu select pin state */ 0);  
  53.       break;  
  54.     case U8X8_MSG_GPIO_MENU_NEXT:  
  55.       u8x8_SetGPIOResult(u8x8, /* get menu next pin state */ 0);  
  56.       break;  
  57.     case U8X8_MSG_GPIO_MENU_PREV:  
  58.       u8x8_SetGPIOResult(u8x8, /* get menu prev pin state */ 0);  
  59.       break;  
  60.     case U8X8_MSG_GPIO_MENU_HOME:  
  61.       u8x8_SetGPIOResult(u8x8, /* get menu home pin state */ 0);  
  62.       break;  
  63.     default:  
  64.       u8x8_SetGPIOResult(u8x8, 1);<span style="white-space:pre;">   </span>// default return value  
  65.       break;  
  66.   }  
  67.   return 1;  
  68. }  
    並不是所有的case都需要實現,只需實現和mcu的GPIO連接相關的case和Delay Message。

3、實踐

     經過移植分析后,結合現有的硬件條件,可以得出:

 

  • 使用軟件模擬4線spi方式來驅動LCD12864(st7920)引腳對應方式如下:

PB10      - CLK          - E
PB11      - SPI data   - R/W
PB9        - RST          - RST
  -           - CS           - PSB                (已經外接下拉電阻,默認為串行模式)
PB12      - CD           - RS

  • 使用Full screen buffer mode模式,調用 u8g2_Setup_st7920_s_128x64_f 函數
  • 使用u8g2庫自帶的函數u8x8_byte_4wire_sw_spi, 軟件模擬spi串行協議
  • 需要實現 u8g2_gpio_and_delay_stm32 函數


    具體步驟:

 

 

  1. 下載u8g2庫源文件,將所有相關的c文件(csrc文件夾)添加到keil工程中,keil工程使用STM32Cube_FW_F1_V1.6.0下的f103分支的temple模板。
  2. 添加u8g2_gpio_and_delay_stm32支持,具體代碼如下:
[cpp]  view plain  copy
 
  1. uint8_t u8g2_gpio_and_delay_stm32(U8X8_UNUSED u8x8_t *u8x8, U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr)  
  2. {  
  3.         GPIO_InitTypeDef  gpioinitstruct;  
  4.       
  5.         switch(msg){  
  6.   
  7.         //Function which implements a delay, arg_int contains the amount of ms  
  8.         case U8X8_MSG_GPIO_AND_DELAY_INIT:  
  9.   
  10.         __HAL_RCC_GPIOB_CLK_ENABLE();  
  11.         /* Configure the GPIO_LED pin */  
  12.         gpioinitstruct.Pin    = GPIO_PIN_12|GPIO_PIN_11|GPIO_PIN_10|GPIO_PIN_9;  
  13.         gpioinitstruct.Mode   = GPIO_MODE_OUTPUT_PP;  
  14.         gpioinitstruct.Pull   = GPIO_NOPULL;  
  15.         gpioinitstruct.Speed  = GPIO_SPEED_FREQ_HIGH;  
  16.         HAL_GPIO_Init(GPIOB, &gpioinitstruct);  
  17.           
  18.         HAL_GPIO_WritePin(LED_GPIO_PORT, GPIO_PIN_12|GPIO_PIN_11|GPIO_PIN_10|GPIO_PIN_9, GPIO_PIN_SET);   
  19.   
  20.         break;  
  21.         //Function which implements a delay, arg_int contains the amount of ms  
  22.         case U8X8_MSG_DELAY_MILLI:  
  23.         HAL_Delay(arg_int);  
  24.         break;  
  25.         //Function which delays 10us  
  26.         case U8X8_MSG_DELAY_10MICRO:  
  27.         delay_us(10);  
  28.         break;  
  29.         //Function which delays 100ns  
  30.         case U8X8_MSG_DELAY_100NANO:  
  31.         __NOP();  
  32.   
  33.         break;  
  34.         //Function to define the logic level of the clockline  
  35.         case U8X8_MSG_GPIO_SPI_CLOCK:  
  36.             if (arg_int) LCD_SCLK_1;  
  37.             else LCD_SCLK_0;  
  38.   
  39.         break;  
  40.         //Function to define the logic level of the data line to the display  
  41.         case U8X8_MSG_GPIO_SPI_DATA:  
  42.             if (arg_int) LCD_SID_1;  
  43.             else LCD_SID_0;  
  44.   
  45.         break;  
  46.   
  47.         // Function to define the logic level of the CS line  
  48.         case U8X8_MSG_GPIO_CS1:  
  49.             if (arg_int) LCD_RS_1   ;  
  50.             else LCD_RS_0;  
  51.   
  52.         break;  
  53.         //Function to define the logic level of the Data/ Command line  
  54.         case U8X8_MSG_GPIO_DC:  
  55.   
  56.         break;  
  57.         //Function to define the logic level of the RESET line  
  58.         case U8X8_MSG_GPIO_RESET:  
  59.             if (arg_int) LCD_RST_1;  
  60.             else LCD_RST_0;  
  61.   
  62.         break;  
  63.           
  64.         default:  
  65.             return 0; //A message was received which is not implemented, return 0 to indicate an error  
  66.     }  
  67.   
  68.     return 1; // command processed successfully.  
  69. }  

      3. 裁剪  u8g2_d_setup.c   u8g2_d_memory.c 文件中與st7920無關的代碼,減小代碼體積,ram用量。

      4. 修改 u8x8.h 文件,添加u8g2顯示庫對 keil setction(armcc) 的支持。

 

[cpp]  view plain  copy
 
  1. #define SECTION(x)   __attribute__((section(x)))  
  2. #ifndef U8X8_FONT_SECTION  
  3. #  define U8X8_FONT_SECTION(name) SECTION(".font." name)  
  4. #endif  

      5.修改 main() 函數,初始化u8g2顯示庫,增加顯示代碼。

 

[cpp]  view plain  copy
 
  1. int main(void)  
  2. {  
  3.  /* This sample code shows how to configure The HAL time base source base with a  
  4.     dedicated  Tick interrupt priority. 
  5.     A general purpose timer (TIM2) is used instead of Systick as source of time base.   
  6.     Time base duration is fixed to 1ms since PPP_TIMEOUT_VALUEs are defined and  
  7.     handled in milliseconds basis. 
  8.     */  
  9.   
  10.   /* STM32F1xx HAL library initialization: 
  11.        - Configure the Flash prefetch 
  12.        - Configure timer (TIM2) to generate an interrupt each 1 msec 
  13.        - Set NVIC Group Priority to 4 
  14.        - Low Level Initialization 
  15.      */  
  16.   HAL_Init();  
  17.     
  18.   /* Configure the system clock to 72 MHz */  
  19.   SystemClock_Config();  
  20.     
  21.   /* Configure LED */  
  22.   BSP_LED_Init();    
  23.       
  24.   u8g2_Setup_st7920_s_128x64_f(&u8g2, U8G2_R0, u8x8_byte_4wire_sw_spi, u8g2_gpio_and_delay_stm32);   
  25.   u8g2_InitDisplay(&u8g2);  
  26.   u8g2_SetPowerSave(&u8g2, 0);   
  27.       
  28.     HAL_Delay(1000);  
  29.   
  30.   /* Insert a Delay of 1000 ms and toggle LED2, in an infinite loop */    
  31.   while (1)  
  32.   {  
  33.     /* Insert a 1s delay */  
  34.     HAL_Delay(1000);    
  35.     BSP_LED2_Toggle();  
  36.     BSP_LED1_Toggle();  
  37.           
  38.     u8g2_ClearBuffer(&u8g2);  
  39.     u8g2_SetFontMode(&u8g2, 1);  
  40.     u8g2_SetFontDirection(&u8g2, 0);  
  41.     u8g2_SetFont(&u8g2, u8g2_font_helvB18_te);  
  42.     u8g2_DrawStr(&u8g2,  0, 24, "hello world");  
  43.     u8g2_DrawStr(&u8g2,  0, 50, "i am Re.");  
  44.     u8g2_SetFont(&u8g2, u8g2_font_u8glib_4_tf);  
  45.     u8g2_DrawStr(&u8g2,  0, 60, "2018-01-18");  
  46.     u8g2_SendBuffer(&u8g2);  
  47.   }   
  48. }  

      6.修改與工程相關的其他代碼,編譯,下載。

     7.測試

4、后記

      u8g2庫支持的函數如下:u8g2reference

      u8x8庫支持的函數如下:u8x8reference

      該顯示庫基於c編寫,在修改相關的GPIO操作函數后,本keil工程理論上支持所有的stm32單片機驅動st7920 12864系列lcd。如需移植到其他lcd,請參考移植步驟。
 
      關於中文字庫:因為普遍的中文字庫都比較大,不適合直接添加到顯示庫中,建議需要的時候,將需要的中文轉成fonts文件,然后編譯、鏈接進工程,具體的fonts轉換,請參閱github的描述。 Rebuild Fonts 
    
      一個中文的u8g2可以使用的漢字庫,來自larryli/u8g2_wqy : https://github.com/larryli/u8g2_wqy
      
      本blog相關的代碼(stm32 keil工程)已經上傳至我的github:  https://github.com/refugeer/stm32_st7920_u8g2

5、其他

接口說明 Wiring
 

 

Pin Argument Description Datasheet Names
clock SPI or I2C clock line SCL, SCLK, ...
data SPI or I2C data line SDA, MOSI, SDIN, ...
d0 ... d7 Data lines of the parallel interface D0 ... D7
cs Chip select line CS
dc Data/command selection line (register select) D/C, A0, RS, ...
enable "Write" for the 8080 interface, "enable" for the 6800 interface 8080: WR, 6800: E
reset Reset line

串行協議說明

 

  • 3SPI, 3-wire SPI: Serial Peripheral Interface with three signals: Clock, Data and Chip-Select.
  • 4SPI, 4-Wire SPI: Same as 3SPI, but with one additional line for commands and data (often labeled as D/C, RS or A0)
  • I2C, IIC or TWI: Inter-Integrated Circuit Bus which has two signals: Clock (SCL) and Data (SDA).
  • 8080: A 8-Bit bus which requires 8 data lines, chip select and a write strobe signal.
  • 6800: Another 8-Bit bus, but with a different protocol.

setup中buffersize的說明

asda

Controller "st7920", Display "128x64" Descirption
u8g2_Setup_st7920_128x64_1(u8g2, rotation, u8x8_byte_8bit_6800mode, uC specific) page buffer, size = 128 bytes
u8g2_Setup_st7920_128x64_2(u8g2, rotation, u8x8_byte_8bit_6800mode, uC specific) page buffer, size = 256 bytes
u8g2_Setup_st7920_128x64_f(u8g2, rotation, u8x8_byte_8bit_6800mode, uC specific) full framebuffer, size = 1024 bytes
  Description
Buffer Description
1 Only one page of the display memory is stored in the microcontroller RAM. Use a firstPage()/nextPage() loop for drawing on the display.
2 Same as 1, but maintains two pages in the microcontroller RAM. This will up to two times faster than 1.
F Keep a copy of the full display frame buffer in the microcontroller RAM. Use clearBuffer() to clear the RAM and sendBuffer() to transfer the microcontroller RAM to the display.

The full buffer F option can be used only, if there is sufficient RAM available in the microcontroller. Use option 1 or 2 on a microcontroller with small amount of RAM. The u8x8 APIcan be used if there is not even RAM for one page.

U8g2 繪制模式說明

 

U8g2 supports three different drawing modes:

  • Full screen buffer mode
  • Page mode (This is the U8glib picture loop)
  • U8x8, character only mode

Full screen buffer mode

Pros and Cons

  • Fast
  • All graphics procedures can be used
  • Requires a lot of RAM

Setup

Use the U8g2 constructor from here. The constructor must include the "F" character. For example:

u8g2_Setup_st7920_128x64_f(u8g2, rotation, u8x8_byte_8bit_6800mode, uC specific)

Usage

  1. Clear the buffer with u8g2.clearBuffer().
  2. Draw something with the usual draw commands.
  3. Send the buffer to the display with u8g2.sendBuffer().

Example

void setup(void) {
  u8g2.begin();
}

void loop(void) {
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_ncenB14_tr);
  u8g2.drawStr(0,20,"Hello World!");
  u8g2.sendBuffer();
}

Page buffer mode (Picture Loop)

Pros and Cons

  • All graphics procedures can be used
  • Only a little bit of RAM is required
  • Slow

Setup

Use the U8g2 constructor from here. The constructor must include the "1" or "2" character. For example:

u8g2_Setup_st7920_128x64_1(u8g2, rotation, u8x8_byte_8bit_6800mode, uC specific)

Usage

  1. Call u8g2.firstPage().
  2. Start a do-while loop
  3. Inside the loop-body: Draw something with the usual draw commands.
  4. Loop as long as u8g2.nextPage() returns true.

Note: Always create the same picture inside the loop body. See details here.

Example

void setup(void) {
  u8g2.begin();
}

void loop(void) {
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_ncenB14_tr);
    u8g2.drawStr(0,24,"Hello World!");
  } while ( u8g2.nextPage() );
}

U8x8 character mode

Pros and Cons

  • Fast
  • No RAM required
  • No graphics possible
  • Not available for all displays

Setup

Use the U8x8 constructor from here. For example:

u8x8_Setup(u8x8_d_ssd1306_128x64_noname, u8x8_cad_001, u8x8_byte_4wire_sw_spi, uC specific)

Usage

All draw commands directly write to the display.

Example

void setup(void) {
  u8x8.begin();
}

void loop(void) {
  u8x8.setFont(u8x8_font_chroma48medium8_r);
  u8x8.drawString(0,1,"Hello World!");
}

 

嵌入式全新視頻:www.makeru.com.cn/?t=12               嵌入式學習交流群:561213221


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM