可用SH1106 OLED SPI接口程序

2020-01-12 17:16发布

最近调试SH1106 OLED显示程序,已成功点亮。如果对你可以帮助的话,参考下。高手勿喷。
#ifndef _OLED_H_
#define _OLED_H_

#include "C8051F020.h"


//----OLED显示字库-----
extern unsigned char code jian1616[];
extern unsigned char code kong1616[];
extern unsigned char code jiang1616[];
extern unsigned char code ji1616[];
extern unsigned char code diao1616[];
extern unsigned char code che1616[];
extern unsigned char code fei1616[];
extern unsigned char code mo1616[];
extern unsigned char code ni1616[];
extern unsigned char code qi1616[];
extern unsigned char code asc0816[95][16];
extern unsigned char code bmp[] ;


//--------LCD接口定义---------
//SH1106驱动芯片,采用SPI 4线接口
sbit         OLED_CS      =P3^7;        //低电平有效
sbit         OLED_CLK                        =P3^1;        //上升沿输入
sbit         OLED_STD                        =P3^0;        //数据,串行,HSB先写入
sbit        OLED_DC                        =P3^3;        //=0命令,=1数据

#define lcd_cmd 0//该数据是给LCD的命令
#define lcd_dat 1//该数据是给LCD的数据


void oled_write_data(bit rs,unsigned char cdata);                //rs==0,为命令;==1,为数据
void oled_init(void);
void oled_set_xy (unsigned char page,unsigned char column);
void oled_clear_screen(void);
void display_128x64(unsigned char *dp);
void display_graphic_16x16(unsigned char page,unsigned char  column,unsigned char *dp);
void display_graphic_8x16(unsigned char page,unsigned char  column,unsigned char *string,unsigned char code *asc_lib );
void oled_welcome(void);        //欢迎界面







#endif


//--------END OF FILE-----------

#include "oled.h"



extern void rst_wdi(void);


//LCD串口函数( SPI接口 )
void oled_write_data(bit rs,unsigned char cdata)//rs==0,为命令;==1,为数据
{
        unsigned char i;
        rst_wdi();
       
        OLED_CLK=0;
        OLED_DC=        rs;

        rst_wdi();
                       
        for(i=0;i<8;i++)//启动移位写入
        {
                OLED_STD=(bit)(cdata&0x80);
                cdata<<=1;
                OLED_CLK=1;
                OLED_CLK=0;
        }
       
        rst_wdi();
       
}
//LCD初始化
void oled_init(void)
{
        OLED_CS=0;
        oled_write_data(lcd_cmd,0xAE);   //display off
        oled_write_data(lcd_cmd,0x20);        //Set Memory Addressing Mode       
        oled_write_data(lcd_cmd,0x10);        //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
        oled_write_data(lcd_cmd,0xb0);        //Set Page Start Address for Page Addressing Mode,0-7
        oled_write_data(lcd_cmd,0xc8);        //Set COM Output Scan Direction
        oled_write_data(lcd_cmd,0x00);//---set low column address
        oled_write_data(lcd_cmd,0x10);//---set high column address
        oled_write_data(lcd_cmd,0x40);//--set start line address
        oled_write_data(lcd_cmd,0x81);//--set contrast control register
        oled_write_data(lcd_cmd,0x7f);
        oled_write_data(lcd_cmd,0xa1);//--set segment re-map 0 to 127
        oled_write_data(lcd_cmd,0xa6);//--set normal display
        oled_write_data(lcd_cmd,0xa8);//--set multiplex ratio(1 to 64)
        oled_write_data(lcd_cmd,0x3F);//
        oled_write_data(lcd_cmd,0xa4);//0xa4,Output follows RAM content;0xa5,Output ignores RAM content
        oled_write_data(lcd_cmd,0xd3);//-set display offset
        oled_write_data(lcd_cmd,0x00);//-not offset
        oled_write_data(lcd_cmd,0xd5);//--set display clock divide ratio/oscillator frequency
        oled_write_data(lcd_cmd,0xf0);//--set divide ratio
        oled_write_data(lcd_cmd,0xd9);//--set pre-charge period
        oled_write_data(lcd_cmd,0x22); //
        oled_write_data(lcd_cmd,0xda);//--set com pins hardware configuration
        oled_write_data(lcd_cmd,0x12);
        oled_write_data(lcd_cmd,0xdb);//--set vcomh
        oled_write_data(lcd_cmd,0x20);//0x20,0.77xVcc
        oled_write_data(lcd_cmd,0x8d);//--set DC-DC enable
        oled_write_data(lcd_cmd,0x14);//
        oled_write_data(lcd_cmd,0xaf);//--turn on oled panel
        OLED_CS=1;

}

//设置显示坐标,page页地址和column列地址
void oled_set_xy (unsigned char page,unsigned char column)
{
        page&=0x07;
        column&=0x7f;
        oled_write_data(lcd_cmd,0xb0+page);        //Set Page Start Address for Page Addressing Mode,0-7
        oled_write_data(lcd_cmd,(column&0x0f)+0x02);//---set low column address,曹仁根注:SH1106要+2偏移,否则显示不正常
        oled_write_data(lcd_cmd,0x10|((column&0xf0)>>4));//---set high column address
}

//olde 清屏
void oled_clear_screen(void)
{
        unsigned char i,j;
        OLED_CS=0;
        for(i=0;i<8;i++)
        {
                oled_write_data(lcd_cmd,0xb0+i);
                oled_write_data(lcd_cmd,0x00+0x02);
                oled_write_data(lcd_cmd,0x10);
                for(j=0;j<128;j++)
                {
                  oled_write_data(lcd_dat,0x00);
                }
        }
        OLED_CS  =1;
}

/*显示128x64点阵图像*/
void display_128x64(unsigned char *dp)
{
        unsigned char i=0,j=0;
        OLED_CS=0;
        for(j=0;j<8;j++)
        {
                oled_set_xy(j,0);
                for (i=0;i<128;i++)
                {       
                        oled_write_data(lcd_dat,*dp++);                                        /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/
                }
        }
        OLED_CS=1;
}

/*显示16x16点阵图像、汉字、生僻字或16x16点阵的其他图标*/
void display_graphic_16x16(unsigned char page,unsigned char  column,unsigned char *dp)
{
        unsigned char i=0,j=0;
        OLED_CS=0;
        for(j=0;j<2;j++)
        {
                oled_set_xy(page,column);
                for (i=0;i<16;i++)
                {       
                        oled_write_data(lcd_dat,*dp++);                                /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/
                }
                page++;
        }
        OLED_CS=1;
}

/*显示8x16点阵图像、汉字、生僻字或8x16点阵的其他图标,主要为ASCII字符*/
void display_graphic_8x16(unsigned char page,unsigned char  column,unsigned char *string,unsigned char code *asc_lib )
{
        unsigned char i=0,j=0,* strtemp , pagetemp=page;
        OLED_CS=0;
        while (*string!=0)
                {
                        if((*string>=0x20) &&(*string<=0x7e))       
                                {
                                        strtemp = asc_lib +(*string++-' ')*16;
                                }
                               
                        page=pagetemp;        //在同一页
                               
                        for(j=0;j<2;j++)
                                {
                                        oled_set_xy(page,column);
                                        for (i=0;i<8;i++)
                                                {       
                                                        oled_write_data(lcd_dat,*strtemp++);                                /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/
                                                }
                                        page++;
                                }
                        column+=8;
                        if(column>127){break;}        //限制为16个字母或数字

                }
       
       
        OLED_CS=1;
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。