基于SPI接口的OLED数据显示
任务要求:
理解OLED屏显和汉字点阵编码原理,使用STM32F103的SPI或IIC接口实现以下功能:
显示自己的学号和姓名;
显示AHT20的温度和湿度;
上下或左右的滑动显示长字符,比如“Hello,欢迎来到重庆交通大学物联网205实训室!”或者歌词、诗词。
一、SPI简介
SPI是串行外设接口(Serial Peripheral Interface)的缩写。SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,如今越来越多的芯片集成了这种通信协议,比如AT91RM9200。
二、下载SPI OLED资料
前往官网下载相关资料,其中还有相关原理图。
模块相关引脚说明
三、相关程序
生成字模
设置字模选项,阴码,逐行式,16*16,C51格式。
输入自己想输出的文字,点击生成字模
程序
打开下载的资料包,在0.96inch_SPI_OLED_Module_SSD1306_MSP096X_V1.0\1-Demo\Demo_STM32目录下选择自己的芯片。
在test.c中添加自己的名字学号
在oledfont.h中选择16*16的部分,将其修改为我们刚刚生成的字模
在文件中添加之前的测温湿度的代码
#include "AHT20tem.h"
//读取AHT20的状态寄存器
u8 AHT20_Read_Status(void)
{
u8 Byte_first,flag;
IIC_Start();
IIC_Send_Byte(0x71);
flag=IIC_Wait_Ack();
Byte_first = IIC_Read_Byte(flag);
IIC_NAck();
IIC_Stop();
return Byte_first;
}
void AHT20_SendAC(void) //向AHT20发送AC命令
{
IIC_Start();
IIC_Send_Byte(0x70);
IIC_Wait_Ack();
IIC_Send_Byte(0xac);//0xAC采集命令
IIC_Wait_Ack();
IIC_Send_Byte(0x33);
IIC_Wait_Ack();
IIC_Send_Byte(0x00);
IIC_Wait_Ack();
IIC_Stop();
}
void AHT20_Init(void) //初始化AHT20
{
IIC_Init();
IIC_Start();
IIC_Send_Byte(0x70);
IIC_Wait_Ack();
IIC_Send_Byte(0xa8);//0xA8进入NOR工作模式
IIC_Wait_Ack();
IIC_Send_Byte(0x00);
IIC_Wait_Ack();
IIC_Send_Byte(0x00);
IIC_Wait_Ack();
IIC_Stop();
delay_ms(10);//延时10ms左右
IIC_Start();
IIC_Send_Byte(0x70);
IIC_Wait_Ack();
IIC_Send_Byte(0xbe);//0xBE初始化命令,AHT20的初始化命令是0xBE, AHT10的初始化命令是0xE1
IIC_Wait_Ack();
IIC_Send_Byte(0x08);//相关寄存器bit[3]置1,为校准输出
IIC_Wait_Ack();
IIC_Send_Byte(0x00);
IIC_Wait_Ack();
IIC_Stop();
delay_ms(10);//延时10ms左右
}
void AHT20tem_init()
{
delay_ms(40);//刚上电,延时40ms才可以读取状态
//首先发0x71读取状态字bit[3],如果=1,为校准输出,无须初始化!!!正常情况下读回来的状态是0x1C或者是0x18,读回来是0x80表示忙状态;
if(!((AHT20_Read_Status()&0x08)==0x08))
{
AHT20_Init(); //初始化AHT20
}
}
void AHT20_Read_CTdata(u32 *ct) //没有CRC校验,直接读取AHT20的温度和湿度数据
{
volatile u8 Byte_1th=0;
volatile u8 Byte_2th=0;
volatile u8 Byte_3th=0;
volatile u8 Byte_4th=0;
volatile u8 Byte_5th=0;
volatile u8 Byte_6th=0;
u32 RetuData = 0;
u16 cnt = 0,flag;
AHT20_SendAC();//向AHT20发送AC命令
delay_ms(80); //大约延时80ms
cnt = 0;
while(((AHT20_Read_Status()&0x80)==0x80))//直到状态bit[7]为0,表示为空闲状态,若为1,表示忙状态
{
delay_ms(1);
if(cnt++>=100) break;
}
IIC_Start();
IIC_Send_Byte(0x71);
flag=IIC_Wait_Ack();
Byte_1th = IIC_Read_Byte(flag);//状态字
Byte_2th = IIC_Read_Byte(flag);//湿度
Byte_3th = IIC_Read_Byte(flag);//湿度
Byte_4th = IIC_Read_Byte(flag);//湿度/温度
Byte_5th = IIC_Read_Byte(flag);//温度
Byte_6th = IIC_Read_Byte(!flag);//温度
IIC_Stop();
RetuData = (RetuData|Byte_2th)<<8;
RetuData = (RetuData|Byte_3th)<<8;
RetuData = (RetuData|Byte_4th);
RetuData =RetuData >>4;
ct[0] = RetuData;//湿度
RetuData = 0;
RetuData = (RetuData|Byte_4th)<<8;
RetuData = (RetuData|Byte_5th)<<8;
RetuData = (RetuData|Byte_6th);
RetuData = RetuData&0xfffff;
ct[1] =RetuData; //温度
//temphum_init();
}
显示“欢迎来到重庆交通大学”
void TEST_English(void)
{
GUI_ShowCHinese(30,15,16,"欢迎来到重庆交通大学",1);
delay_ms(100);
}
平滑滚动代码
void gunon1()//水平滚动 SSD1306电机驱动可以实现平滑滚动,但是必须要先对显示屏内容进行书写缓存才可以实现平滑滚动的效果
{
OLED_WR_Byte(0x2e,OLED_CMD);//关滚动
OLED_WR_Byte(0x2A,OLED_CMD);//29向右,2a向左
OLED_WR_Byte(0x00,OLED_CMD);//A:空字节
OLED_WR_Byte(0x00,OLED_CMD);//B:水平起始页
OLED_WR_Byte(0x00,OLED_CMD);//C:水平滚动速度
OLED_WR_Byte(0x07,OLED_CMD);//D:水平结束页
OLED_WR_Byte(0x00,OLED_CMD);//E:每次垂直滚动位移
OLED_WR_Byte(0x2f,OLED_CMD);//开滚动
}
四、实验结果
连接模块与STM32
程序生成.hex文件,利用串口下载软件进行烧录
显示界面
任务完成!