本文使用到的软件:Keil MDK,串口调试助手 本文使用到的硬件:PC机,STM32最小系统开发板,0.96寸OLED显示屏
一、SPI通信协议简介
-
与I2C协议一样,对于通讯协议,我们也以分层的方式来理解,最基本的是把它分为物理层和协议层。 -
物理层 (1)SS( Slave Select) :从设备选择信号线,常称为片选信号线,也称为 NSS、CS,以下用 NSS 表示。 (2) SCK (Serial Clock) :时钟信号线,用于通讯数据同步。它由通讯主机产生,决定了通讯的速率,不同的设备支持的最高时钟频率不一样,如 STM32 的 SPI 时钟频率最大为fpclk/2,两个设备之间通讯时,通讯速率受限于低速设备。 (3) MOSI (Master Output, Slave Input) :主设备输出/从设备输入引脚。主机的数据从这条信号线输出,从机由这条信号线读入主机发送的数据,即这条线上数据的方向为主机到从机。 (4) MISO(Master Input,,Slave Output) :主设备输入/从设备输出引脚。主机从这条信号线读入数据,从机的数据由这条信号线输出到主机,即在这条线上数据的方向为从机到主机。 -
协议层
二、显示自己的学号和姓名
void GUI_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size,u8 mode)
{
unsigned char j=0,csize;
if(Char_Size == 16)
{
csize = Char_Size/2;
}
else if(Char_Size == 8)
{
csize = Char_Size/2+2;
}
else
{
return;
}
while (chr[j]!='\0')
{
GUI_ShowChar(x,y,chr[j],Char_Size,mode);
x+=csize;
if(x>120)
{
x=0;
y+=Char_Size;
}
j++;
}
}
void GUI_ShowFont32(u8 x,u8 y,u8 *s,u8 mode)
{
u8 i,j,k,tmp;
u16 num;
num = sizeof(cfont32)/sizeof(typFNT_GB32);
for(i=0;i<num;i++)
{
if((cfont32[i].Index[0]==*s)&&(cfont32[i].Index[1]==*(s+1)))
{
for(j=0;j<128;j++)
{
if(mode)
{
tmp = cfont32[i].Msk[j];
}
else
{
tmp = ~(cfont32[i].Msk[j]);
}
for(k=0;k<8;k++)
{
if(tmp&(0x80>>k))
{
OLED_Set_Pixel(x+(j%4)*8+k, y+j/4,1);
}
else
{
OLED_Set_Pixel(x+(j%4)*8+k, y+j/4,0);
}
}
}
break;
}
}
OLED_Display();
}
main函数
int main(void)
{
delay_init();
NVIC_Configuration();
OLED_Init();
OLED_Clear(0);
while(1)
{
TEST_MainPage();
}
}
- 在oledfont.h将要显示的汉字添加(oledfont.h主要是存放的字库数据,包含常用的字符和用户自己所取模的中文)
"任",0x08,0x10,0x08,0x78,0x0B,0xC0,0x10,0x40,0x10,0x40,0x30,0x40,0x30,0x40,0x5F,0xFE,
0x90,0x40,0x10,0x40,0x10,0x40,0x10,0x40,0x10,0x40,0x10,0x40,0x17,0xFC,0x10,0x00,
"璐",0x00,0x10,0x07,0x90,0xFC,0xBC,0x24,0xA4,0x24,0xC4,0x27,0xA8,0x21,0x10,0xF9,0x28,
0x21,0x46,0x25,0xC0,0x25,0x3C,0x3D,0x24,0xE5,0x24,0x45,0xA4,0x0E,0x3C,0x00,0x24,
"芸",0x08,0x20,0x08,0x20,0xFF,0xFE,0x08,0x20,0x08,0x20,0x00,0x00,0x3F,0xF8,0x00,0x00,
0x00,0x00,0xFF,0xFE,0x02,0x00,0x04,0x00,0x08,0x20,0x10,0x10,0x3F,0xF8,0x10,0x08,
汉字字模生成方式我放在最后
- 结果展示
- 7脚OLED显示屏引脚如下:
三、显示AHT20的温度和湿度
AHT20与STM32F103芯片接法看我另一篇博客:https://blog.csdn.net/isyuuun/article/details/121409657
int main(void)
{
delay_init();
uart_init(115200);
IIC_Init();
NVIC_Configuration();
OLED_Init();
OLED_Clear(0);
while(1)
{
read_AHT20_once();
OLED_Clear(0);
delay_ms(1500);
}
}
读取温湿度数据函数
void read_AHT20_once(void)
{
delay_ms(10);
reset_AHT20();
delay_ms(10);
init_AHT20();
delay_ms(10);
startMeasure_AHT20();
delay_ms(80);
read_AHT20();
delay_ms(5);
}
-
引脚接法 -
结果展示
四、左右滑动显示长字符
void OLED_WR_Byte(unsigned dat,unsigned cmd)
{
if(cmd)
{
OLED_DC_Set();
}
else
{
OLED_DC_Clr();
}
OLED_CS_Clr();
SPI_WriteByte(dat);
OLED_CS_Set();
}
完成滚动所用函数
void SPI_WriteByte(u8 Data)
{
unsigned char i=0;
for(i=8;i>0;i--)
{
if(Data&0x80)
{
OLED_MOSI_SET();
}
else
{
OLED_MOSI_CLR();
}
OLED_CLK_CLR();
OLED_CLK_SET();
Data<<=1;
}
}
main函数:
int main(void)
{
delay_init();
NVIC_Configuration();
OLED_Init();
OLED_Clear(0);
OLED_WR_Byte(0x2E,OLED_CMD);
OLED_WR_Byte(0x27,OLED_CMD);
OLED_WR_Byte(0x00,OLED_CMD);
OLED_WR_Byte(0x00,OLED_CMD);
OLED_WR_Byte(0x07,OLED_CMD);
OLED_WR_Byte(0x07,OLED_CMD);
OLED_WR_Byte(0x00,OLED_CMD);
OLED_WR_Byte(0xFF,OLED_CMD);
TEST_MainPage();
OLED_WR_Byte(0x2F,OLED_CMD);
while(1)
{
}
}
显示函数:
void TEST_MainPage(void)
{
GUI_ShowCHinese(10,20,16,"生活因你而火热",1);
delay_ms(1500);
delay_ms(1500);
}
字库中存放下列字模:
"生",0x01,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x3F,0xFC,0x21,0x00,0x41,0x00,0x81,0x00,
0x01,0x00,0x3F,0xF8,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xFF,0xFE,0x00,0x00,
"活",0x00,0x10,0x20,0x78,0x13,0xC0,0x10,0x40,0x80,0x40,0x47,0xFE,0x40,0x40,0x10,0x40,
0x10,0x40,0x23,0xF8,0xE2,0x08,0x22,0x08,0x22,0x08,0x22,0x08,0x23,0xF8,0x02,0x08,
"因",0x00,0x00,0x7F,0xFC,0x40,0x04,0x41,0x04,0x41,0x04,0x41,0x04,0x5F,0xF4,0x41,0x04,
0x42,0x84,0x42,0x44,0x44,0x24,0x48,0x14,0x50,0x14,0x40,0x04,0x7F,0xFC,0x40,0x04,
"你",0x08,0x80,0x08,0x80,0x08,0x80,0x11,0xFE,0x11,0x02,0x32,0x04,0x34,0x20,0x50,0x20,
0x91,0x28,0x11,0x24,0x12,0x24,0x12,0x22,0x14,0x22,0x10,0x20,0x10,0xA0,0x10,0x40,
"而",0x00,0x00,0x7F,0xFC,0x01,0x00,0x01,0x00,0x02,0x00,0x3F,0xF8,0x24,0x88,0x24,0x88,
0x24,0x88,0x24,0x88,0x24,0x88,0x24,0x88,0x24,0x88,0x24,0x88,0x20,0x28,0x20,0x10,
"火",0x01,0x00,0x01,0x00,0x01,0x00,0x11,0x08,0x11,0x08,0x11,0x10,0x21,0x20,0x21,0x00,
0x42,0x80,0x02,0x80,0x04,0x40,0x04,0x40,0x08,0x20,0x10,0x10,0x20,0x08,0xC0,0x06,
"热",0x10,0x40,0x10,0x40,0x10,0x40,0xFD,0xF8,0x10,0x48,0x10,0x48,0x1C,0xC8,0x30,0x48,
0xD0,0xAA,0x10,0xAA,0x51,0x06,0x22,0x02,0x00,0x00,0x48,0x88,0x44,0x44,0x84,0x44,
- 结果展示
五、总结
温湿度采集使用的I2C,OLED的显示采用SPI通信协议,代码网络上都有,看懂则需要很多时间。套用配置好的函数,来改变显示内容,在这过程也遇到很多问题,比如字模的提取,滚动屏的速度等。
参考文章: https://blog.csdn.net/qq_43279579/article/details/111678857 https://blog.csdn.net/qq_43279579/article/details/111500137 https://blog.csdn.net/qq_43279579/article/details/111414037 完整代码: 链接:https://pan.baidu.com/s/1bBmnMRTFDf4zaeJ3XZuNDw 提取码:1111
|