基于IIC和SPI协议的温湿度采集与OLED显示

目录

一、基于I2C协议的AHT20温湿度传感器的数据采集

1.I2C协议

1)软件I2C

2)硬件I2C

3)二者区别

2.源代码

3.烧录运行

二、STM32应用OLED屏显

1.OLED简介

2.模块特点

3.接线方式

4.源代码

5.烧录运行

1)固定文字

2)温湿度

3)滚屏

三、总结


一、基于I2C协议的AHT20温湿度传感器的数据采集

1.I2C协议

1)软件I2C

直接使用 CPU 内核按照 I2C 协议的要求控制 GPIO 输出高低电平,从而模拟I2C。

2)硬件I2C

对应 STM32 芯片中的硬件 I2C 外设,有相应的I2C驱动电路,其所使用的I2C管脚也是专用。

3)二者区别

可以看底层配置,比如IO口配置,如果配置了IO口的功能(IIC功能)那就是固件IIC,否则就是模拟

可以看IIC写函数,看里面有木有调用现成的函数或者给某个寄存器赋值,如果有,则肯定是固件IIC功能,没有的话肯定是数据一个bit一个bit模拟发生送的,肯定用到了循环,则为模拟。

2.源代码

void AHT20_Init(void)   //初始化AHT20
{	
	Init_I2C_Sensor_Port();
	I2C_Start();
	AHT20_WR_Byte(0x70);
	Receive_ACK();
	AHT20_WR_Byte(0xa8);//0xA8进入nor工作模式
	Receive_ACK();
	AHT20_WR_Byte(0x00);
	Receive_ACK();
	AHT20_WR_Byte(0x00);
	Receive_ACK();
	Stop_I2C();

	Delay_1ms(10);//延时10毫秒

	I2C_Start();
	AHT20_WR_Byte(0x70);
	Receive_ACK();
	AHT20_WR_Byte(0xbe);//0xBE初始化命令,AHT20的初始化命令式是0xBE,AHT10的初始化命令是0xE1
	Receive_ACK();
	AHT20_WR_Byte(0x08);//相关寄存器bit[3]置1,为校准输出
	Receive_ACK();
	AHT20_WR_Byte(0x00);
	Receive_ACK();
	Stop_I2C();
	Delay_1ms(10);//延时10毫秒
}

主要流程

uint32_t CT_data[2];
	volatile int  c1,t1;
	/***********************************************************************************/
	/**///①刚上电,产品芯片内部就绪需要时间,延时100~500ms,建议500ms
	/***********************************************************************************/
	Delay_1ms(500);
	/***********************************************************************************/
	/**///②上电第一次发0x71读取状态字,判断状态字是否为0x18,如果不是0x18,进行寄存器初始化
	/***********************************************************************************/
	if((AHT20_Read_Status()&0x18)!=0x18)
	{
	AHT20_Start_Init(); //重新初始化寄存器
	Delay_1ms(10);
	}
	
	/***********************************************************************************/
	/**///③根据客户自己需求发测量命令读取温湿度数据,当前while(1)循环发测量命令读取温湿度数据,仅供参考
	/***********************************************************************************/
	while(1)
	{
	 AHT20_Read_CTdata(CT_data);       //不经过CRC校验,直接读取AHT20的温度和湿度数据    推荐每隔大于1S读一次
    //AHT20_Read_CTdata_crc(CT_data);  //crc校验后,读取AHT20的温度和湿度数据 
	

	 c1 = CT_data[0]*100*10/1024/1024;  //计算得到湿度值c1(放大了10倍)
	 t1 = CT_data[1]*200*10/1024/1024-500;//计算得到温度值t1(放大了10倍)
	下一步客户处理显示数据,
	 }

3.烧录运行

 

二、STM32应用OLED屏显

1.OLED简介

OLED,即有机发光二极管(Organic Light-Emitting Diode),又称为有机电激光显示(Organic Electroluminesence Display, OELD)。OLED 由于同时具备自发光,不需背光源、对比度高、厚度薄、视角广、反应速度快、可用于挠曲性面板、使用温度范围广、构造及制程较简单等优异之特性,被认为是下一代的平面显示器新兴应用技术。 LCD 都需要背光,而 OLED 不需要,因为它是自发光的。这样同样的显示,OLED 效果要来得好一些。以目前的技术,OLED 的尺寸还难以大型化,但是分辨率确可以做到很高 值得注意的是,该模块不和 5.0V 接口兼容,别直接接到 5V 的系统上去,否则可能烧坏模块

2.模块特点

1)模块有单色和双色两种可选,单色为纯蓝色,而双色则为黄蓝双色。 2)尺寸小,显示尺寸为 0.96 寸,而模块的尺寸仅为 27mm26mm 大小。 3)高分辨率,该模块的分辨率为 12864。 4)多种接口方式,该模块提供了总共 5 种接口包括:6800、8080 两种并行接口方式、3 线或 4 线的穿行 SPI 接口方式,、IIC 接口方式(只需要 2 根线就可以控制 OLED 了!)。 5)不需要高压,直接接 3.3V 就可以工作了。

3.接线方式

stm32----------四针脚OLED

G-----------------GND

3.3---------------VCC

PB5--------------SCL

PB6--------------SDA

注:SCL与SDA的外设GPIO引脚不一定必须是PB6与PB5,可以在程序里面修改

4.源代码

main.c

#include "delay.h"
#include "key.h"
#include "usart.h"
#include "timer.h"
#include "oled.h"

//GND  接电源地
//VCC  接5V或3.3v电源
//D0   接(SCL)
//D1   接(SDA)

int main(void)
{		
	 delay_init();	    	 //延时函数初始化	  
	 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 
	 OLED_Init(); //OLED初始化
	 OLED_Clear();
	
	 
   OLED_WR_Byte(0x2E,OLED_CMD);        //关闭滚动
   OLED_WR_Byte(0x26,OLED_CMD);        //水平向左或者向右滚动 26/27
   OLED_WR_Byte(0x00,OLED_CMD);        //虚拟字节
   OLED_WR_Byte(0x00,OLED_CMD);        //起始页0
   OLED_WR_Byte(0x07,OLED_CMD);        //滚动时间间隔
   OLED_WR_Byte(0x07,OLED_CMD);        //终止页 7
   OLED_WR_Byte(0x00,OLED_CMD);        //虚拟字节
   OLED_WR_Byte(0xFF,OLED_CMD);        //虚拟字节
   OLED_WR_Byte(0x2F,OLED_CMD);        //开启滚动
	 
 	
	 OLED_ShowChinese(0,0,0,16);     //"人"
	 OLED_ShowChinese(16,0,1,16);    //"间"
	 OLED_ShowChinese(16*2,0,2,16);  //"尤"
	 OLED_ShowChinese(16*3,0,3,16);  //"物"
     OLED_ShowChinese(16*4,0,4,16);  //"绝"
	 OLED_ShowChinese(16*5,0,5,16);  //"世"
	 OLED_ShowChinese(16*6,0,6,16);  //"颜"

	 
	 OLED_ShowChinese(0,16,7,16);    //"风"
	 OLED_ShowChinese(16,16,8,16);   //"华"
	 OLED_ShowChinese(16*2,16,9,16); //"绝"
	 OLED_ShowChinese(16*3,16,10,16);//"代"
     OLED_ShowChinese(16*4,16,11,16);//"鞠"
	 OLED_ShowChinese(16*5,16,12,16);//"婧"
	 OLED_ShowChinese(16*6,16,13,16);//"祎"

	 
	 
	 OLED_Refresh_Gram();
	
	
	
   while(1)
	 {

	 }
}

汉字显示函数

void OLED_ShowChinese(u8 x,u8 y,u8 num,u8 size1)
{
	u8 i,m,n=0,temp,chr1;
	u8 x0=x,y0=y;
	u8 size3=size1/8;
	while(size3--)
	{
		chr1=num*size1/8+n;
		n++;
			for(i=0;i<size1;i++)
			{
				if(size1==16)
						{temp=Hzk1[chr1][i];}//调用16*16字体
				else return;
							
						for(m=0;m<8;m++)
							{
								if(temp&0x01)OLED_DrawPoint1(x,y);
								else OLED_ClearPoint1(x,y);
								temp>>=1;
								y++;
							}
							x++;
							if((x-x0)==size1)
							{x=x0;y0=y0+8;}
							y=y0;
			 }
	}
}

温度显示函数

void read_AHT20(void)
{
	uint8_t   i;
	for(i=0; i<6; i++)
	{
		readByte[i]=0;
	}

	//-------------
	I2C_Start();

	I2C_WriteByte(0x71);
	ack_status = Receive_ACK();
	readByte[0]= I2C_ReadByte();
	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();
	SendNot_Ack();
	//Send_ACK();

	I2C_Stop();

	//--------------
	if( (readByte[0] & 0x68) == 0x08 )
	{
		H1 = readByte[1];
		H1 = (H1<<8) | readByte[2];
		H1 = (H1<<8) | readByte[3];
		H1 = H1>>4;

		H1 = (H1*1000)/1024/1024;

		T1 = readByte[3];
		T1 = T1 & 0x0000000F;
		T1 = (T1<<8) | readByte[4];
		T1 = (T1<<8) | readByte[5];

		T1 = (T1*2000)/1024/1024 - 500;

		AHT20_OutData[0] = (H1>>8) & 0x000000FF;
		AHT20_OutData[1] = H1 & 0x000000FF;

		AHT20_OutData[2] = (T1>>8) & 0x000000FF;
		AHT20_OutData[3] = T1 & 0x000000FF;
	}
	else
	{
		AHT20_OutData[0] = 0xFF;
		AHT20_OutData[1] = 0xFF;

		AHT20_OutData[2] = 0xFF;
		AHT20_OutData[3] = 0xFF;
		printf("lyy");

	}
	/*通过串口显示采集得到的温湿度
	printf("\r\n");
	printf("温度:%d%d.%d",T1/100,(T1/10)%10,T1%10);
	printf("湿度:%d%d.%d",H1/100,(H1/10)%10,H1%10);
	printf("\r\n");*/
	t=T1/10;
	t1=T1%10;
	a=(float)(t+t1*0.1);
	h=H1/10;
	h1=H1%10;
	b=(float)(h+h1*0.1);
	sprintf(strTemp,"%.1f",a);   //调用Sprintf函数把DHT11的温度数据格式化到字符串数组变量strTemp中  
    sprintf(strHumi,"%.1f",b);    //调用Sprintf函数把DHT11的湿度数据格式化到字符串数组变量strHumi中  
	GUI_ShowCHinese(16,00,16,"温湿度显示",1);
	GUI_ShowCHinese(16,20,16,"温度",1);
	GUI_ShowString(53,20,strTemp,16,1);
	GUI_ShowCHinese(16,38,16,"湿度",1);
	GUI_ShowString(53,38,strHumi,16,1);
	delay_ms(1500);		
	delay_ms(1500);
}

点阵函数表达

{0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x80,0x40,0x20,0x10,0x0C,0x03,0x00,0x00,0x00,0x03,0x0C,0x10,0x20,0x40,0x80,0x00},/*"人",0*/
/* (16 X 16)*/

{0x00,0xF8,0x01,0x06,0x00,0xF0,0x12,0x12,0x12,0xF2,0x02,0x02,0x02,0xFE,0x00,0x00},
{0x00,0xFF,0x00,0x00,0x00,0x1F,0x11,0x11,0x11,0x1F,0x00,0x40,0x80,0x7F,0x00,0x00},/*"间",1*/
/* (16 X 16)*/

{0x10,0x10,0x10,0x10,0x10,0xFF,0x10,0x10,0xF0,0x10,0x11,0x16,0x10,0x10,0x10,0x00},
{0x80,0x40,0x20,0x18,0x06,0x01,0x00,0x00,0x3F,0x40,0x40,0x40,0x40,0x40,0x78,0x00},/*"尤",2*/
/* (16 X 16)*/

{0x40,0x3C,0x10,0xFF,0x10,0x10,0x20,0x10,0x8F,0x78,0x08,0xF8,0x08,0xF8,0x00,0x00},
{0x02,0x06,0x02,0xFF,0x01,0x01,0x04,0x42,0x21,0x18,0x46,0x81,0x40,0x3F,0x00,0x00},/*"物",3*/
/* (16 X 16)*/

{0x20,0x30,0xAC,0x63,0x10,0x20,0x10,0xE8,0x27,0x24,0xE4,0x34,0x2C,0xE0,0x00,0x00},
{0x22,0x67,0x22,0x12,0x12,0x00,0x00,0x3F,0x42,0x42,0x43,0x42,0x42,0x43,0x70,0x00},/*"绝",4*/
/* (16 X 16)*/

{0x20,0x20,0x20,0xFE,0x20,0x20,0xFF,0x20,0x20,0x20,0xFF,0x20,0x20,0x20,0x20,0x00},
{0x00,0x00,0x00,0x7F,0x40,0x40,0x47,0x44,0x44,0x44,0x47,0x40,0x40,0x40,0x00,0x00},/*"世",5*/
/* (16 X 16)*/

{0x00,0xE4,0x2C,0x35,0xA6,0x74,0x2C,0x24,0x02,0xF2,0x1A,0xD6,0x12,0xF2,0x02,0x00},
{0x40,0x3F,0x80,0x89,0x44,0x22,0x11,0x08,0x80,0x4F,0x30,0x0F,0x10,0x2F,0xC0,0x00},/*"颜",6*/
/* (16 X 16)*/

{0x00,0x00,0xFE,0x02,0x12,0x22,0xC2,0x02,0xC2,0x32,0x02,0xFE,0x00,0x00,0x00,0x00},
{0x80,0x60,0x1F,0x00,0x20,0x10,0x0C,0x03,0x0C,0x30,0x00,0x0F,0x30,0x40,0xF8,0x00},/*"风",7*/
/* (16 X 16)*/

{0x20,0x10,0x08,0xFC,0x03,0x20,0x20,0x10,0x7F,0x88,0x88,0x84,0x82,0xE0,0x00,0x00},
{0x04,0x04,0x04,0x05,0x04,0x04,0x04,0xFF,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00},/*"华",8*/
/* (16 X 16)*/

{0x20,0x30,0xAC,0x63,0x10,0x20,0x10,0xE8,0x27,0x24,0xE4,0x34,0x2C,0xE0,0x00,0x00},
{0x22,0x67,0x22,0x12,0x12,0x00,0x00,0x3F,0x42,0x42,0x43,0x42,0x42,0x43,0x70,0x00},/*"绝",9*/
/* (16 X 16)*/

{0x00,0x80,0x60,0xF8,0x07,0x20,0x20,0x20,0x7F,0xA0,0x10,0x11,0x16,0x10,0x10,0x00},
{0x01,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x03,0x0C,0x10,0x20,0x40,0xF8,0x00},/*"代",10*/
/* (16 X 16)*/

{0x04,0xC4,0x5F,0xF4,0x5F,0xC4,0x14,0x08,0x27,0x44,0xF4,0x44,0x24,0x04,0xFC,0x00},
{0x08,0x0B,0x0A,0xFF,0x0A,0x0B,0x08,0x11,0x09,0x05,0x3F,0x05,0x49,0x81,0x7F,0x00},/*"鞠",11*/
/* (16 X 16)*/

{0x10,0x10,0xF0,0x1F,0x10,0xF0,0x44,0x54,0x54,0x54,0x7F,0x54,0x54,0x54,0x44,0x00},
{0x40,0x22,0x15,0x08,0x16,0x61,0x00,0xFF,0x15,0x15,0x15,0x55,0x95,0x7F,0x00,0x00},/*"婧",12*/
/* (16 X 16 , )*/

{0x08,0x08,0x89,0xEE,0x58,0x80,0x08,0x48,0x48,0x48,0xFF,0x48,0x48,0x48,0x48,0x00},
{0x02,0x01,0x00,0xFF,0x00,0x00,0x02,0x02,0x02,0x02,0xFF,0x02,0x12,0x22,0x1E,0x00},/*"祎",13*/
/* (16 X 16)*/

5.烧录运行

1)固定文字

 

2)温湿度

 

3)滚屏

 

三、总结

       通过I2C的接口使用STM32来采集AHT20测得的温度上传到上位机,这个实验是我们了解到了SPI协议,了解到了I2C的工作模式。下面两个实验的要求是关于OLED显示平显示AHT20所测得的温度和湿度,然后使用OLED显示滚动字幕。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值