基于I2C/SPI的温湿度采集与OLED显示

一、基于I2C/SPI的温湿度采集与OLED显示

1、什么是I2C

I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。主器件用于启动总线传送数据,并产生时钟以开放传送的器件,此时任何被寻址的器件均被认为是从器件.在总线上主和从、发和收的关系不是恒定的,而取决于此时数据传送方向。如果主机要发送数据给从器件,则主机首先寻址从器件,然后主动发送数据至从器件,最后由主机终止数据传送;如果主机要接收从器件的数据,首先由主器件寻址从器件.然后主机接收从器件发送的数据,最后由主机终止接收过程。在这种情况下.主机负责产生定时时钟和终止数据传送。
软件I2C:
软件I2C一般是使用GPIO管脚,用软件控制SCL,SDA线输出高低电平,模拟I2C协议的时序。
硬件I2C:
硬件I2C对应芯片上的I2C外设,有相应I2C驱动电路,其所使用的I2C管脚也是专用的,因而效率要远高于软件模拟的I2C;一般也较为稳定,但是程序较为繁琐。

2、温湿度采集

(1)代码

奥松官网下载AHT20芯片代码: 奥松下载中心
修改main函数

#include "led.h"
#include "usart.h"
#include "temhum.h"

 int main(void)
 {	 	
    u32 CT_data[2]={0};
    volatile float  hum=0,tem=0;     
     
    delay_init();	    	 //延时函数初始化	  
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    uart_init(115200);	 //串口初始化为115200
    LED_Init();			     //LED端口初始化
    temphum_init();     //ATH20初始化    
	
	while(1)
	{
        AHT20_Read_CTdata(CT_data);       //不经过CRC校验,直接读取AHT20的温度和湿度数据 

        hum = CT_data[0]*100*10/1024/1024;  //计算得到湿度值(放大了10倍)
        tem = CT_data[1]*200*10/1024/1024-500;//计算得到温度值(放大了10倍)

        printf("湿度:%.1f%%\r\n",(hum/10));
        printf("温度:%.1f度\r\n",(tem/10));
        printf("\r\n");
        
        //延时2s,LED闪烁提示串口发送状态
        LED=0;
        delay_ms(1000);
        LED=1;
        delay_ms(1000);
	 }
}

(2)结果

在这里插入图片描述
在这里插入图片描述

二、OLED显示

1、显示学号姓名

(1)姓名点阵

使用工具转换

在这里插入图片描述

  "罗",0x00,0x00,0x3F,0xF8,0x24,0x48,0x24,0x48,0x24,0x48,0x3F,0xF8,0x02,0x00,0x04,0x00,
  0x0F,0xF0,0x10,0x10,0x68,0x20,0x04,0x40,0x02,0x80,0x03,0x00,0x1C,0x00,0xE0,0x00,/*"罗",0*/
  "子",0x00,0x00,0x7F,0xF8,0x00,0x10,0x00,0x20,0x00,0x40,0x01,0x80,0x01,0x00,0xFF,0xFE,
  0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x05,0x00,0x02,0x00,/*"子",1*/
  "豪",0x01,0x00,0x7F,0xFC,0x00,0x00,0x1F,0xF0,0x10,0x10,0x1F,0xF0,0x00,0x00,0x7F,0xFE,
  0x40,0x02,0x9F,0xF4,0x06,0x00,0x19,0x20,0x06,0xC0,0x39,0xB0,0x06,0x8C,0x39,0x80,/*"豪",2*/

(2)放到文件夹USER的gui.c–>oledfont.h

在这里插入图片描述

(3)显示代码

void TEST_MainPage(void)
{	
	GUI_ShowCHinese(28,20,16,"罗子豪",1);
	GUI_ShowString(4,48,"631907060115",16,1);
	delay_ms(1500);		
	delay_ms(1500);
}

(4)烧录

在这里插入图片描述

(5)结果

在这里插入图片描述

2、滑动显示长字符

(1)滑动命令

水平向左向右滑动

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_WR_Byte(0x2e,OLED_CMD);        //关闭滚动
OLED_WR_Byte(0x29,OLED_CMD);        //水平垂直和水平滚动左右 29/2a
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);        //终止页 1
OLED_WR_Byte(0x01,OLED_CMD);        //垂直滚动偏移量
OLED_WR_Byte(0x2F,OLED_CMD);        //开启滚动

(2)取字模

"曾",0x08,0x20,0x04,0x40,0x3F,0xF8,0x21,0x08,0x29,0x28,0x25,0x48,0x3F,0xF8,0x00,0x00,
  0x1F,0xF0,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10,/*"曾",0*/
  "经",0x10,0x00,0x11,0xFC,0x20,0x08,0x24,0x10,0x44,0x30,0xF8,0x48,0x10,0x84,0x23,0x02,
  0x40,0x00,0xFD,0xFC,0x40,0x20,0x00,0x20,0x1C,0x20,0xE0,0x20,0x43,0xFE,0x00,0x00,/*"经",1*/
  "沧",0x00,0x40,0x40,0x40,0x20,0xA0,0x21,0x10,0x02,0x08,0x84,0x04,0x4B,0xF2,0x42,0x10,
  0x12,0x10,0x22,0x10,0xE2,0x50,0x22,0x20,0x22,0x04,0x22,0x04,0x21,0xFC,0x00,0x00,/*"沧",2*/
	"海" ,0x01,0x00,0x21,0x00,0x11,0xFC,0x12,0x00,0x85,0xF8,0x41,0x08,0x49,0x48,0x09,0x28,
  0x17,0xFE,0x11,0x08,0xE2,0x48,0x22,0x28,0x23,0xFC,0x20,0x08,0x20,0x50,0x00,0x20,/*"海",3*/
  "难",0x00,0xA0,0x00,0x90,0xFC,0x80,0x05,0xFE,0x05,0x10,0x4B,0x10,0x2D,0xFC,0x29,0x10,
  0x11,0x10,0x11,0xFC,0x29,0x10,0x25,0x10,0x45,0x10,0x81,0xFE,0x01,0x00,0x01,0x00,/*"难",4*/
  "为",0x01,0x00,0x21,0x00,0x11,0x00,0x11,0x00,0x01,0x00,0x7F,0xF8,0x02,0x08,0x02,0x08,
  0x02,0x88,0x04,0x48,0x04,0x48,0x08,0x08,0x10,0x08,0x20,0x08,0x40,0x50,0x80,0x20,/*"为",5*/
  "水",0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x08,0x01,0x08,0x7D,0x90,0x05,0xA0,0x09,0x40,
  0x09,0x40,0x11,0x20,0x11,0x10,0x21,0x08,0x41,0x06,0x81,0x00,0x05,0x00,0x02,0x00,/*"水",6*/
  "除",0x00,0x40,0x78,0x40,0x48,0xA0,0x51,0x10,0x52,0x08,0x65,0xF6,0x50,0x40,0x48,0x40,
  0x4F,0xFC,0x48,0x40,0x6A,0x50,0x52,0x48,0x44,0x44,0x48,0x44,0x41,0x40,0x40,0x80,/*"除",7*/
  "却",0x08,0x00,0x08,0x00,0x08,0x7C,0x7F,0x44,0x08,0x44,0x08,0x44,0x08,0x44,0xFF,0xC4,
  0x10,0x44,0x10,0x44,0x24,0x44,0x42,0x54,0xFF,0x48,0x41,0x40,0x00,0x40,0x00,0x40,/*"却",8*/
  "巫",0x00,0x00,0x00,0x00,0x7F,0xFC,0x01,0x00,0x01,0x00,0x11,0x10,0x11,0x10,0x11,0x10,
  0x29,0x28,0x29,0x28,0x45,0x44,0x85,0x84,0x01,0x00,0x01,0x00,0xFF,0xFE,0x00,0x00,/*"巫",9*/
  "山",0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,
  0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x3F,0xF8,0x00,0x08,0x00,0x00,/*"山",10*/
  "不",0x00,0x00,0x7F,0xFC,0x00,0x80,0x00,0x80,0x01,0x00,0x01,0x00,0x03,0x40,0x05,0x20,
  0x09,0x10,0x11,0x08,0x21,0x04,0x41,0x04,0x81,0x00,0x01,0x00,0x01,0x00,0x01,0x00,/*"不",11*/
  "是",0x1F,0xF0,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10,0x10,0x10,0x1F,0xF0,0x00,0x00,
  0xFF,0xFE,0x01,0x00,0x11,0x00,0x11,0xF8,0x11,0x00,0x29,0x00,0x45,0x00,0x83,0xFE,/*"是",12*/
  "云",0x00,0x00,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0x02,0x00,
  0x04,0x00,0x04,0x00,0x08,0x40,0x10,0x20,0x20,0x10,0x7F,0xF8,0x20,0x08,0x00,0x08,/*"云",13*/

(3)main.c代码在上面改动

#include "delay.h"
#include "sys.h"
#include "oled.h"
#include "gui.h"
#include "test.h"
int main(void)
{	
	delay_init();	    	       //延时函数初始化	  
	NVIC_Configuration(); 	   //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 	
	OLED_Init();			         //初始化OLED  
	OLED_Clear(0);             //清屏(全黑)
	OLED_WR_Byte(0x2E,OLED_CMD);        //关闭滚动
    OLED_WR_Byte(0x27,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);        //虚拟字节
	TEST_MainPage();
	OLED_WR_Byte(0x2F,OLED_CMD);        //开启滚动
}

(4)修改显示函数TEST_MainPage

void TEST_MainPage(void)
{	
	GUI_ShowCHinese(28,20,16,"曾经沧海难为水除却巫山不是云",1);
	delay_ms(1500);		
	delay_ms(1500);
}

(5)烧录

在这里插入图片描述

(6)结果

在这里插入图片描述

三、总结

通过本次实验,我对I2C有了更清晰的认识,汉字显示需要先取字模,再在代码中进行相应的修改,汉字滚动则需要加上滑动命令。温湿度采集的过程中使用了I2C。总体来说收获较多。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值