U8g2移植在STM32

编程入门 行业动态 更新时间:2024-10-20 07:40:07

U8g2移植在STM32

U8g2移植在STM32

U8g2简介

 

1.1 U8g2是什么

    U8g2是嵌入式设备的单色图形库,一句话简单明了。主要应用于嵌入式设备,包括我们常见的单片机;

1.2 U8g2支持的显示控制器

    U8g2支持单色OLED和LCD,包括以下控制器:SSD1305,SSD1306,SSD1309,SSD1322,SSD1325,SSD1327,SSD1329,SSD1606,SSD1607,SH1106,SH1107,SH1108,SH1122,T6963,RA8835,LC7981,PCD8544,PCF8812,HX1230 ,UC1601,UC1604,UC1608,UC1610,UC1611,UC1701,ST7565,ST7567,ST7588,ST75256,NT7534,IST3020,ST7920,LD7032,KS0108,SED1520,SBN1661,IL3820,MAX7219(有关完整列表,请参见 此处)。
    可以说,基本上主流的显示控制器都支持,比如我们常见的SSD1306 12864,读者在使用该库之前请查阅自己的OLED显示控制器是否处于支持列表中。

1.3 U8g2的优势


    为什么要运用U8g2库?也就是说U8g2库能带给我们什么样的开发便利。在博主看来,主要考虑几个方面:

U8g2库平台支持性好,基本上支持绝大部分Arduino开发板,特别也博主比较喜欢的ESP8266;
U8g2库显示控制器支持性好,基本上市面上的OLED都完美支持;
U8g2库 API众多,特别支持了中文,支持了不同字体,这是一个对于开发者俩说不小的福利。

u8g2是开源的,可直接下载代码移植:GitHub - olikraus/u8g2: U8glib library for monochrome displays, version 2。

2.1下载u8g2库函数

只需下载方框内文件 .

u8g2里面支持多种驱动芯片,以u8x8_d_xxx.c命名的就是驱动文件,本文使用的是0.96吋oled,芯片是ssd1306,将不必要的外设驱动(u8x8_d_xxx.c)删除,只保留需要使用的驱动(u8g2_d_memory.cu8g2_d_setup.c要保留),下面以ssd1306为例,保留u8x8_d_ssd1306_128x64_noname.c文件,

(3)将剩下的库添加到工程中

 (4)修改"u8g2_d_setup.c"这个文件,里面有各种驱动芯片的初始化函数,删除其他函数,只留下与使用的驱动芯片相关的函数。
本文使用的ssd1306,但是与ssd1306相关的有多个函数,例如:
u8g2_Setup_ssd1306_128x64_noname_1、
u8g2_Setup_ssd1306_128x64_noname_2、
u8g2_Setup_ssd1306_128x64_noname_f,
这些都是spi接口的;
u8g2_Setup_ssd1306_i2c_128x64_noname_1、
u8g2_Setup_ssd1306_i2c_128x64_noname_2、
u8g2_Setup_ssd1306_i2c_128x64_noname_f,
这些都是i2c接口的;
后缀1、2、f代表缓冲区大小的不同:
1代表128字节,
2代表256字节,
f代表1024字节;
根据单片机空间的大小选择合适的接口,缓冲区小的,刷新lcd/oled的时候就比较耗时,反之。
本文使用u8g2_Setup_ssd1306_i2c_128x64_noname_f这个接口:

所以删除或者屏蔽u8g2_d_setup.c中不必要的内容,只保留u8g2_Setup_ssd1306_128x64_noname_f函数

(5)修改“u8g2_d_memory.c”文件,这个文件里面其实就是“u8g2_d_setup.c”文件对应的缓冲区,同上面一样,屏蔽掉没用到的,留下用到的:

6)两个回调函数
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);

参数byte_cb和gpio_and_delay_cb是需要编写的两个回调函数。

byte_cb:是通信相关的函数,比如i2c写数据,
gpio_and_delay_cb:是延时相关的函数。
关于回调函数的写法,官方也给出了参考例子:

通信函数:直接使用官方的这个u8x8_byte_sw_i2c

#define SCL_Pin GPIO_Pin_9
#define SDA_Pin GPIO_Pin_8#define IIC_GPIO_Port GPIOB
void IIC_Init(void)
{                         GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(    RCC_APB2Periph_GPIOB, ENABLE );    GPIO_InitStructure.GPIO_Pin = SCL_Pin|SDA_Pin;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(IIC_GPIO_Port, &GPIO_InitStructure);
}


 

延时函数:在这个通信函数分为硬件接口和软件模拟方式,软件模拟方式官方基本写好了,只需要简单的指定io口即可。函数里面,根据传递的参数,拉低或者拉高SCL以及SDA。

uint8_t u8x8_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{switch (msg){case U8X8_MSG_DELAY_100NANO: // delay arg_int * 100 nano seconds__NOP();break;case U8X8_MSG_DELAY_10MICRO: // delay arg_int * 10 micro secondsfor (uint16_t n = 0; n < 320; n++){__NOP();}break;case U8X8_MSG_DELAY_MILLI: // delay arg_int * 1 milli secondDelay_ms(1);break;case U8X8_MSG_DELAY_I2C: // arg_int is the I2C speed in 100KHz, e.g. 4 = 400 KHzDelay_us(5);break;                    // arg_int=1: delay by 5us, arg_int = 4: delay by 1.25uscase U8X8_MSG_GPIO_I2C_CLOCK: // arg_int=0: Output low at I2C clock pinif(arg_int == 1) {GPIO_SetBits(IIC_GPIO_Port, SCL_Pin);}else if(arg_int == 0){GPIO_ResetBits(IIC_GPIO_Port, SCL_Pin);  }  break;                    // arg_int=1: Input dir with pullup high for I2C clock pincase U8X8_MSG_GPIO_I2C_DATA:  // arg_int=0: Output low at I2C data pinif(arg_int == 1) {GPIO_SetBits(IIC_GPIO_Port, SDA_Pin);}else if(arg_int == 0){GPIO_ResetBits(IIC_GPIO_Port, SDA_Pin);  } break;                    // arg_int=1: Input dir with pullup high for I2C data pincase U8X8_MSG_GPIO_MENU_SELECT:u8x8_SetGPIOResult(u8x8, /* get menu select pin state */ 0);break;case U8X8_MSG_GPIO_MENU_NEXT:u8x8_SetGPIOResult(u8x8, /* get menu next pin state */ 0);break;case U8X8_MSG_GPIO_MENU_PREV:u8x8_SetGPIOResult(u8x8, /* get menu prev pin state */ 0);break;case U8X8_MSG_GPIO_MENU_HOME:u8x8_SetGPIOResult(u8x8, /* get menu home pin state */ 0);break;default:u8x8_SetGPIOResult(u8x8, 1); // default return valuebreak;}return 1;
}

最后对OLED初始化

void oled_init(void)
{u8g2_Setup_ssd1306_128x64_noname_f(&u8g2, U8G2_R0, u8x8_byte_4wire_sw_spi, gpio_and_delay_cb);  // 初始化u8g2u8g2_InitDisplay(&u8g2);                // 初始化显示器u8g2_SetPowerSave(&u8g2, 0);            // 唤醒显示器u8g2_ClearBuffer(&u8g2);                // 清空缓冲区的内容
}


 

main.c的代码#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "stdio.h"
#include "u8g2.h"
#include "u8g2_C.h" void process_Test(u8g2_t *u8g2);
int main(void)
{    IIC_Init();     u8g2_t u8g2;u8g2Init(&u8g2);while(1){ Delay_ms(100);u8g2_ClearBuffer(&u8g2);process_Test(&u8g2);u8g2_SendBuffer(&u8g2); }
}//进度条显示
void process_Test(u8g2_t *u8g2)
{for(int i=10;i<=80;i=i+2){u8g2_ClearBuffer(u8g2); char buff[20];sprintf(buff,"%d%%",(int)(i/80.0*100));u8g2_DrawStr(u8g2,0,i,"1");//字符显示u8g2_SetFont(u8g2,u8g2_font_ncenB18_tf);         //设置字体u8g2_DrawStr(u8g2,24,32,"STM32");//字符显示u8g2_SetFont(u8g2,u8g2_font_ncenB08_tf);u8g2_DrawStr(u8g2,100,49,buff);//当前进度显示u8g2_DrawRBox(u8g2,16,40,i,10,4);//圆角填充框矩形框u8g2_DrawRFrame(u8g2,16,40,80,10,4);//圆角矩形u8g2_SendBuffer(u8g2);}
}

最后效果图

更多推荐

U8g2移植在STM32

本文发布于:2024-02-27 05:16:55,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1705317.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!