• 香蕉派 I2C点亮OLED


    香蕉派 I2C点亮OLED

    最近比赛项目需要在香蕉派上利用oled显示收到的数据,于是淘宝买了一块0.91寸、IIC驱动的oled屏幕,然而店家只提供了一份51单片机的驱动程序,需要自己移植到香蕉派上,踩了一些小坑,记录一波。

    实验器材:

    1. 一块BPI M64的板子,系统为Ubuntu 16.04.3 LTS
    2. 0.91寸OLED模块,控制芯片为SSD1306
    3. 逻辑分析仪

    实验步骤

    1. 首先测试香蕉派的IIC通信是否正常,系统dev目录下已有两个设备i2c-0、i2c-1。只需要写用户态的程序就可以了,查看M64的管脚图可以看到确实有两个,一个在3、5脚;一个在27、28脚。
      BPI M64管脚图
      那么只有分别尝试一下了,利用逻辑分析仪查看那个管脚有波形就可以了,不赘述。这里发现对i2c-1写入时3、5脚有波形,看来这两个是对应的。程序如下:
    	int fd = open("/dev/i2c-1", O_RDWR);
    	if (fd < 0)
    	{
    		printf("i2c open failed
    ");
    		return -1;
    	}
    	struct i2c_rdwr_ioctl_data data;
    	data.msgs = (struct i2c_msg *)malloc(2 * sizeof(struct i2c_msg));
    	uint8_t sendbuf[sizeof(uint8_t) + 1] = {0};
    	data.nmsgs = 1; //消息的数目
    	data.msgs[0].len = 2;//1个写入目标的reg地址和1个数据
    	data.msgs[0].addr = 0x78;//i2c设备地址
    	data.msgs[0].flags = 0;//flags为0:表示写;为1:表示读.
    	data.msgs[0].buf = sendbuf;//申请内存为2个Byte
    	data.msgs[0].buf[0] = 0x00;//i2c设备要操作的reg地址
    	data.msgs[0].buf[1] = 0x00;//向reg写入的值
    	ioctl(fd,I2C_RDWR,(uint64_t)&data);
    }
    

    2 然后测试香蕉派是否可以和oled通信。这里我犯了一个傻,直接将香蕉派的I2C管脚和逻辑分析仪连接,然后发现发送的信号永远只有地址,没有下文了。然后才反应过来,I2C每发送一位,都需要一个ack的确认信号,我没有和oled相连,就没有信号确认,香蕉派就不会继续发送数据。于是将香蕉派和oled连接上,然后在SCL和SDA中引出一根线连接逻辑分析仪。

    3 接下来又是一个坑,具体是这样的:我查看卖家的51单片机程序,他是通过GPIO口模拟IIC通信协议实现的,他在发送每位时发送的从机地址位0x78,于是我在程序中也设置地址位0x78,结果oled并没有反应,逻辑分析仪显示波形如下:
    设置地址位0x78的波形

    4 折腾了一下午,直到看到这篇博客:为什么i2c从机地址要左移一位。i2c每次发送8位,最后一位为读写控制位,也就是说7位的地址需要左移一位才可以被正确的识别。那么问题又来了,为什么逻辑分析中显示发送的地址为0xF0呢。在网上查阅到SSD1306的IIC地址位0x3C,也就是说单片机程序已经将0x3C左移了一位变成了0x78,为什么从机还是不应答呢,根据逻辑分析仪可以发现,linux内核中肯定已经左移了一位,所以0x78变成了0xF0。那么只需要填入原来的地址即可,也就是0x3C。最后,成功通信:

    设置地址位0x3C的波形

    5 后面就没什么好说的了,单片机程序没什么地方需要改动,直接复制过来,改一下代码风格就是自己的了,最后成功点亮。
    成功点亮

  • 相关阅读:
    7段数码管绘制
    画五角星
    绘制正方形
    蟒蛇的绘制
    玫瑰花
    小猪佩奇
    数列求和
    水仙花数
    鸡兔同笼
    画国际象棋盘
  • 原文地址:https://www.cnblogs.com/sakurapiggy/p/13021140.html
Copyright © 2020-2023  润新知