一、硬件
STM32F103ZET6单片机、0.96寸4线IIC OLED屏 SSD1306 128x64
二、软件
STM32F103ZET6单片机的一个LED例程(这里采用标准库)
三、u8g2图形库
下载地址
https://github.com/olikraus/u8g2
四、对u8g2图形库的源码进行裁剪
1、删除多余的驱动文件
在源码目录下\u8g2-master\csrc\,类似u8x8_d_xxx.c文件对应为各钟OLED屏的驱动型号,这里使用SSD1306 128x64的屏幕,所以只保留u8x8_d_ssd1306_128x64_noname.c这个文件即可,其余的删除。
在删除文件时注意保留以下这两个文件:u8g2_d_memory.c、u8g2_d_setup.c

2、修改u8g2_d_setup.c文件
u8g2_d_setup.c文件主要为一些显示接口函数。
在u8g2_d_setup.c文件中只保留u8g2_Setup_ssd1306_i2c_128x64_noname_f()这一个函数即可,其余的删除。

3、修改u8g2_d_memory.c文件
u8g2_d_memory.c文件用于管理显示内存。
在u8g2_d_memory.c文件中只保留u8g2_m_16_8_f()这一个函数即可,其余的删除。

4、修改u8x8_fonts.c和u8g2_fonts.c文件
u8x8_fonts.c和u8g2_fonts.c文件为字体文件,可以根据需要裁剪。
五、将裁剪好的文件移植到自己的工程文件中
只需要将源码目录下\u8g2-master\csrc\的.c和.h文件移植到自己的工程文件中

1、添加文件路径

2、添加项目

六、编译测试移植的文件
1、出现declaration may not appear after executable statement in block报错
错误解释:变量声明不能出现在可执行的语句之后。
解决方法:开启C99 Mode

2、出现L6406E: No space in execution regions with .ANY selector matching u8x8_display.o(.text).错误
解决方法:增加优化等级,Level 0 (-O0)改为Level 3 (-O3)

七、添加OLED的IO配置文件
1、bsp_oled.c
/**
* @brief 初始化控制OLED的IO
* @param 无
* @retval 无
*/
void OLED_GPIO_Config(void)
{
/*定义一个GPIO_InitTypeDef类型的结构体*/
GPIO_InitTypeDef GPIO_InitStructure;
/*开启OLED相关的GPIO外设时钟*/
RCC_APB2PeriphClockCmd(IIC_OLED_SCL_GPIO_CLK, ENABLE);
/*选择要控制的GPIO引脚*/
GPIO_InitStructure.GPIO_Pin = IIC_OLED_SCL_PIN;
/*设置引脚模式为通用推挽输出*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
/*设置引脚速率为50MHz */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/*调用库函数,初始化GPIOB*/
GPIO_Init(IIC_OLED_SCL_GPIO, &GPIO_InitStructure);
/*开启OLED相关的GPIO外设时钟*/
RCC_APB2PeriphClockCmd(IIC_OLED_SDA_GPIO_CLK, ENABLE);
/*选择要控制的GPIO引脚*/
GPIO_InitStructure.GPIO_Pin = IIC_OLED_SDA_PIN;
/*设置引脚模式为通用推挽输出*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
/*设置引脚速率为50MHz */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/*调用库函数,初始化GPIOB*/
GPIO_Init(IIC_OLED_SDA_GPIO, &GPIO_InitStructure);
}
void IIC_OLED_SDA_HIGH(void)
{
GPIO_SetBits(IIC_OLED_SDA_GPIO,IIC_OLED_SDA_PIN);
}
void IIC_OLED_SDA_LOW(void)
{
GPIO_ResetBits(IIC_OLED_SDA_GPIO,IIC_OLED_SDA_PIN);
}
void IIC_OLED_SCL_HIGH(void)
{
GPIO_SetBits(IIC_OLED_SCL_GPIO,IIC_OLED_SCL_PIN);
}
void IIC_OLED_SCL_LOW(void)
{
GPIO_ResetBits(IIC_OLED_SCL_GPIO,IIC_OLED_SCL_PIN);
}
2、bsp_oled.h
#define IIC_OLED_SDA_PIN GPIO_Pin_7
#define IIC_OLED_SDA_GPIO GPIOB
#define IIC_OLED_SDA_GPIO_CLK RCC_APB2Periph_GPIOB
#define IIC_OLED_SCL_PIN GPIO_Pin_6
#define IIC_OLED_SCL_GPIO GPIOB
#define IIC_OLED_SCL_GPIO_CLK RCC_APB2Periph_GPIOB
void OLED_GPIO_Config(void);
void IIC_OLED_SDA_HIGH(void);
void IIC_OLED_SDA_LOW(void);
void IIC_OLED_SCL_HIGH(void);
void IIC_OLED_SCL_LOW(void);
八、u8g2绘制测试
1、初始化u8g2
定义一个u8g2_t类型的结构体,用于初始化u8g2,后续的显示都需要用到该结构体
//定义一个u8g2_t类型的结构体,里面包含了屏幕显示的一些参数定义
u8g2_t u8g2_test;
2、增加回调函数,用于模拟I2C时序
uint8_t u8g2_gpio_and_delay(U8X8_UNUSED u8x8_t *u8x8, U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DELAY_MILLI://Function which implements a delay, arg_int contains the amount of ms
SysTick_Delay_Ms(arg_int);
break;
case U8X8_MSG_DELAY_10MICRO://Function which delays 10us
SysTick_Delay_Us(10);
break;
case U8X8_MSG_DELAY_100NANO://Function which delays 100ns
__NOP();
break;
case U8X8_MSG_GPIO_I2C_CLOCK:
if(arg_int)
{
IIC_OLED_SCL_HIGH();
}
else
{
IIC_OLED_SCL_LOW();
}
break;
case U8X8_MSG_GPIO_I2C_DATA:
if(arg_int)
{
IIC_OLED_SDA_HIGH();
}
else
{
IIC_OLED_SDA_LOW();
}
break;
default:
return 0; //A message was received which is not implemented, return 0 to indicate an error
}
return 1; // command processed successfully.
}
注意:SysTick_Delay_Ms()和SysTick_Delay_Us()可以根据自己的实际项目进行配置
3、初始化u8g2
void u8g2_init(void)
{
u8g2_Setup_ssd1306_i2c_128x64_noname_f(&u8g2_test, U8G2_R0, u8x8_byte_sw_i2c, u8g2_gpio_and_delay); //链接u8g2的配置
u8g2_InitDisplay(&u8g2_test); //初始化序列发送到显示器
u8g2_SetPowerSave(&u8g2_test, 0); //打开显示器
u8g2_ClearBuffer(&u8g2_test); //清除显示缓存
}
4、测试
void draw(u8g2_t *u8g2)
{
u8g2_ClearBuffer(u8g2);
u8g2_SetFontMode(u8g2, 1);
u8g2_SetFontDirection(u8g2, 0);
u8g2_SetFont(u8g2, u8g2_font_inb24_mf);
u8g2_DrawStr(u8g2, 0, 20, "U");
u8g2_SetFontDirection(u8g2, 1);
u8g2_SetFont(u8g2, u8g2_font_inb30_mn);
u8g2_DrawStr(u8g2, 21,8,"8");
u8g2_SetFontDirection(u8g2, 0);
u8g2_SetFont(u8g2, u8g2_font_inb24_mf);
u8g2_DrawStr(u8g2, 51,30,"g");
u8g2_DrawStr(u8g2, 67,30,"\xb2");
u8g2_DrawHLine(u8g2, 2, 35, 47);
u8g2_DrawHLine(u8g2, 3, 36, 47);
u8g2_DrawVLine(u8g2, 45, 32, 12);
u8g2_DrawVLine(u8g2, 46, 33, 12);
u8g2_SetFont(u8g2, u8g2_font_4x6_tr);
u8g2_DrawStr(u8g2, 1,54,"github.com/olikraus/u8g2");
u8g2_SendBuffer(u8g2);
}
/**
* @brief 主函数
* @param 无
* @retval 无
*/
int main(void)
{
/* LED 端口初始化 */
LED_GPIO_Config();
/* OLED 端口初始化 */
OLED_GPIO_Config();
/* u8g2 初始化 */
u8g2_init();
SysTick_Delay_Ms(1000);
while(1)
{
draw(&u8g2_test);
SysTick_Delay_Ms(1000);
}
}

6615

被折叠的 条评论
为什么被折叠?



