声明:本次使用软件IIC(就是使用IO口翻动来模拟IIC协议),因此不使用硬件IIC的任何函数及接口,选用I2C1接口是为了下一篇文章硬件IIC驱动时不用重新接线。
本次u8g2
的移植应用于所有单色屏,对标于彩屏的lvgl
库,只不过,u8g2
多了屏幕的驱动部分,而lvgl
库只是GUI库,不包含屏幕底层驱动部分。因此,两个相差不是很大,移植,也只是简单移植所有接口,使得u8g2
库能调用当前MCU的IO口,官方的移植文档可参考wiki。
本次我们驱动IIC接口的SSD1306屏幕,需要使用CH32V307的I2C1接口。从手册中可以看到,I2C1接口的对应关系如下,请按照下表接线:
CH32V307接口 | IO功能 | SSD1306屏幕接口 |
---|---|---|
GND | 地 | GND |
VCC | 3.3V | VCC |
PB6 | I2C1-SCL | SCL |
PB7 | I2C1-SDA | SDA |
接线后如图:
github链接 下载命令git clone https://github.com/olikraus/u8g2.git
gitee链接 下载命令git clone https://gitee.com/liuzewen/u8g2.git
从上面挑选一个链接下载代码,代码结构如下:
我们本次只使用csrc
目录下的源码。
GPIO
的例子,命名为U8g2
,也可不修改,如图:U8g2
目录,将里面的文件夹命名为U8g2-ssd1306
,也可不修改,如图:U8g2-ssd1306
项目下新建u8g2
目录,并将我们下载的u8g2/csrc
下的所有文件拷贝进新建的u8g2
目录,操作如图:MounRiver Studio IDE
打开此项目,并点击项目属性,如图:在里面添加/${ProjName}/u8g2
目录,如图:
应用后,你的目录里面就会多出我们刚才新建的u8g2目录啦
#include "u8g2.h"
u8g2_t u8g2;
CH32_gpio_and_delay
函数会被调用,在此函数中,你可以控制CH32V307的IO口翻动:u8g2_Setup_ssd1306_i2c_128x64_noname_f(&u8g2, U8G2_R0, u8x8_byte_sw_i2c, CH32_gpio_and_delay);
CH32_gpio_and_delay
函数如下:uint8_t CH32_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 seconds
for (uint16_t n = 0; n < 320; n++) {
__NOP();
}
break;
case U8X8_MSG_DELAY_MILLI: // delay arg_int * 1 milli second
Delay_Ms(1);
break;
case U8X8_MSG_DELAY_I2C: // arg_int is the I2C speed in 100KHz, e.g. 4 =
// 400 KHz
delay_us(5);
break; // arg_int=1: delay by 5us, arg_int = 4: delay by 1.25us
case U8X8_MSG_GPIO_I2C_CLOCK: // arg_int=0: Output low at I2C clock pin
if (arg_int == 1) // arg_int=1: Input dir with pullup high for I2C clock pin
GPIO_WriteBit(GPIOB, SCL_Pin, 1);
else if (arg_int == 0)
GPIO_WriteBit(GPIOB, SCL_Pin, 0);
break;
case U8X8_MSG_GPIO_I2C_DATA: // arg_int=0: Output low at I2C data pin
if (arg_int == 1) // arg_int=1: Input dir with pullup high for I2C data pin
GPIO_WriteBit(GPIOB, SDA_Pin, 1);
else if (arg_int == 0)
GPIO_WriteBit(GPIOB, SDA_Pin, 0);
break;
case 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 value
break;
}
return 1;
}
使用的图片数组为工具转化,请参考我另一篇文章:【《Arduino》开发 之 用 u8g2 库 给 0.96寸OLED 刷bmp图片,OLED图片取模】
本次粗略用u8g2点亮了SSD1306的屏幕,但是,使用的SW IIC接口实现不了高刷新率,下次,我们采用HW IIC来驱动,相信效果一定会更赞。
更多回帖