STM32 I2C OLED显示汉字及实现屏幕滚动
STM32 I2C_OLED显示汉字及屏幕滚动
文章目录
任务简介
学习I2C总线通信协议,使用STM32F103完成基于I2C协议的AHT20温湿度传感器的数据采集,并将采集的温度-湿度值通过串口输出。具体任务:
显示自己的学号和姓名;
显示AHT20的温度和湿度;
上下或左右的滑动显示长字符
一.I2C以及AHT20温湿度传感器介绍
这里可以看上一篇链接
二.用0.96寸OLED屏幕显示数据
1.OLED介绍
OLED器件由基板、阴极、阳极、空穴注入层(HIL)、电子注入层(EIL)、空穴传输层(HTL)、电子传输层(ETL)、电子阻挡层(EBL)、空穴阻挡层(HBL)、发光层(EML)等部分构成。其中,基板是整个器件的基础,所有功能层都需要蒸镀到器件的基板上;通常采用玻璃作为器件的基板,但是如果需要制作可弯曲的柔性OLED器件,则需要使用其它材料如塑料等作为器件的基板。阳极与器件外加驱动电压的正极相连,阳极中的空穴会在外加驱动电压的驱动下向器件中的发光层移动,阳极需要在器件工作时具有一定的透光性,使得器件内部发出的光能够被外界观察到;阳极最常使用的材料是ITO。空穴注入层能够对器件的阳极进行修饰,并可以使来自阳极的空穴顺利的注入到空穴传输层;空穴传输层负责将空穴运输到发光层;电子阻挡层会把来自阴极的电子阻挡在器件的发光层界面处,增大器件发光层界面处电子的浓度;发光层为器件电子和空穴再结合形成激子然后激子退激发光的地方;空穴阻挡层会将来自阳极的空穴阻挡在器件发光层的界面处,进而提高器件发光层界面处电子和空穴再结合的概率,增大器件的发光效率;电子传输层负责将来自阴极的电子传输到器件的发光层中;电子注入层起对阴极修饰及将电子传输到电子传输层的作用;阴极中的电子会在器件外加驱动电压的驱动下向器件的发光层移动,然后在发光层与来自阳极的空穴进行再结合。
2.样例测试


三.汉字编码原理
所有的汉字或者英文都是下面的原理,
生成的字库说明:(以12×12例子)

编码排序A0A0→A0FE A1A0→A2FE依次排列。
其他的类推即可。
英文点阵也是如此推理。
四.实验步骤
1.软件
因为后文我们需要在OLED屏幕上显示汉字,所以我们需要一个取字模的软件PCtoLCD2002 提取码: 1234
下面介绍字模提取的步骤“
2.具体实现
①.目录结构
②.字模函数
分析:
根据我们的任务,我们需要显示的字符有:数字,±号(数字前面的符号),以及几个汉字(“姓名”,‘温’,‘湿’,‘度’),在例程中OLED_Font.h
已经有了数字以及特数字符的字模了,所以我们只需要自己取几个汉字的字模。汉字另外放在一个const数组里
const uint8_t OLED_F10x16[][40]=
{
0x00,0x00,0x00,0x00,0xFC,0x84,0x84,0xA4,0xA4,0xA4,0xFC,0xA4,0xA4,0x94,0x84,0x04,
0xFE,0x00,0x00,0x00,0x00,0x40,0x20,0x1C,0x03,0x00,0x00,0x1F,0x12,0x12,0x12,0x12,
0x1E,0x1F,0x40,0x40,0x7F,0x00,0x00,0x00,/*"周",0*/
0x00,0x00,0x08,0xF0,0x00,0x00,0xFE,0x00,0x00,0xF0,0x10,0x10,0xFE,0xFE,0x10,0x10,
0xF0,0x10,0x00,0x00,0x00,0x80,0x40,0x27,0x10,0x0E,0x01,0x00,0x00,0x0F,0x00,0x00,
0xFF,0x7F,0x08,0x08,0x0F,0x00,0x00,0x00,/*"帅",1*/
0x00,0x00,0x00,0xFC,0x78,0x88,0xA8,0xA8,0xA8,0xA8,0xFA,0xA6,0xA8,0xA8,0xA8,0xE8,
0x84,0x44,0x00,0x00,0x00,0x40,0x30,0x0F,0x00,0x20,0x20,0x16,0x1A,0x4A,0x7F,0x02,
0x06,0x1A,0x1A,0x2B,0x64,0x44,0x00,0x00,/*"康",2*/
0x00,0x20,0x40,0x04,0x0C,0xE0,0x10,0x00,0xFC,0x94,0x94,0x94,0x94,0x94,0x94,0xFC,
0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x7C,0x43,0x40,0x7E,0x42,0x42,0x42,0x7E,0x42,
0x42,0x7E,0x42,0x42,0x7E,0x42,0x40,0x00,/*"温",0*/
0x00,0x20,0x62,0x44,0x8C,0x60,0x10,0x00,0xFC,0x94,0x54,0x54,0x54,0x94,0x54,0x54,
0xFC,0x00,0x00,0x00,0x00,0x04,0x34,0x7E,0x01,0x40,0x42,0x4C,0x58,0x40,0x7F,0x40,
0x40,0x7F,0x50,0x48,0x44,0x43,0x42,0x00,/*"湿",0*/
0x00,0x00,0x00,0xF8,0x28,0x28,0x28,0x28,0xF8,0x28,0x26,0x24,0x28,0xF8,0x38,0x28,
0x28,0x24,0x00,0x00,0x00,0x40,0x38,0x87,0x80,0x80,0x40,0x42,0x45,0x2B,0x33,0x13,
0x33,0x2B,0x46,0x40,0x40,0x40,0x40,0x00,/*"度",1*/
};
③.显示汉字
我们把汉字的字模放在一个数组里,用下标来找到对应汉字
传入参数中Num指的是向显示的汉字在数组当中的位置,比如上面‘周’对应Num就是0
void OLED_ShowCN(uint8_t Line, uint8_t Column, uint8_t Num)
{
uint8_t i;
uint8_t wide=20;//字宽
OLED_SetCursor((Line-1)*2, (Column-1)*wide); //参数1:把光标设置在第几页. 参数2:把光标设置在第几列
for (i = 0; i < wide; i++)
{
OLED_WriteData(OLED_F10x16[Num][i]); //显示上半部分内容
}
OLED_SetCursor((Line-1)*2+1,(Column-1)*wide);
for (i = 0; i < wide; i++)
{
OLED_WriteData(OLED_F10x16[Num][i+wide]); //显示下半部分内容
}
}
④.屏幕滚动
OLED_WriteCommand(0x2E); //关闭滚动
OLED_WriteCommand(0x26); //水平向左或者右滚动 26/27
OLED_WriteCommand(0x00); //虚拟字节
OLED_WriteCommand(0x00); //起始页 0
OLED_WriteCommand(0x07); //滚动时间间隔,数字越大转动越慢
OLED_WriteCommand(0x03); //终止页 3
OLED_WriteCommand(0x00); //虚拟字节
OLED_WriteCommand(0xFF); //虚拟字节
OLED_WriteCommand(0x2F); //开启滚动
⑤.主函数
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "AHT20-21_DEMO_V1_3.h"
int main(void)
{
volatile float c1=0,t1=0;
uint32_t CT_data[2];
Init_I2C_Sensor_Port();//初始化SDA,SCL的IO口
Delay_1ms(500);
OLED_Init();
if((AHT20_Read_Status()&0x18)!=0x18)
{
AHT20_Start_Init(); //重新初始化寄存器
Delay_1ms(10);
}
//下面显示汉字
OLED_ShowCN(1,1,0); //周
OLED_ShowCN(1,2,1); //帅
OLED_ShowCN(1,3,2); //康
OLED_ShowString(2,1,"632007060321"); //学号
OLED_ShowCN(3,1,3);//温
OLED_ShowCN(3,2,5);//度
OLED_ShowCN(4,1,4);//湿
OLED_ShowCN(4,2,5);//度
while(1)
{
//屏幕滚动
OLED_WriteCommand(0x2E); //关闭滚动
OLED_WriteCommand(0x26); //水平向左或者右滚动 26/27
OLED_WriteCommand(0x00); //虚拟字节
OLED_WriteCommand(0x00); //起始页 0
OLED_WriteCommand(0x07); //滚动时间间隔,数字越大转动越慢
OLED_WriteCommand(0x03); //终止页 3
OLED_WriteCommand(0x00); //虚拟字节
OLED_WriteCommand(0xFF); //虚拟字节
OLED_WriteCommand(0x2F); //开启滚动
//AHT20_Read_CTdata(CT_data); //不经过CRC校验,直接读取AHT20的温度和湿度数据 推荐每隔大于1S读一次
AHT20_Read_CTdata_crc(CT_data); //crc校验后,读取AHT20的温度和湿度数据
while(CT_data[0]==0x00&&CT_data[1]==0x00) //如果CRC校验不通过
{
AHT20_Read_CTdata_crc(CT_data);
}
c1 = CT_data[0]*100*10/1024/1024; //计算得到湿度值c1(放大了10倍)
t1 = CT_data[1]*200*10/1024/1024-500;//计算得到温度值t1(放大了10倍)
下一步客户处理显示数据,
Delay_1ms(1000);
OLED_Showfloat(3,7,t1/10.00,2,1);
OLED_Showfloat(4,7,c1/10.00,2,1);
}
}
五.实验结果
六.程序源码
链接: https://pan.baidu.com/s/1WErBaAsek_QvCTCDn8GOWQ?pwd=1234 提取码: 1234