STM32单片机移植u8g2图形库,使用软件I2C的驱动方式

一、硬件

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);
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值