GD32F4移植u8g2
GD32F4移植u8g2库
1.获取并修改u8g2源代码

u8g2的源码可以从 https://github.com/olikraus/u8g2 下载,下载好的源码中csrc文件夹下的文件为所需的源代码,经过下列裁剪后加入到工程中:
u8x8_d_d开头的文件为硬件驱动,只保留自己使用的屏幕的驱动(如u8x8_d_sdd1306_128x64_noname.c),其余文件都删除;- 裁剪
u8g8_d_setup.c文件,如删除u8g2_Setup_sdd1306_i2c_128x64_noname_f以外的其他函数; - 裁剪
u8g2_d_memory.c文件,如删除u8g2_m_16_8_f()以外的其他函数; - 裁剪
u8g2_fonts.c和u8x8_fonts.c文件,这两个文件为字体文件,可以保留副本后根据需要添加字体。
2.回调函数
u8g2已经包含了屏幕驱动,我们只需给出i2c的实现方式即可,使用软件i2c时需要给出回调函数u8x8_gpio_delay_sw()用于模拟时序,使用硬件i2c则需要回调函数u8x8_gpio_delay_hw()和i2c驱动函数u8x8_byte_hw_i2c()。
uint8_t u8x8_gpio_and_delay_sw(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg){
case U8X8_MSG_GPIO_AND_DELAY_INIT:
gpio_sw_config();
break;
case U8X8_MSG_DELAY_MILLI:
delay_ms(arg_int);
break;
case U8X8_MSG_DELAY_10MICRO:
delay_us(10);
break;
case U8X8_MSG_DELAY_100NANO:
__NOP();
break;
case U8X8_MSG_GPIO_I2C_CLOCK:
if (arg_int) gpio_bit_write(I2C_SCL_PORT, I2C_SCL_PIN, SET);
else gpio_bit_write(I2C_SCL_PORT, I2C_SCL_PIN, RESET);;
break;
case U8X8_MSG_GPIO_I2C_DATA:
if (arg_int) gpio_bit_write(I2C_SDA_PORT, I2C_SDA_PIN, SET);
else gpio_bit_write(I2C_SDA_PORT, I2C_SDA_PIN, RESET);
break;
default:
return 0;
}
return 1;
}
uint8_t u8x8_gpio_and_delay_hw(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) {
switch (msg) {
case U8X8_MSG_DELAY_100NANO:
break;
case U8X8_MSG_DELAY_10MICRO:
break;
case U8X8_MSG_DELAY_MILLI:
delay_ms(1);
break;
case U8X8_MSG_DELAY_I2C:
break;
case U8X8_MSG_GPIO_I2C_CLOCK:
break;
case U8X8_MSG_GPIO_I2C_DATA:
break;
case U8X8_MSG_GPIO_MENU_SELECT:
u8x8_SetGPIOResult(u8x8, 0);
break;
case U8X8_MSG_GPIO_MENU_NEXT:
u8x8_SetGPIOResult(u8x8, 0);
break;
case U8X8_MSG_GPIO_MENU_PREV:
u8x8_SetGPIOResult(u8x8, 0);
break;
case U8X8_MSG_GPIO_MENU_HOME:
u8x8_SetGPIOResult(u8x8, 0);
break;
default:
u8x8_SetGPIOResult(u8x8, 1);
break;
}
return 1;
}
uint8_t u8x8_byte_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) {
uint8_t* data = (uint8_t*) arg_ptr;
switch(msg) {
case U8X8_MSG_BYTE_SEND:
while( arg_int-- > 0 ) {
i2c_data_transmit(I2CX, *data++);
while (!i2c_flag_get(I2CX, I2C_FLAG_BTC))
;
}
break;
case U8X8_MSG_BYTE_INIT:
i2c_hw_config();
break;
case U8X8_MSG_BYTE_SET_DC:
break;
case U8X8_MSG_BYTE_START_TRANSFER:
while(i2c_flag_get(I2CX, I2C_FLAG_I2CBSY))
;
i2c_start_on_bus(I2CX);
while(!i2c_flag_get(I2CX, I2C_FLAG_SBSEND))
;
i2c_master_addressing(I2CX, I2C_SLAVE_ADDR, I2C_TRANSMITTER);
while (!i2c_flag_get(I2CX, I2C_FLAG_ADDSEND))
;
i2c_flag_clear(I2CX, I2C_FLAG_ADDSEND);
break;
case U8X8_MSG_BYTE_END_TRANSFER:
i2c_stop_on_bus(I2CX);
while(I2C_CTL0(I2CX) & I2C_CTL0_STOP)
;
break;
default:
return 0;
}
return 1;
}
其中gpio_sw_config和i2c_hw_config分别为软件I2C的GPIO初始化、硬件I2C的GPIO和I2C初始化。
3.初始化u8g2
下面是初始化u8g2的代码,若使用软件I2C,则将u8x8_byte_hw_i2c和u8x8_gpio_and_delay_hw更改为u8x8_byte_sw_i2c和u8x8_gpio_and_delay_hw。
u8g2_t u8g2;
u8g2_Setup_ssd1306_i2c_128x64_noname_f(&u8g2, U8G2_R0, u8x8_byte_hw_i2c, u8x8_gpio_and_delay_hw);
u8g2_InitDisplay(&u8g2); // send init sequence to the display, display is in sleep mode after this,
u8g2_SetPowerSave(&u8g2, 0); // wake up display
u8g2_ClearBuffer(&u8g2); // clear the internal memory

浙公网安备 33010602011771号