Neza-D1开发板学习之I2C-OLED篇
-
-
Neza-D1开发板扩展IO上引出了I2C2,从原理图上看,已经接了PCF8574@38了,总线速度400K,我们的OLED也是接在这上边的,由于这屏幕比较小,显示不了多少东西,就不用FB方式了,直接在应用层操作OLED,所以设备树也不需要配置
-
在应用层操作就跟单片机操作是一样的了,这里为了方便操作屏幕,我分辨率移植u8g2这个库,我手里的哦了的是1.3"的,驱动IC是SHT1106,用1306也可以,只能显示不满屏,可能是基地址定义的不一样
-
我们不需要从OLED读取数据,所以只需要实现I2C写函数就可以,注意OLED模块上标的地址是0x78,这个是8位地址,这里使用的是7位地址,右移一位所以是0x3C
unsigned char i2c_init() { const char *i2c_dev = "/dev/i2c-2"; fd = open(i2c_dev, O_RDWR); if (fd < 0) { printf("not have /dev/i2c-2 t\r\n"); fflush(stdout); return -1; } return 0; } // I2C Addr 7bit unsigned char base_i2c_write(unsigned char device_addr, unsigned char *buff, int num) { struct i2c_rdwr_ioctl_data data; struct i2c_msg msgs_str[1]; data.msgs = msgs_str; data.nmsgs = 1; data.msgs[0].len = num; data.msgs[0].addr = device_addr; data.msgs[0].flags = 0; data.msgs[0].buf = buff; ioctl(fd, I2C_RDWR, (unsigned long)&data); }
-
移植u8g2 非常简单,只需修改这下边这个函数里初始化位置和写数据位置就行,另外一个是延时,可以不用修改
uint8_t u8x8_byte_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) { /* u8g2/u8x8 will never send more than 32 bytes between START_TRANSFER and END_TRANSFER */ static uint8_t buffer[128]; static uint8_t buf_idx; uint8_t *data; switch (msg) { case U8X8_MSG_BYTE_INIT: { /* add your custom code to init i2c subsystem */ i2c_init; // I2C初始化 } break; case U8X8_MSG_BYTE_START_TRANSFER: { buf_idx = 0; } break; case U8X8_MSG_BYTE_SEND: { data = (uint8_t *)arg_ptr; while (arg_int > 0) { buffer[buf_idx++] = *data; data++; arg_int--; } } break; case U8X8_MSG_BYTE_END_TRANSFER: { //i2c写函数 if (base_i2c_write(OLED_ADDRESS, buffer, buf_idx) != 0) return 0; } break; case U8X8_MSG_BYTE_SET_DC: break; default: return 0; } return 1; } 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 break; case U8X8_MSG_DELAY_10MICRO: // delay arg_int * 10 micro seconds break; case U8X8_MSG_DELAY_MILLI: // delay arg_int * 1 milli second 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 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 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; }
-
这就移植完了,带中文字库,可以直接显示中文,非常方便,做一个显示信息的小玩意儿还是非常方便的,下边编译一下传到开发板里,可以看到显示成功(图片)
-
最后附上完整工程供参考
neza_d1_u8g2_oled.7z
-
Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号