|
|
/*
本人承接毕业设计,程序设计,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);//开启显示
}
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|