欢迎来到泰骏兴电子,大家有问题可以直接联系管理员QQ:233619809单片机 QQ群:59194556 各位游客也可以注册玩玩,享受更多权益。温馨提示:本网站仅提供平台学习以及渠道,一切后果自行承担,还望广大用户提高自我意识,请不要轻易相信他人,请不要轻易相信他人,请不要轻易相信他人。为了更好的管理论坛工作,所以现在使用邮箱注册,如果以前的邮箱不能修改的,请联系管理员代为修改

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 98|回复: 0

适用STC单片机的SPIOLED屏幕程序

[复制链接]
发表于 2022-11-20 16:33:27 | 显示全部楼层 |阅读模式
/*



本人承接毕业设计,程序设计,PCB设计, 电子产品维修,DIY设计,电子装配调试技能竞赛训练套件销售等方面



以下程序来源于本人编写,部分来源于官方或其他收集,若遇到程序无法运行,或者其他问题可以随时于本人联系
*/


#include "spioled.h"
#include "ASCII.h"
#include "text.h"



//使用位操作加快SPI读写速度
uchar bdata Byte_data;
sbit Byte_data7=Byte_data^7;
sbit Byte_data6=Byte_data^6;
sbit Byte_data5=Byte_data^5;
sbit Byte_data4=Byte_data^4;
sbit Byte_data3=Byte_data^3;
sbit Byte_data2=Byte_data^2;
sbit Byte_data1=Byte_data^1;
sbit Byte_data0=Byte_data^0;


//MCU向OLED写入一个字节(字节数据,选择字节为命令还是数据)
void oled_one_byte(uchar Byte,uchar command_or_data)
{
    OLED_DC=command_or_data;
    OLED_CS=0;
    OLED_MOSI=1;
    Byte_data=Byte;
    OLED_CLK=0;OLED_MOSI=Byte_data7;OLED_CLK=1;
    OLED_CLK=0;OLED_MOSI=Byte_data6;OLED_CLK=1;
    OLED_CLK=0;OLED_MOSI=Byte_data5;OLED_CLK=1;
    OLED_CLK=0;OLED_MOSI=Byte_data4;OLED_CLK=1;
    OLED_CLK=0;OLED_MOSI=Byte_data3;OLED_CLK=1;
    OLED_CLK=0;OLED_MOSI=Byte_data2;OLED_CLK=1;
    OLED_CLK=0;OLED_MOSI=Byte_data1;OLED_CLK=1;
    OLED_CLK=0;OLED_MOSI=Byte_data0;OLED_CLK=1;
    OLED_MOSI=1;
    OLED_CS=1;
}

//光标的位置,0到7行,0到127列(行,列)
void OLED_cursor_location(uchar row,uchar column)
{
    oled_one_byte(0xB0+row,OLED_COMMAND);//设置行(0~7)
    oled_one_byte(0x10|(column&0xF0)>>4,OLED_COMMAND);//设置显示位置大列(0~7)
    oled_one_byte(0x00|(column&0x0F),OLED_COMMAND);//设置显示位置小列(0~7)
}

//设置内存地址模式(使用水平地址模式:0x00或垂直地址模式:0x01)
void OLED_set_memory_address_mode(uchar mode)
{
    oled_one_byte(0x20,OLED_COMMAND);//设置内存地址模式(使用水平地址模式或垂直地址模式)
    oled_one_byte(mode,OLED_COMMAND);//水平地址模式:0x00,垂直地址模式:0x01,页地址模式:0x02
    oled_one_byte(0x21,OLED_COMMAND);//设置显示位置列初始地址和终止地址
    oled_one_byte(0x00,OLED_COMMAND);//列初始地址
    oled_one_byte(0x7F,OLED_COMMAND);//列终止地址
    oled_one_byte(0x22,OLED_COMMAND);//设置显示位置页初始地址和终止地址
    oled_one_byte(0x00,OLED_COMMAND);//页初始地址
    oled_one_byte(0x07,OLED_COMMAND);//页终止地址
}

//清屏
void oled_clear()
{  
    uint i;
    for(i=0;i<1024;++i) oled_one_byte(0x00,OLED_DATA);
}

//打印BMP图片(图片数组,选择图片的取模方式(水平取模:0x00或垂直取模:0x01),是否反色(填0或1))
void OLED_print_BMP(uchar *p,uchar mode,uchar invert_color)
{
    uint i;
    OLED_set_memory_address_mode(mode);
    if(invert_color)
    for(i=0;i<1024;++i)
    oled_one_byte(~*(p+i),OLED_DATA);
    else for(i=0;i<1024;++i)
    oled_one_byte(*(p+i),OLED_DATA);
}

//OLED打印单个字符(行(0到3),列(0到15),字符,是否反色(填0或1))
void OLED_print_char(uchar row,uchar column,uchar _char,uchar invert_color)
{
    uchar i;
    if(invert_color)
    {
        //光标的位置,0到7行,0到127列(行,列)
        OLED_cursor_location(2*row,8*column);
        for(i=0;i<8;++i) oled_one_byte(~character8x16[_char-32][i],OLED_DATA);//因为ASCII码0到31位去除了,所以减32
        //光标的位置,0到7行,0到127列(行,列)
        OLED_cursor_location(2*row+1,8*column);
        for(i=0;i<8;++i) oled_one_byte(~character8x16[_char-32][i+8],OLED_DATA);//因为ASCII码0到31位去除了,所以减32
    }
    else
    {
        //光标的位置,0到7行,0到127列(行,列)
        OLED_cursor_location(2*row,8*column);
        for(i=0;i<8;++i) oled_one_byte(character8x16[_char-32][i],OLED_DATA);//因为ASCII码0到31位去除了,所以减32
        //光标的位置,0到7行,0到127列(行,列)
        OLED_cursor_location(2*row+1,8*column);
        for(i=0;i<8;++i) oled_one_byte(character8x16[_char-32][i+8],OLED_DATA);//因为ASCII码0到31位去除了,所以减32
    }
}

//OLED打印单个文字(行(0到3),列(0到15),单个所在文字的数组,是否反色(填0或1))
void OLED_print_single_word(uchar row,uchar column,uchar *word,uchar invert_color)
{
    uint i;
    uchar j;
    for(i=0;i<(sizeof(chinese_characters))/35;++i)
    {
        if((*word==chinese_characters[i].name[0])&&(*(word+1)==chinese_characters[i].name[1]))//对比汉字区码位码
        {
            //光标的位置,0到7行,0到127列(行,列)
            OLED_cursor_location(2*row,8*column);
            for(j=0;j<32;++j)
            {
                if(j==16) OLED_cursor_location(2*row+1,8*column);//光标的位置,0到7行,0到127列(行,列)
                if(invert_color) oled_one_byte(~chinese_characters[i].array[j],OLED_DATA);
                else oled_one_byte(chinese_characters[i].array[j],OLED_DATA);
            }
        }
    }
}

//OLED打印文本(行(0到3),列(0到15),所打印的文本,是否反色(填0或1))
void oled_display(uchar row,uchar column,uchar *p,uchar invert_color)
{
    //设置内存地址模式(使用水平地址模式:0x00或垂直地址模式:0x01)
    OLED_set_memory_address_mode(0x00);
    while(*p!='\0')
    {
        if(*p&0x80)//判断是否为汉字
        {
            //OLED打印单个文字(行(0到3),列(0到15),单个所在文字的数组,是否反色(填0或1))
            OLED_print_single_word(row,column,p,invert_color);
            p=p+2;
            column=column+2;
        }
        else
        {
            //OLED打印单个字符(行(0到3),列(0到15),字符,是否反色(填0或1))
            OLED_print_char(row,column,*p,invert_color);
            ++p;
            ++column;
        }
        
        if(*p&0x80)//判断下一个字符是中文还是英文,防止在末尾显示的位置不够
        {
            if(column>=15)
            {
                ++row;
                column=0;
            }
        }
        else
        {
            if(column==16)
            {
                ++row;
                column=0;
            }
        }
        
        if(row==4) return;//第四行不存在,显示到第四行直接退出(从第零行开始算)
    }
}

//初始化OLED(内存地址模式默认使用水平地址模式,可在初始化程序中更改)
void spi_oled_init()
{
    OLED_RES=1;
    delay_ms(500);//延时函数
    OLED_RES=0;
    delay_ms(500);//延时函数
    OLED_RES=1;
   
    oled_one_byte(0xAE,OLED_COMMAND);//关闭显示
    oled_one_byte(0x00,OLED_COMMAND);//设置低列地址
    oled_one_byte(0x10,OLED_COMMAND);//设置高列地址
    oled_one_byte(0x40,OLED_COMMAND);//设置显示起始行
   
    oled_one_byte(0xB0,OLED_COMMAND);//设置页地址
    oled_one_byte(0x81,OLED_COMMAND);//
    oled_one_byte(0xFF,OLED_COMMAND);//
   
    oled_one_byte(0xA1,OLED_COMMAND);//设置细分重映射(0xA1正常,0xA0左右反置)
    oled_one_byte(0xA6,OLED_COMMAND);//设置正常/反向(0xA6正常显示,0xA7反向显示)
    oled_one_byte(0xA8,OLED_COMMAND);//设置多路比率
    oled_one_byte(0x3F,OLED_COMMAND);
    oled_one_byte(0xC8,OLED_COMMAND);//设置列输出扫描方向(0xC8正常,0xC0上下反置)
    oled_one_byte(0xD3,OLED_COMMAND);//设置显示偏移(垂直偏移)
    oled_one_byte(0x00,OLED_COMMAND);
    oled_one_byte(0xD5,OLED_COMMAND);//设置显示时钟分频
    oled_one_byte(0x80,OLED_COMMAND);
    oled_one_byte(0xD9,OLED_COMMAND);//设置预充电周期
    oled_one_byte(0xF1,OLED_COMMAND);//将预充电设置为15个时钟加上其放电设置为1个时钟
    oled_one_byte(0xDA,OLED_COMMAND);//设置COM口硬件配置
    oled_one_byte(0x12,OLED_COMMAND);//启用备用COM向导配置
    oled_one_byte(0xDB,OLED_COMMAND);//设置Vcomh取消选择等级
    oled_one_byte(0x30,OLED_COMMAND);//
    oled_one_byte(0x8D,OLED_COMMAND);//充电凹凸设置
    oled_one_byte(0x14,OLED_COMMAND);//在显示期间启用血浆泵
   
    //光标的位置,0到7行,0到127列(行,列)
    OLED_cursor_location(0,0);
   
    //设置内存地址模式(使用水平地址模式:0x00或垂直地址模式:0x01)
    OLED_set_memory_address_mode(0x00);
   
    //清屏
    oled_clear();
   
    oled_one_byte(0xAF,OLED_COMMAND);//开启显示
}


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
高级模式
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|泰骏兴电子科技有限公司 ( 粤ICP备2023060260号-1 ) 单片机爱好者

GMT+8, 2025-10-31 17:13

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表