导航

    全志在线开发者论坛

    • 注册
    • 登录
    • 搜索
    • 版块
    • 话题
    • 在线文档
    • 社区主页

    Neza-D1开发板学习之I2C-OLED篇

    MR Series
    1
    1
    1492
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • X
      xfdr0805 LV 5 最后由 编辑

      1. Neza-D1开发板扩展IO上引出了I2C2,从原理图上看,已经接了PCF8574@38了,总线速度400K,我们的OLED也是接在这上边的,由于这屏幕比较小,显示不了多少东西,就不用FB方式了,直接在应用层操作OLED,所以设备树也不需要配置
        2021-09-10 22-07-43屏幕截图.png

      2. 在应用层操作就跟单片机操作是一样的了,这里为了方便操作屏幕,我分辨率移植u8g2这个库,我手里的哦了的是1.3"的,驱动IC是SHT1106,用1306也可以,只能显示不满屏,可能是基地址定义的不一样

      3. 我们不需要从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);
         }
        
      4. 移植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;
         }
        
      5. 这就移植完了,带中文字库,可以直接显示中文,非常方便,做一个显示信息的小玩意儿还是非常方便的,下边编译一下传到开发板里,可以看到显示成功(图片)

      6. 最后附上完整工程供参考
        neza_d1_u8g2_oled.7z

      1 条回复 最后回复 回复 引用 分享 0
      • 1 / 1
      • First post
        Last post

      Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号

      行为准则 | 用户协议 | 隐私权政策