模块如图
压缩包中共有三个程序:
分别为:软件IIC,软件SPI和硬件SPI
软件IIC用于IIC接口的OLED模块
使用STC89C516单片机和STC12C5A60S2单片机,12MHz晶振,测试通过
软件SPI和硬件SPI用于SPI接口的OLED模块
软件SPI使用STC89C516单片机和STC12C5A60S2单片机,12MHz晶振,测试通过
硬件SPI使STC12C5A60S2单片机,12MHz晶振,测试通过
注意:在用硬件SPI程序时留意单片机是否有硬件SPI(STC89C516单片机无硬件SPI)
程序功能:
1.显示128*64图片,图片可以列行取模和列取模,可反色显示
2.支持汉字英文混合显示,汉字应先用取模软件取模,,可反色显示
注意:汉字只可以用列行取模,取模后数据存放在OLED文件夹中的text.h文件中
单片机源程序如下:
- #include <intrins.h>
- #include "public.h"
- #include "OLED.h"
- #include "ASCII.h"
- #include "text.h"
- #include "port.h"
- //使用位操作加快SPI读写速度
- u8 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;
- void OLED_delay500ms()//12.000MHz
- {
- u8 i,j,k;
- i=23;
- j=205;
- k=120;
- do
- {
- do
- {
- while (--k);
- }while (--j);
- }while (--i);
- }
- //MCU向OLED写入一个字节(字节数据,选择字节为命令还是数据)
- void MCU_write_OLED_Byte(u8 Byte,u8 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(u8 row,u8 column)
- {
- MCU_write_OLED_Byte(0xB0+row,OLED_COMMAND);//设置行(0~7)
- MCU_write_OLED_Byte(0x10|(column&0xF0)>>4,OLED_COMMAND);//设置显示位置大列(0~7)
- MCU_write_OLED_Byte(0x00|(column&0x0F),OLED_COMMAND);//设置显示位置小列(0~7)
- }
- //设置内存地址模式(使用水平地址模式:0x00或垂直地址模式:0x01)
- void OLED_set_memory_address_mode(u8 mode)
- {
- MCU_write_OLED_Byte(0x20,OLED_COMMAND);//设置内存地址模式(使用水平地址模式或垂直地址模式)
- MCU_write_OLED_Byte(mode,OLED_COMMAND);//水平地址模式:0x00,垂直地址模式:0x01,页地址模式:0x02
- MCU_write_OLED_Byte(0x21,OLED_COMMAND);//设置显示位置列初始地址和终止地址
- MCU_write_OLED_Byte(0x00,OLED_COMMAND);//列初始地址
- MCU_write_OLED_Byte(0x7F,OLED_COMMAND);//列终止地址
- MCU_write_OLED_Byte(0x22,OLED_COMMAND);//设置显示位置页初始地址和终止地址
- MCU_write_OLED_Byte(0x00,OLED_COMMAND);//页初始地址
- MCU_write_OLED_Byte(0x07,OLED_COMMAND);//页终止地址
- }
- //清屏
- void OLED_clear()
- {
- u16 i;
- for(i=0;i<1024;++i) MCU_write_OLED_Byte(0x00,OLED_DATA);
- }
- //打印BMP图片(图片数组,选择图片的取模方式(水平取模:0x00或垂直取模:0x01),是否反色(填0或1))
- void OLED_print_BMP(u8 *p,u8 mode,u8 invert_color)
- {
- u16 i;
- OLED_set_memory_address_mode(mode);
- if(invert_color) for(i=0;i<1024;++i) MCU_write_OLED_Byte(~*(p+i),OLED_DATA);
- else for(i=0;i<1024;++i) MCU_write_OLED_Byte(*(p+i),OLED_DATA);
- }
- //OLED打印单个字符(行(0到3),列(0到15),字符,是否反色(填0或1))
- void OLED_print_char(u8 row,u8 column,u8 _char,u8 invert_color)
- {
- u8 i;
- if(invert_color)
- {
- //光标的位置,0到7行,0到127列(行,列)
- OLED_cursor_location(2*row,8*column);
- for(i=0;i<8;++i) MCU_write_OLED_Byte(~ASCII[_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) MCU_write_OLED_Byte(~ASCII[_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) MCU_write_OLED_Byte(ASCII[_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) MCU_write_OLED_Byte(ASCII[_char-32][i+8],OLED_DATA);//因为ASCII码0到31位去除了,所以减32
- }
- }
- //OLED打印单个文字(行(0到3),列(0到15),单个所在文字的数组,是否反色(填0或1))
- void OLED_print_single_word(u8 row,u8 column,u8 *word,u8 invert_color)
- {
- u16 i;
- u8 j;
- for(i=0;i<(sizeof(text))/35;++i)
- {
- if((*word==text[i].name[0])&&(*(word+1)==text[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) MCU_write_OLED_Byte(~text[i].array[j],OLED_DATA);
- else MCU_write_OLED_Byte(text[i].array[j],OLED_DATA);
- }
- }
- }
- }
- //OLED打印文本(行(0到3),列(0到15),所打印的文本,是否反色(填0或1))
- void OLED_print_text(u8 row,u8 column,u8 *p,u8 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 OLED_init()
- {
- OLED_RES=1;
- OLED_delay500ms();//延时函数
- OLED_RES=0;
- OLED_delay500ms();//延时函数
- OLED_RES=1;
-
- MCU_write_OLED_Byte(0xAE,OLED_COMMAND);//关闭显示
- MCU_write_OLED_Byte(0x00,OLED_COMMAND);//设置低列地址
- MCU_write_OLED_Byte(0x10,OLED_COMMAND);//设置高列地址
- MCU_write_OLED_Byte(0x40,OLED_COMMAND);//设置显示起始行
-
- MCU_write_OLED_Byte(0xB0,OLED_COMMAND);//设置页地址
- MCU_write_OLED_Byte(0x81,OLED_COMMAND);//
- MCU_write_OLED_Byte(0xFF,OLED_COMMAND);//
-
- MCU_write_OLED_Byte(0xA1,OLED_COMMAND);//设置细分重映射(0xA1正常,0xA0左右反置)
- MCU_write_OLED_Byte(0xA6,OLED_COMMAND);//设置正常/反向(0xA6正常显示,0xA7反向显示)
- MCU_write_OLED_Byte(0xA8,OLED_COMMAND);//设置多路比率
- MCU_write_OLED_Byte(0x3F,OLED_COMMAND);
- MCU_write_OLED_Byte(0xC8,OLED_COMMAND);//设置列输出扫描方向(0xC8正常,0xC0上下反置)
- MCU_write_OLED_Byte(0xD3,OLED_COMMAND);//设置显示偏移(垂直偏移)
- MCU_write_OLED_Byte(0x00,OLED_COMMAND);
- MCU_write_OLED_Byte(0xD5,OLED_COMMAND);//设置显示时钟分频
- MCU_write_OLED_Byte(0x80,OLED_COMMAND);
- MCU_write_OLED_Byte(0xD9,OLED_COMMAND);//设置预充电周期
- MCU_write_OLED_Byte(0xF1,OLED_COMMAND);//将预充电设置为15个时钟加上其放电设置为1个时钟
- MCU_write_OLED_Byte(0xDA,OLED_COMMAND);//设置COM口硬件配置
- MCU_write_OLED_Byte(0x12,OLED_COMMAND);//启用备用COM向导配置
- MCU_write_OLED_Byte(0xDB,OLED_COMMAND);//设置Vcomh取消选择等级
- MCU_write_OLED_Byte(0x30,OLED_COMMAND);//
- MCU_write_OLED_Byte(0x8D,OLED_COMMAND);//充电凹凸设置
- MCU_write_OLED_Byte(0x14,OLED_COMMAND);//在显示期间启用血浆泵
-
- //光标的位置,0到7行,0到127列(行,列)
- OLED_cursor_location(0,0);
-
- //设置内存地址模式(使用水平地址模式:0x00或垂直地址模式:0x01)
- OLED_set_memory_address_mode(0x00);
-
- //清屏
- OLED_clear();
-
- MCU_write_OLED_Byte(0xAF,OLED_COMMAND);//开启显示
- }
复制代码
所有资料51hei提供下载:
0.96寸12864OLED(SSD1306)模块.rar
(313.5 KB, 下载次数: 423)
链接:游客,本帖隐藏的内容需要积分高于 1 才可浏览,您当前积分为 0
今天闲逛帖子,无意之中找到上述问题解决方法,实测有效
http://www.51hei.com/bbs/dpj-42047-1.html
http://www.51hei.com/bbs/dpj-5399-1.html |