本节学习oled的驱动。
偶尔看见群里有大佬使用u8g2 开源代码驱动oled,搜索了解了一下开源库,大概了解了移植流程。
刚好拿来移植学习学习。
使用的iic 1024缓存,删除不需要的文件,iic硬件读写。
-----------------------------------------------------------------------------------------------------------------------
玩不转,硬件模拟,没点亮屏幕,通过例程iic检测到设备,写数据发不出去,程序还死掉了。
换使用gpio模拟iic点亮。
引脚:使用与电源相邻的引脚 p2-3(sda) p2-4(scl)。
接线和效果如下
初始化代码,和引脚配置
#define SW_I2C_P MXC_GPIO2 #define SW_I2C_SCL_PIN MXC_GPIO_PIN_4 #define SW_I2C_SDA_PIN MXC_GPIO_PIN_3 void u8g2Init(u8g2_t *u8g2) { u8g2_Setup_ssd1315_i2c_128x64_noname_f(u8g2, U8G2_R0, u8x8_byte_sw_i2c, u8x8_gpio_and_delay); // 初始化 u8g2 结构体 u8g2_InitDisplay(u8g2); // 根据所选的芯片进行初始化工作,初始化完成后,显示器处于关闭状态 u8g2_SetPowerSave(u8g2, 0); // 打开显示器 u8g2_ClearBuffer(u8g2); }
控引脚和延时函数
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 seconds MXC_Delay(10); break; case U8X8_MSG_DELAY_MILLI: // delay arg_int * 1 milli second MXC_Delay(1000);; break; case U8X8_MSG_DELAY_I2C: // arg_int is the I2C speed in 100KHz, e.g. 4 = 400 KHz 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) { MXC_GPIO_OutSet(gpio_scl.port, gpio_scl.mask); }else if(arg_int == 0){ MXC_GPIO_OutClr(gpio_scl.port, gpio_scl.mask); } break; // arg_int=1: Input dir with pullup high for I2C clock pin case U8X8_MSG_GPIO_I2C_DATA: // arg_int=0: Output low at I2C data pin if(arg_int == 1) { MXC_GPIO_OutSet(gpio_sda.port, gpio_sda.mask); }else if(arg_int == 0){ MXC_GPIO_OutClr(gpio_sda.port, gpio_sda.mask); } break; // arg_int=1: Input dir with pullup high for I2C data pin 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; }
官方的显示图像函数。
void draw(u8g2_t *u8g2) { u8g2_SetFontMode(u8g2, 1); /*字体模式选择*/ u8g2_SetFontDirection(u8g2, 0); /*字体方向选择*/ u8g2_SetFont(u8g2, u8g2_font_wqy16_t_chinese2); /*字库选择*/ u8g2_DrawUTF8(u8g2, 90, 20, "你好啊"); 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); u8g2_ClearBuffer(u8g2); }
main函数,主要为初始化引脚,调用draw函数用于显示官方的例程图像。
// ***************************************************************************** int main(void) { printf("\n\n******** I2C SLAVE ADDRESS SCANNER *********\n"); printf("\nThis example finds the addresses of any I2C Slave devices connected to the"); printf("\nsame bus as I2C%d (SCL - P0.%d, SDA - P0.%d).\n", MXC_I2C_GET_IDX(I2C_MASTER), I2C_SCL_PIN, I2C_SDA_PIN); gpio_scl.port = SW_I2C_P; gpio_scl.mask = SW_I2C_SCL_PIN; gpio_scl.pad = MXC_GPIO_PAD_WEAK_PULL_UP; gpio_scl.func = MXC_GPIO_FUNC_OUT; gpio_scl.vssel = MXC_GPIO_VSSEL_VDDIO; gpio_scl.drvstr = MXC_GPIO_DRVSTR_0; MXC_GPIO_Config(&gpio_scl); gpio_sda.port = SW_I2C_P; gpio_sda.mask = SW_I2C_SDA_PIN; gpio_sda.pad = MXC_GPIO_PAD_WEAK_PULL_UP; gpio_sda.func = MXC_GPIO_FUNC_OUT; gpio_sda.vssel = MXC_GPIO_VSSEL_VDDIO; gpio_sda.drvstr = MXC_GPIO_DRVSTR_0; MXC_GPIO_Config(&gpio_sda); u8g2_t u8g2St; int error; //Setup the I2CM error = MXC_I2C_Init(I2C_MASTER, 1, 0); if (error != E_NO_ERROR) { printf("-->I2C Master Initialization failed, error:%d\n", error); return -1; } else { printf("\n-->I2C Master Initialization Complete\n"); } printf("-->Scanning started\n"); MXC_I2C_SetFrequency(I2C_MASTER, I2C_FREQ); reqMaster.i2c = I2C_MASTER; reqMaster.addr = 0x3C; reqMaster.tx_buf = NULL; reqMaster.tx_len = 0; reqMaster.rx_buf = NULL; reqMaster.rx_len = 0; reqMaster.restart = 0; reqMaster.callback = NULL; u8g2Init(&u8g2St); draw(&u8g2St); // u8g2_FirstPage(&u8g2St); int lcunt = 0; while(1){ lcunt++; MXC_Delay(MXC_DELAY_MSEC(1000)); log("wait [%d]",lcunt); } for (uint8_t address = 8; address < 120; address++) { printf("."); fflush(0); reqMaster.addr = address; if ((MXC_I2C_MasterTransaction(&reqMaster)) == 0) { printf("\nFound slave ID %03d; 0x%02X\n", address, address); counter++; } MXC_Delay(MXC_DELAY_MSEC(200)); } printf("\n-->Scan finished. %d devices found\n", counter); return 0; }
tips:
打印日志带了颜色,minicom如果要支持颜色显示,开启命令:minicom -c on