目录
一、基于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。总体来说收获较多。