【课程设计】4.OLED屏显示-实现基础函数

2017-06-11  本文已影响227人  Murrey_Xiao

1. 前言

完成了小车的遥控部分后,考虑外加一个OLED屏来远程调参。Joystick上有一个LCD的模块插口,但是我手头上只有OLED,所以使用了它上面部分引脚口,并用模拟SPI方式实现对OLED的驱动。

接线图

2. OLED_SPI类

SPI通讯需要反复使用定位Set_Pos、Write_Byte等函数,为了防止代码冗余,我把它写成一个类。

OLED_SPI.h ↓ ↓ ↓
#define  u8 unsigned char   // 0~255
#define  u16 unsigned int   // 0~65535
#define  u32 unsigned long  // 0~4294967295

class OLED_SPI
{
public:
    /* 构造函数 初始化引脚 */
    OLED_SPI(u8 D0,u8 D1,u8 RES,u8 DC,u8 CS);
    
    /* 基础成员函数 */                        
    void Init();                    //引脚模式初始化 屏幕参数初始化
    void WR_Byte(u8 dat,u8 cmd);    //根据cmd值发送数据或命令  
    void Display_On();            //开启OLED显示  
    void Display_Off();          //关闭OLED显示  
    void Clear();               //清屏
    void Set_Pos(u8 x,u8 y);        //定位 x:0~127 y:0~7

    /* 其他函数 */
    void Dele_Row(u8 row);      //删除一整行 row(0~3)

    /* 引脚电平变化函数 */
    void OLED_CS_Set(u8 staus); 
    void OLED_RES_Set(u8 staus);
    void OLED_DC_Set(u8 staus);
    void OLED_SCL_Set(u8 staus);
    void OLED_SDA_Set(u8 staus);

private:
    u8 OLED_SCL;      //D0
    u8 OLED_SDA;     //D1
    u8 OLED_RES;      //RES
    u8 OLED_DC;    //DC
    u8 OLED_CS;    //CS
};

OELD_SPI.cpp ↓ ↓ ↓

(1) 构造函数:初始化各个引脚

//  OLED_SPI构造函数
OLED_SPI::OLED_SPI(u8 D0,u8 D1,u8 RES,u8 DC,u8 CS)
{
    this->OLED_SCL=D0;
    this->OLED_SDA=D1; 
    this->OLED_RES=RES;
    this->OLED_DC=DC;
    this->OLED_CS=CS;
}

(2) 引脚电平变化函数

/* 引脚电平变化函数 */
void OLED_SPI::OLED_SCL_Set(u8 staus)
{
    if(staus) digitalWrite(this->OLED_SCL,HIGH);
    else digitalWrite(this->OLED_SCL,LOW);
}
void OLED_SPI::OLED_SDA_Set(u8 staus)
{
    if(staus) digitalWrite(this->OLED_SDA,HIGH); 
    else digitalWrite(this->OLED_SDA,LOW); 
}
void OLED_SPI::OLED_RES_Set(u8 staus)
{
    if(staus) digitalWrite(this->OLED_RES,HIGH); 
    else digitalWrite(this->OLED_RES,LOW); 
}
void OLED_SPI::OLED_DC_Set(u8 staus)
{
    if(staus) digitalWrite(this->OLED_DC,HIGH); 
    else digitalWrite(this->OLED_DC,LOW); 
}
void OLED_SPI::OLED_CS_Set(u8 staus)
{
    if(staus) digitalWrite(this->OLED_CS,HIGH);
    else digitalWrite(this->OLED_CS,LOW); 
}

(3) 写字节函数:使用SPI通讯方式写一个字节

//  函数功能:向SSD1306写入一个字节。
//  dat:要写入的数据/命令
//  cmd:数据/命令标志 0,表示命令;1,表示数据;
void OLED_SPI::WR_Byte(u8 dat,u8 cmd)
{   
    u8 i;             
    if(cmd)
      OLED_DC_Set(1);       //写数据
    else 
      OLED_DC_Set(0);       //写命令
    OLED_CS_Set(0);         //片选先低后高 上升沿触发
    for(i=0;i<8;i++)        //发送数据
    {             
        OLED_SCL_Set(0);
        if(dat&0x80)
        {
           OLED_SDA_Set(1);
        }
        else
           OLED_SDA_Set(0);
        OLED_SCL_Set(1);
        dat<<=1;   
    }             
    OLED_CS_Set(1);
    OLED_DC_Set(1);         //空闲时期默认为写数据
}    

(4) 初始化函数:配置引脚模式,初始化OLED系统参数

//初始化SSD1306                        
void OLED_SPI::Init()
{
    pinMode(this->OLED_SDA,OUTPUT);    //SDA D1配置为输出模式
    pinMode(this->OLED_SCL,OUTPUT);   //SCL D0配置为输出模式
    pinMode(this->OLED_DC,OUTPUT);    //Data/Command配置为输出模式
    pinMode(this->OLED_CS,OUTPUT);    //CS配置为输出模式
    pinMode(this->OLED_RES,OUTPUT);   //RES配置为输出模式

    OLED_RES_Set(1);
    delay(100); 
    OLED_RES_Set(0);
    delay(100);
    OLED_RES_Set(1); 

    WR_Byte(0xAE,OLED_CMD);//--turn off oled panel
    WR_Byte(0x00,OLED_CMD);//---set low column address
    WR_Byte(0x10,OLED_CMD);//---set high column address
    WR_Byte(0x40,OLED_CMD);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
    WR_Byte(0x81,OLED_CMD);//--set contrast control register
    WR_Byte(0xCF,OLED_CMD); // Set SEG Output Current Brightness
    WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常
    WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常
    WR_Byte(0xA6,OLED_CMD);//--set normal display
    WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
    WR_Byte(0x3f,OLED_CMD);//--1/64 duty
    WR_Byte(0xD3,OLED_CMD);//-set display offset    Shift Mapping RAM Counter (0x00~0x3F)
    WR_Byte(0x00,OLED_CMD);//-not offset
    WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
    WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
    WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
    WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
    WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
    WR_Byte(0x12,OLED_CMD);
    WR_Byte(0xDB,OLED_CMD);//--set vcomh
    WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level
    WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
    WR_Byte(0x02,OLED_CMD);//
    WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
    WR_Byte(0x14,OLED_CMD);//--set(0x10) disable
    WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
    WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7) 
    WR_Byte(0xAF,OLED_CMD);//--turn on oled panel
    
    WR_Byte(0xAF,OLED_CMD); /*display ON*/ 
    Clear();
    Set_Pos(0,0);   
}

(5) 设置打印点位置函数

//  函数功能:设置坐标
//  x:横坐标(0~127)
//  y:纵坐标(0~7)
void OLED_SPI::Set_Pos(u8 x, u8 y) 
{ 
    WR_Byte(0xb0+y,OLED_CMD);
    WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
    WR_Byte((x&0x0f)|0x01,OLED_CMD); 
}

(6) 其他功能函数

//  函数介绍:开启OLED显示    
void OLED_SPI::Display_On()
{
    WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
    WR_Byte(0X14,OLED_CMD);  //DCDC ON
    WR_Byte(0XAF,OLED_CMD);  //DISPLAY ON
}
//  函数介绍:关闭OLED显示     
void OLED_SPI::Display_Off()
{
    WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
    WR_Byte(0X10,OLED_CMD);  //DCDC OFF
    WR_Byte(0XAE,OLED_CMD);  //DISPLAY OFF
}

//  函数功能:清屏
void OLED_SPI::Clear()  
{  
    u8 i,n;         
    for(i=0;i<8;i++)  
    {  
        WR_Byte(0xb0+i,OLED_CMD);    //设置页地址(0~7)
        WR_Byte(0x00,OLED_CMD);      //设置显示位置—列低地址
        WR_Byte(0x10,OLED_CMD);      //设置显示位置—列高地址   
        for(n=0;n<128;n++) WR_Byte(0,OLED_DATA); 
    }
}

//  功能介绍:删除屏幕中0-3的某一行
void OLED_SPI::Dele_Row(u8 row)
{
    if(row >4 ) return; //行数错误
    u8 x,y;
    WR_Byte(0x00,OLED_CMD);      //设置显示位置—列低地址
    WR_Byte(0x10,OLED_CMD);      //设置显示位置—列高地址 
    for(y=row*2;y<row*2+2;y++)
    {
        WR_Byte(0xb0+y,OLED_CMD);    //设置页地址(0~7)
        for(x=0;x<64;x++)
        {
            WR_Byte(0,OLED_DATA);
            WR_Byte(0,OLED_DATA);
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读