嵌⼊式linux学习笔记--i2c协议的应⽤--基于imx6ull点亮oled
上周末着重看了IIC协议的内容,也尝试着⾃⼰抄了韦东⼭⽼师的虚拟IIC总线的内容,⽆奈还是不能完全理解,所以先记录⼀下最近的IIC的应⽤过程。
去⽹上IIC的应⽤不外乎就是两种主要的思路,⼀种是使⽤ioctl() 这个函数,⼀种就是直接使⽤标准的read() write() 去操作 直接当做⽂件去进⾏读写。
这⾥我使⽤的是 ioctl() 的做法。 实现了点亮了 ssd1306 驱动的0.96⼨OLED。
详细的接线过程就不去赘述了,这⾥的实现是在韦东⼭⽼师的i.mx 6ull pro 开发板上实现的,⾃⼰飞线引出了开发板板载的i2c0.
关于oled 的初始化⽅⾯使⽤的是⾏刷新模式,⼀次性写⼊1K的数据,这样可以⼀次刷新⼀整个的屏幕的信息。⽽且对应的全局的buffer 可以实现显存buffer的使⽤。
代码如下:
#include <errno.h>
#include <stddef.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
韦东山嵌入式linux视频#include <stdio.h>
#include "./i2c/smbus.h"
#include <sys/stat.h>
#include <fcntl.h>
#include <memory.h>
#define dev_path "/dev/i2c-0"
#define frame_buf_size 1025
/
/ struct i2c_msg {
// __u16 addr; /* slave address */
// __u16 flags;
// #define I2C_M_RD 0x0001 /* read data, from slave to master */
// /* I2C_M_RD is guaranteed to be 0x0001! */
// #define I2C_M_TEN 0x0010 /* this is a ten bit chip address */
// #define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */
// #define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */
// #define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
// #define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
// #define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_NOSTART */
/
/ #define I2C_M_STOP 0x8000 /* if I2C_FUNC_PROTOCOL_MANGLING */
// __u16 len; /* msg length */
// __u8 *buf; /* pointer to msg data */
// };
// struct i2c_rdwr_ioctl_data {
// struct i2c_msg __user *msgs; /* pointers to i2c_msgs */
// __u32 nmsgs; /* number of i2c_msgs */
// };
class oled{
public:
int oled_write_cmd(unsigned char cmd);
int oled_write_dat(unsigned char dat);
int oled_write_frame(void);
int oled_init(const char*dev);
unsigned char*get_fram_buf_ptr(void);
oled();
private:
unsigned char frame_buf[frame_buf_size];
struct i2c_rdwr_ioctl_data msg_rdwr;
struct i2c_msg i2cmsg;
int fd;
};
void temp(oled &o);// 临时放点字符进去,懒得搞字库了
int main(void)
{
oled o_class;
unsigned char*p_buffer;
unsigned int cnt =0;
if(o_class.oled_init(dev_path)){
perror("oled_init() faild!");
return-1;
}
p_buffer = _fram_buf_ptr();
/
/ p_buffer[1] = 0x1;
while(1)
{
p_buffer[(cnt++)%1024]=1;
o_class.oled_write_frame();
}
}
int oled::oled_write_cmd(unsigned char cmd)
{
int err;
this->msg_rdwr.msgs =&(this->i2cmsg);
this->sgs =1;
this->i2cmsg.addr =0x3c;
this->i2cmsg.flags =0;
this->i2cmsg.len =2;
this->i2cmsg.buf =this->frame_buf;
this->frame_buf[0]=0x00;
this->frame_buf[1]= cmd;
if((err=ioctl(this->fd,I2C_RDWR,&(this->msg_rdwr)))<0){ perror("ioctl()");
fprintf(stderr,"ioctl returned %d\n",err);
return-1;
}
return0;
}
int oled::oled_write_dat(unsigned char dat)
{
int err;
this->msg_rdwr.msgs =&(this->i2cmsg);
this->sgs =1;
this->i2cmsg.addr =0x3c;
this->i2cmsg.flags =0;
this->i2cmsg.len =2;
this->i2cmsg.buf =this->frame_buf;
this->frame_buf[0]=0x40;
this->frame_buf[1]= dat;
if((err=ioctl(this->fd,I2C_RDWR,&(this->msg_rdwr)))<0){ perror("ioctl()");
fprintf(stderr,"ioctl returned %d\n",err);
return-1;
}
return0;
}
int oled::oled_write_frame(void)
{
int err;
this->msg_rdwr.msgs =&(this->i2cmsg);
this->sgs =1;
this->i2cmsg.addr =0x3c;
this->i2cmsg.flags =0;
this->i2cmsg.len =1025;
this->i2cmsg.buf =this->frame_buf;
this->frame_buf[0]=0x40;
if((err=ioctl(this->fd,I2C_RDWR,&(this->msg_rdwr)))<0){
perror("ioctl()");
fprintf(stderr,"ioctl returned %d\n",err);
return-1;
}
return0;
}
oled::oled()
{
memset(this->frame_buf,0,frame_buf_size);
fd =-1;//init at init function;
}
unsigned char* oled::get_fram_buf_ptr(void)
{
return(this->frame_buf);// the first bit is 0x40 means data }
int oled::oled_init(const char*dev)
{
this->fd =open(dev_path,O_WRONLY,0666);
if(fd<0)
{
perror("open file faild\n");
return-1;
}
this->oled_write_cmd(0x10);
this->oled_write_cmd(0xB0);
this->oled_write_cmd(0xC8);
this->oled_write_cmd(0x00);
this->oled_write_cmd(0x10);
this->oled_write_cmd(0x10);
this->oled_write_cmd(0x40);
this->oled_write_cmd(0x81);
this->oled_write_cmd(0xdf);
this->oled_write_cmd(0xa1);
this->oled_write_cmd(0xa6);
this->oled_write_cmd(0xa8);
this->oled_write_cmd(0x3f);
this->oled_write_cmd(0xa4);
this->oled_write_cmd(0xd3);
this->oled_write_cmd(0x00);
this->oled_write_cmd(0xd5);
this->oled_write_cmd(0xf0);
this->oled_write_cmd(0xd9);
this->oled_write_cmd(0x22);
this->oled_write_cmd(0xda);
this->oled_write_cmd(0x12);
this->oled_write_cmd(0xdb);
this->oled_write_cmd(0x20);
this->oled_write_cmd(0x8d);
this->oled_write_cmd(0x14);
this->oled_write_cmd(0xaf);
this->oled_write_cmd(0x20);
this->oled_write_cmd(0x00);
this->oled_write_cmd(0xb0);
this->oled_write_cmd(0x00);
this->oled_write_cmd(0x10);
this->oled_write_cmd(0x00);
this->oled_write_cmd(0x00); }
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论