我有一些驱动程序代码,我正在测试用于SSD1306驱动的OLED屏幕,它是128x32(与OLED adafruit型号相同)。我需要这个在debian中运行(我正在使用Linario-4.4.9
)
我已经按照Debian指南了解如何开始为设备创建文件处理程序,这可以如下所示。 oled.h
中唯一的内容是设备地址(0x3C
)和原型类型。我遵循了对adafruit github采用的初始化方法(因为我首先在Ardunio上尝试了他们的代码,以确保屏幕确实工作)。我相信我可能做错了什么,但我不完全确定我做错了什么。我还在下面列出了我的init进程。
#include <errno.h>
#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <linux/i2c-dev.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include "oled.h"
int oled;
int lcd_driver_init(void)
{
///< Begin the init proc.
int dloc = open("/dev/i2c-1", O_RDWR);
if (dloc < 0 )
{
fprintf(stderr, "Error opening i2c device\n");
return -1;
}
if(ioctl(dloc, I2C_SLAVE, SCR_ADDR) < 0)
{
fprintf(stderr, "Error in ioctl. Errno :%i\n",errno);
return -2;
}
oled = dloc;
fprintf(stderr, "init success, device open and local\n");
return EXIT_SUCCESS;
}
int oled_command( uint8_t cmd)
{
char command[2]= {0};
command[1] = cmd;
int check = (write(oled, command, 2));
return check;
}
void oled_cmd_start()
{
int check = (write(oled, 0x00, sizeof(uint8_t)));
if(check<0)
fprintf(stderr, "Errno set:: %i\n", errno);
return;
}
void oled_data_start()
{
uint8_t _data_start_[1] ={ 0x40 };
int check = (write(oled, _data_start_, sizeof(uint8_t)));
if(check<0)
fprintf(stderr, "Errno set oled_data_start:: %i\n", errno);
return;
}
int oled_data (uint8_t xmit)
{
int check = (write(oled, &xmit, (sizeof(uint8_t))));
if(check<0)
fprintf(stderr, "Errno set oled_data:: %i\n", errno);
return check;
}
void sendcommand(unsigned char payload)
{
oled_data(0x00); //Control Byte - Command
oled_data(payload); //payload
}
void lcd_init(void)
{
sendcommand(0xAE);//--Set Display off
sendcommand(0x00);//--set low column address
sendcommand(0x10);//--set high column address
sendcommand(0x81);//--set contrast control register
sendcommand(0x7f);
sendcommand(0xa1);//--set segment re-map 95 to 0
sendcommand(0xA6);//--set normal display
sendcommand(0xa8);//--set multiplex ratio(1 to 16)
sendcommand(0x1f);//--duty 1/32
sendcommand(0xd3);//--set display offset
sendcommand(0x00);//--not offset
sendcommand(0xd5);//--set display clock divide ratio/oscillator frequency
sendcommand(0xf0);//--set divide ratio
sendcommand(0xd9);//--set pre-charge period
sendcommand(0x22);
sendcommand(0xda);//--set com pins hardware configuration
sendcommand(0x02);//disable left/right remap and set for sequential
sendcommand(0xdb);//--set vcomh
sendcommand(0x49);//--0.83*vref
sendcommand(0x8d);//--set DC-DC enable
sendcommand(0x14);//
sendcommand(0xAF);//--turn on oled panel
sendcommand(0xA4);//--Entire Display ON
}
在此之后,我发送交替0xFF
以尝试在屏幕上创建条纹。唯一出现的是随机像素。没有什么连贯的。
我已连接逻辑分析仪来嗅探I2C线路,看来当我连接LA时,I2C线路不再起作用,ERRNO
返回IO故障(#5)。
然而,开放设备以获取文件指针似乎不是一个问题。
我有时会将ERRNO
作为超时,但我已经读过这只是使用protocal的I2C设备的问题,write
期望比I2C更快的响应。
我也在使用-std=c99 -O0
进行编译,以确保所有内联函数都存在,并确保循环变量可用。
如果有人能指出我正确的方向可以指出我的方法中的一些缺陷,那将非常感激。谢谢。
我已检查设备树并正确启用了i2c设备。但是,似乎没有启用i2c_freq
速度。这会导致超时和垃圾数据传输吗?
答案 0 :(得分:1)
我已经连接了一个逻辑分析仪来嗅探I2C线路,看来当我连接LA时,I2C线路不再起作用,ERRNO会返回IO故障(#5)。
逻辑分析仪只是一种测量设备。它将捕获的数据转换为时序图,解码您设置的协议。因此,它不会对任何I2C读写错误负责(直到接地和h / w连接正确)。
对于超时问题,您可以尝试降低i2c clock-frequency
或ioctl I2C_TIMEOUT
。
答案 1 :(得分:0)
事实证明,SOM有一个内部稳压器,用于I2C线路为1V8,而SSD1306芯片的运行电压为3V3,导致信息处理不当。 SOM上未记录此行为。
将电平转换芯片应用于设计允许正确通信。
如果有人遇到同样的问题,请检查原理图中的电压不匹配等级。