一、SPI 协议
SPI,是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口。是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。SPI是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议。
SPI的通信原理很简单,它以主从方式工作.SPI只有主模式和从模式之分,没有读和写的说法,因为实质上每次SPI是主从设备在交换数据。也就是说,你发一个数据必然会收到一个数据;你要收一个数据必须也要先发一个数据。这种模式通常有一个主设备和一个或多个从设备,需要至少4根线,单向传输时3根也可以。也是所有基于SPI的设备共有的,它们是MISO(主设备数据输入)、MOSI(主设备数据输出)、SCLK(时钟)、CS(片选)。
(1)MISO– Master Input Slave Output,主设备数据输入,从设备数据输出;
(2)MOSI– Master Output Slave Input,主设备数据输出,从设备数据输入;
(3)SCLK – Serial Clock,时钟信号,由主设备产生;
(4)CS – Chip Select,从设备使能信号,由主设备控制。
二、汉字显示
- 硬件连接
我使用的是stm35mini版所以选择的是厂家所给代码中的0.96inch_OLED_Demo_STM32F103RCT6_Hardware_4-wire_SPI文件
打开工程,在main.c中即可看见管脚的连接方式
然后按照其接线方式接线
- 获取汉字字模
可使用野火所给资料中的PCtoLCD2002程序获取汉字字模
- 修改代码
main.c修改
test.c修改
函数说明
GUI_ShowString() 的参数
参数一:X 坐标
参数二:Y 坐标
参数三:字符串(ASCLL码中的)
参数四:bit (表示字符显示格式,这里我用的 16 ,和汉字一样高)
参数五:显示样式(1:白字黑底;0:黑字白底)
GUI_ShowChinese() 的参数
参数一:X 坐标
参数二:Y 坐标
参数三:汉字点阵大小(这里使用的是 16×16 的,参数应该是 16)
参数四:要显示的汉字
参数五:显示样式(1:白字黑底;0:黑字白底)
记得在test.h中进行函数声明
oledfont.h修改
- 烧录程序
keil烧录配置可参考前面的博客
- 结果展示
三、显示温度
将显示温湿度代码移植到oled显示的代码中
main.c
#include "delay.h"
#include "sys.h"
#include "oled.h"
#include "gui.h"
#include "test.h"
#include "bsp_i2c.h"
int main(void)
{
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
OLED_Init(); //初始化OLED
IIC_Init(); //初始化IIC
OLED_Clear(0); //清屏(全黑)
while(1)
{
read_AHT20_once(); //读取温度并显示
delay_ms(1500);
}
}
修改bsp_i2c.c
uint8_t t;
u8 *strTemp1;
u8 *strTemp2;
u8 *strTemp3;
u8 *strHumi1;
u8 *strHumi2;
u8 *strHumi3;
void read_AHT20(void)
{
uint8_t i;
//初始化 readByte 数组
for(i=0; i<6; i++)
{
readByte[i]=0;
}
I2C_Start();
//通过发送 0x71 可以获取一个字节的状态字
I2C_WriteByte(0x71);
ack_status = Receive_ACK();
//接收 6 个 8 bit的数据
readByte[0]= I2C_ReadByte();
//发送 ACK 信号
Send_ACK();
readByte[1]= I2C_ReadByte();
Send_ACK();
readByte[2]= I2C_ReadByte();
Send_ACK();
readByte[3]= I2C_ReadByte();
Send_ACK();
readByte[4]= I2C_ReadByte();
Send_ACK();
readByte[5]= I2C_ReadByte();
//发送 NACK 信号
SendNot_Ack();
I2C_Stop();
//温湿度的二进制数据处理
//0x68 = 0110 1000
//0x08 = 0000 1000
if( (readByte[0] & 0x68) == 0x08 )
{
H1 = readByte[