又是记录 学习 嵌入式 Linux 的 一天。(写毕业论文真是难顶,牵涉东西太多了,学得太杂了,像QT、Opencv、深度学习 Keras 搭 cnn ,后续考虑介绍一下毕设)
在看完原子的Linux l2C 驱动实验视频后,通过 ap3216 这个 光传感器编写了 Linux 下的 I2C 设备驱动程序,但是我用不上这个传感器。
手上刚好有一个IIC控制的oled , 抱着学习Linux l2C 框架的目的,就通过这个小小的 屏幕 来 更多地实践一下。
顺便 把 DHT 11 这个 单总线的 温 湿 度 传感器也回顾 一下。
首先,要 修改 DTB 设备树 ,如下图 所示 ,在 l2c1 的 节点下 添加 oled 节点, 3c 是 设备地址。 在 STM32 中,这个 值是 0x78 = 0111 1000
由于linux 的 i2c 地址 是 7位 , 故 0x78 = 0111 1000 = 111 1000 = 0x3c
根据 视频教程, 可直接 把 ap3216 的 整体 驱动 copy 过来 ,把 相关的 函数名 修改好就行了, 反正 框架是固定的(手动再敲一遍,太累了)
由于 之前 都是 学习 STM32的 , 我就 把 相关 的 代码 移植 过来。
以下是 STM32 oled 初始化 程序 截图
感觉oled.c 这个 文件 中 所有 用到东西 移植 一遍 到 linux 下,模拟i2c 的 函数 就不用写了。记得器件地址3C,命令控制配置寄存器地址0x00, 数据寄存器地址0x40就行了
linux 的 I2C 驱动 编写 比较 方便 , I2C 总线驱动 不用 自己写(NXP 编写 好 了),开发者 只需 编写 I2C设备驱动,具体 我就 不 详细 讲了 , 教程 手册 自己看吧(懒得copy)
最主要的就是 给 OLED 这个从机 写 寄存器了
然后就是 相关的 初始化了 (参考 STM32 的初始化 过程)
向 oled 写 数据 就像 上图 一样,改变寄存器地址 为0x40 和 想要填写的数据就行了,挺简单的。
通过原子的 Makefile , make 一下 获得 .ko文件后,测试 一下 加载和卸载 有没有问题,看 /dev/oled 存不存在
我在probe函数中 就 写了 显示 相关文字进行测试,如下图
驱动写好后,就要 编写 app 测试 程序了(由于 dht11 之前自己写过,我就不在这里 赘述,有想要了解可以自己去查其他博客)
int main(int argc, char *argv[])
{
int dht11fd,oledfd,ret,oled_ret;
unsigned char buf[4];//数据缓存区
dht11fd = open("/dev/dht11", O_RDONLY);
if(dht11fd < 0){
printf("/dev/dht11 open fail\n");
return 0;
}
oledfd = open("/dev/oled", O_RDWR);
if(dht11fd < 0){
printf("/dev/oled open fail\n");
return 0;
}
while(1){
// printf("dht11fd = %d\n",dht11fd);
ret = read(dht11fd, buf, sizeof(buf));
if(ret < 0)
printf("read err!\n");
else{
printf("humidity = %d.%d%%\ttemp = %d.%d\n",
buf[0], buf[1],buf[2], buf[3]);
oled_ret = write(oledfd, buf, sizeof(buf));
if(oled_ret < 0)
printf("write err!\n");
}
sleep(2);//采样时间
}
close(dht11fd); /* 关闭文件 */
close(oledfd); /* 关闭文件 */
return 0;
}
编写app后,记得 arm-linux-gnueabihf-gcc oledAPP.c -o oledApp
在加载 oled、dht11 驱动后,运行oledApp,结果如下