SSD1306屏幕驱动
SSD1306是一款带控制器的用于OLED点阵图形显示系统的单片CMOS OLED/PLED驱动器。它由128个SEG(列输出)和64个COM(行输出)组成。该芯片专为共阴极OLED面板设计。SSD1306内置对比度控制器、显示RAM(GDDRAM)和振荡器,以此减少了外部元件的数量和功耗。该芯片有256级亮度控制。数据或命令由通用微控制器通过硬件选择的6800/8000系通用并行接口、I2C接口或串行外围接口发送。该芯片适用于许多小型便携式应用,如手机副显示屏、MP3播放器和计算器等。
改引脚
许多人在拿到程序的时候都是认为直接改宏定义的引脚即可,实际上这个只是其中一个步骤,还需要去对应的初始化函数里增加对应的引脚的初始化定义。比如这里使用的代码里就需要到对应的oled.h里改宏定义的引脚,如下改成适配自己的单片机的驱动引脚。(注意这里代码使用的软件模拟SPI才可以随便改动引脚,如果是硬件SPI就需要底层的逻辑一起改变)
这里使用的单片机是STM32F103C8T6,底层代码驱动使用的是中景园的0.96寸屏幕驱动程序,使用的是软件模拟spi。
打开程序中的oled.h文档,然后更改对应的引脚。
//-----------------OLED端口定义----------------
#define OLED_SCL_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_13)//SCL
#define OLED_SCL_Set() GPIO_SetBits(GPIOB,GPIO_Pin_13)
#define OLED_SDA_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_15)//SDA
#define OLED_SDA_Set() GPIO_SetBits(GPIOB,GPIO_Pin_15)
#define OLED_RES_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_14)//RES
#define OLED_RES_Set() GPIO_SetBits(GPIOB,GPIO_Pin_14)
#define OLED_DC_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_1)//DC
#define OLED_DC_Set() GPIO_SetBits(GPIOB,GPIO_Pin_1)
#define OLED_CS_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_12)//CS
#define OLED_CS_Set() GPIO_SetBits(GPIOB,GPIO_Pin_12)
再打开oled.c文档添加对应引脚的初始化语句
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE); //使能A端口时钟
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOB
GPIO_SetBits(GPIOB,GPIO_Pin_1|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
注意:如果使用到的引脚有PB3,PB4,PA15的话,需要加这两个语句才能作为普通端口
//打开复用端口时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,ENABLE);
//关闭JTAG,使能SWD。即能用PB3,PB4,PA15做普通IO,PA13&14用于SWD调试
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
STM32F103的PB3、PB4、PA15在默认上电状态并不是具有普通 IO 的功能的。而是用作 SWJ-DP端口(用于JTAG调试),所以需要自行禁止其功能,才能将PB3和PB4,PA15作为普通IO引脚使用。
取模
如果屏幕底板带字库的芯片可以直接引用对应的字库芯片支持的字,类似这种0.96寸OLED屏幕的一般都是不带字库的,这个时候就需要我们自己取模,下面分别演示下汉字,英文,图片取模的方法。
汉字取模
这里使用的是PCtoLCD2002进行取模,首先是软件的配置如下图:
1.选择模式→字符模式
2.点击选项,按下图配置。
- 阴码、阳码:指字模点阵中有笔迹像素位的状态是“1”还是“0”。
- 取模方式取决自己的代码编写逻辑,这里使用的是行列式。
- 每行显示数据:点阵这里手动输入999,这里主要影响的是每行有几个,建议输入999,可以使用对应的行格式然后放进代码里。
- 格式:这里要选择C51格式,下面的各个前后缀就需要自己根据实际去配置的,一般需要改动的只有行前缀和行后缀,这里就按下图配置即可。
3.设置文字取模大小
在字宽,字高选择对应的取模大小,比如1616,2424,3232,6464等,然后下面文本框输入要取模的文字,比如这里输入“优信电子”进行取模,将字模保存下来或者直接复制到代码中进行使用。
4.将对应的字模复制到代码中去(这里只列举两种,其他可以下方留言邮箱查看具体代码哦)
//16*16
const unsigned char Hzk1[][32]={
{0x00,0x80,0x60,0xF8,0x07,0x10,0x10,0x10,0xFF,0x10,0xF0,0x11,0x16,0x10,0x10,0x00,
0x01,0x00,0x00,0xFF,0x00,0x80,0x60,0x1C,0x03,0x00,0x3F,0x40,0x40,0x40,0x78,0x00},/*"优"*/
{0x00,0x80,0x60,0xF8,0x07,0x00,0x04,0x24,0x24,0x25,0x26,0x24,0x24,0x24,0x04,0x00,
0x01,0x00,0x00,0xFF,0x00,0x00,0x00,0xF9,0x49,0x49,0x49,0x49,0x49,0xF9,0x00,0x00},/*"信"*/
{0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0xFF,0x88,0x88,0x88,0x88,0xF8,0x00,0x00,0x00,
0x00,0x00,0x1F,0x08,0x08,0x08,0x08,0x7F,0x88,0x88,0x88,0x88,0x9F,0x80,0xF0,0x00},/*"电"*/
{0x80,0x82,0x82,0x82,0x82,0x82,0x82,0xE2,0xA2,0x92,0x8A,0x86,0x82,0x80,0x80,0x00,
0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"子"*/};
//24*24
const unsigned char Hzk2[][72]={
{0x00,0x00,0x00,0x00,0xC0,0xF0,0x1E,0x04,0x00,0x00,0x00,0x00,0xFE,0xFC,0x00,0x00,
0x04,0x08,0x38,0x70,0x80,0x00,0x00,0x00,0x00,0x10,0x0C,0x03,0x01,0xFF,0x01,0x01,
0x01,0x01,0x01,0x81,0xFF,0x07,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,0x20,0x18,0x0C,0x03,0x00,0x00,0x00,0x3F,
0x20,0x20,0x20,0x20,0x20,0x3E,0x10,0x00},/*"优"*/
{0x00,0x00,0x00,0x00,0x80,0x60,0x1C,0x04,0x20,0x20,0x20,0x20,0x20,0x22,0x3C,0x38,
0x20,0x20,0x20,0xA0,0x30,0x20,0x00,0x00,0x00,0x10,0x08,0x06,0x01,0xFF,0x00,0x00,
0x00,0x09,0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x8D,0x89,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x7F,0x10,0x10,0x10,0x10,0x10,
0x10,0x10,0x10,0x7F,0x00,0x00,0x00,0x00},/*"信"*/
{0x00,0x00,0x00,0x00,0xC0,0x40,0x40,0x40,0x40,0x40,0x40,0xFE,0x40,0x40,0x40,0x40,
0x40,0x40,0xC0,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x84,0x84,0x84,
0x84,0x84,0x84,0xFF,0x84,0x84,0x84,0x84,0x84,0x84,0xFF,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x40,
0x40,0x40,0x41,0x40,0x60,0x7C,0x00,0x00},/*"电"*/
{0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x88,0x88,0x48,
0x28,0x18,0x18,0x08,0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
0x08,0x08,0x08,0xFF,0xFF,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x0C,0x08,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x20,0x60,0x7F,0x3F,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"子"*/};
然后再在主函数中引用
//16*16
OLED_ShowChinese(18,0,1,16,1);//优
OLED_ShowChinese(36,0,2,16,1);//信
OLED_ShowChinese(54,0,3,16,1);//电
OLED_ShowChinese(72,0,4,16,1);//子
//24*24
OLED_ShowChinese(0,16,1,24,1);//优
OLED_ShowChinese(26,16,2,24,1);//信
OLED_ShowChinese(52,16,3,24,1);//电
OLED_ShowChinese(78,16,4,24,1);//子
OLED_Refresh();
delay_ms(500);
OLED_Clear();
//32*32
OLED_ShowChinese(0,16,1,32,1);//优
OLED_ShowChinese(32,16,2,32,1);//信
OLED_ShowChinese(64,16,3,32,1);//电
OLED_ShowChinese(96,16,4,32,1);//子
OLED_Refresh();
delay_ms(500);
OLED_Clear();
//64*64
OLED_ShowChinese(0,0,1,64,1);//优
OLED_ShowChinese(64,0,2,64,1);//信
OLED_Refresh();
delay_ms(500);
OLED_Clear();
就可以看到屏幕轮流显示了不同大小的字体。
英文取模
这个跟汉字是一样,不同的是字体大小选择1616的时候对应的英文大小为816即字宽会减半,其他使用方法和汉字都是相同的。这里不再赘述。这里提供ASCII码方便取模使用。
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
图片取模
同样也是使用的PCtoLCD2002这个软件进行取模。
1.选择模式→图形模式
2.点击选项,按下图配置。配置和汉字取模是一样的,这里就不重复说了。
- 每行显示数据:点阵这里输入999或者16或者其他数据都是可以的,对应的是一行有几个。
3.点击“文件”→“打开”→打开对应BMP格式的图片进行取模→生成字模→复制到代码bmp.h中
unsigned char BMP3[] =
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,
0xFF,0xFF,0xFF,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0xF0,0xF0,0xF0,0xF0,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,
0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xFC,0xFC,0xFC,0xFC,0x03,
0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xC0,
0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0x80,0x80,0x80,0x80,0x80,0x80,0x7C,0x7C,0x7C,0x7C,0x2B,0x03,0x03,0x03,0x03,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x03,0x03,0x03,0x03,
0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0xFC,0xFC,0xFC,0xFC,
0xFF,0xFF,0xFF,0xFF,0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,0xFF,0xFF,
0xFF,0xFF,0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,
0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0xFF,0xFF,
0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x70,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0x07,0x07,0x0F,0x07,
0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0x0F,0x0F,0x0F,0x0F,0x00,0x00,0x00,0x00,/*点赞图片64*64*/
};
在main.c中进行引用
OLED_ShowPicture(32,0,64,64,BMP3,1);
OLED_Refresh();
显示现象:
总结
1.如果取模后主函数进行显示的时候发现是乱码:
- 排查自己的代码语句是否拼写正确
- 取模方式是否正确(可以对程序已经取模过的汉字或者图片重新取模,替换到代码中进行验证)
- 是否没有清屏(无清屏会叠加显示)
- 如果是什么都没有显示的情况下:看下这个语句OLED_Refresh();是否加上,这个代码的作用是更新显存到OLED,不引用就无法显示的。
2.自行编写程序发现模块花屏了建议使用对应的例程去测试看下是否正常显示,一般是屏幕的初始化函数不正确。
3.显示汉字一直在闪:看循坏函数代码里是否哪里多加了清屏函数。
需要代码和取模工具以及图片的可以在评论区下留言邮箱哦!