zoukankan      html  css  js  c++  java
  • 基于以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/MirrorDescription
    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:
    MessageDescription
    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 ProcedureDescription
    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 ArgumentDescriptionDatasheet 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

  • 相关阅读:
    JS实现表格隔行换色,鼠标经过换色,单击换色,再单击还原等功能
    URL带有其他参数时,如何使用PHP的CI框架分页类?
    linux SVN web 同步
    php播放器代码
    php 获取IP 根据IP 获取城市信息 判断是否手机登陆
    微信公众平台获取微信用户信息
    appcan 本地真机调试
    对于探索搜索网站路上的一些迷茫
    成为全栈工程师真的好吗?
    ServletContext与ServletConfig
  • 原文地址:https://www.cnblogs.com/huan-huan/p/8528307.html
Copyright © 2011-2022 走看看