前言
使用工具
- 正点原子STM32F103RCTb MINI开发板
- 4PIN-OLED
- KEIL5
- FlyMcu
- PCtoLCD2002(取模软件)
最终效果与连线
VCC————3.3V
GND————GND
SCL————PC11
SDA————PC12
说明:本文不讲解OLED与IIC的基本原理,只考虑使用与实现功能。
代码
KEIL文件总览
上述文件中,main.c包含主函数,oled.c包含IIC底层代码与OLED显示。
当然还有.h文件,其中bmp.h包含BMP图片的取模16进制编码,oled.h包含对IIC引脚定义和OLED屏幕相关定义,oledfont.h包含ASCALL码与自己定义的中文字符。
其他均为官方提供文件,无另外编写。
关键代码
oled.h中对IIC引脚定义
如果要修改使用的引脚,将GPIOC、GPIO_Pin_11和GPIO_Pin_12改为对应即可,其他都无需做任意改动。
#define OLED_SCLK_Clr() GPIO_ResetBits(GPIOC,GPIO_Pin_11)//CLK
#define OLED_SCLK_Set() GPIO_SetBits(GPIOC,GPIO_Pin_11)
#define OLED_SDIN_Clr() GPIO_ResetBits(GPIOC,GPIO_Pin_12)//DIN
#define OLED_SDIN_Set() GPIO_SetBits(GPIOC,GPIO_Pin_12)
#define OLED_CMD 0 //写命令
#define OLED_DATA 1 //写数据
/*在oled.c中初始化SSD1306还有相关程序
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_SetBits(GPIOC,GPIO_Pin_11|GPIO_Pin_12);
*/
显示字符串
//第一个参数为x坐标(0-128);第二个参数为y坐标(0-8);
//第三个为ASCALL码,当chr = 65时,为'A';第四个参数为文字大小,仅为12/16。
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size)
{
unsigned char c=0,i=0;
c=chr-' ';//得到偏移后的值
if(x>Max_Column-1){x=0;y=y+2;}
if(Char_Size ==16)
{
OLED_Set_Pos(x,y);
for(i=0;i<8;i++)
OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
OLED_Set_Pos(x,y+1);
for(i=0;i<8;i++)
OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
}
else {
OLED_Set_Pos(x,y);
for(i=0;i<6;i++)
OLED_WR_Byte(F6x8[c][i],OLED_DATA);
}
}
显示数字
//第一个参数为x坐标(0-128);第二个参数为y坐标(0-8);
//第三个num为数字;第四个参数为数字长度;第五个参数为数字大小,仅为12/16。
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2)
{
u8 t,temp;
u8 enshow=0;
for(t=0;t<len;t++)
{
temp=(num/oled_pow(10,len-t-1))%10;
if(enshow==0&&t<(len-1))
{
if(temp==0)
{
OLED_ShowChar(x+(size2/2)*t,y,' ',size2);
continue;
}else enshow=1;
}
OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2);
}
}
显示字符串
//第一个参数为x坐标(0-128);第二个参数为y坐标(0-8);
//第三个为字符串;第四个参数为字符大小,仅为12/16。
void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size)
{
unsigned char j=0;
while (chr[j]!='\0')
{ OLED_ShowChar(x,y,chr[j],Char_Size);
x+=8;
if(x>120){x=0;y+=2;}
j++;
}
}
显示汉字
//第一个参数为x坐标(0-128);第二个参数为y坐标(0-8);
//第三个为要输入的汉字,在oledfont.h中定义。
void OLED_ShowCHinese(u8 x,u8 y,u8 no)
{
u8 t,adder=0;
OLED_Set_Pos(x,y);
for(t=0;t<16;t++)
{
OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);
adder+=1;
}
OLED_Set_Pos(x,y+1);
for(t=0;t<16;t++)
{
OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
adder+=1;
}
}
显示BMP图片
//第一个参数为起始x0坐标(0-128);第二个参数为起始y0坐标(0-8);
//第三个参数为结束x1坐标(0-128);第四个参数为结束y1坐标(0-8);
//第五个为要输入的图片。
void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[])
{
unsigned int j=0;
unsigned char x,y;
if(y1%8==0) y=y1/8;
else y=y1/8+1;
for(y=y0;y<y1;y++)
{
OLED_Set_Pos(x0,y);
for(x=x0;x<x1;x++)
{
OLED_WR_Byte(BMP[j++],OLED_DATA);
}
}
}
取模软件使用
软件设置
1、选择阴码和阳码,看自己需要的效果。
2、如果使用列行式,则OLED_DrawBMP函数的x1-x0为图像大小的第一个参数。使用行列式,则OLED_DrawBMP的x1-x0为图像大小的第二个参数。
3、取模走向采用逆向。
4、自定义格式选择C51格式。
采用阴码、列行式、逆向、C51效果图如下:
代码烧录效果图:
动态图实现
与上述展示BMP图步骤一样,区别在于它要一张一张取出来进行展示,很是麻烦。
有时候GIF图直接取成BMP图后,色调会变得很淡,如右图(它是有东西的)。可以先用Python程序将GIF图转为PNG图片,如果图片不是黑底,需再将PNG图片用WINDOW自带的画图进行取反颜色变为黑底,,然后再转为BMP图,如左图效果。取成左图这样的效果后在进行取模,放入数组中用for循环即可实现效果,这里无须delay。
应有的效果图: