基于小熊派光强传感器BH1750状态机驱动项目升级(带LCD屏显示)

简介: 基于小熊派光强传感器BH1750状态机驱动项目升级(带LCD屏显示)

我们用multi_timer+状态机的方式实现了光强读取,文章链接如下:


基于小熊派光强传感器BH1750实践(multi_timer+状态机工程应用)


今天我们再小小的进阶一步,把它和小熊派上的OLED结合起来吧!所谓所见即所得,这才是开发最大的乐趣,在实现这个小项目之前,我们先来了解下小熊派开发板上的这个屏吧,先看下原理图是怎么接的:

640.png

640.png

如上图所示,根据Datasheet解读下该LCD的控制方式:


LCD_SPI_MOSI、LCD_SPI_CLK这两个管脚是用于建立SPI通信协议用的,传统的SPI都有SPI_MOSI(主设备输出从设备输入)、SPI_MISO(主设备输入从设备输出)、SPI_SCK(SPI的时钟线),那为什么这里没有SPI_MISO呢?


这是由于只需要进行显示,所以模组设计的时候将从机发往主机的数据线进行了隐藏,这个在Datasheet里的66页可以看到相关的说明,由于篇幅限制,这里就不贴出。

原理图管脚用途解析

LCD_WR_RS是芯片的命令/数据控制引脚:

640.png

由datasheet得知,当LCD_WR_RS引脚为低电平时,则是写命令状态,当LCD_WR_RS引脚为高电平时,为写数据状态。


LCD_RESET是LCD的复位引脚,模块上电的时候拉低,通常情况下需要将该位置1。

640.png

LCD_POWER是LCD的电源引脚,通常情况下给它直接拉高就可以正常点亮工作了。

640.png

还有一个非常重要的功能,也就是LCD的片选功能,原理图里已经将片选直接拉低,这样芯片才会被使能。

640.png

关于通信协议

640.png

对于SPI通信而言,数据是有传输时序的,即时钟相位(CPHA)与时钟极性(CPOL)的组合:CPHA的高低决定串行同步时钟是在第一时钟跳变沿还是第二个时钟跳变沿数据被采集,当CPHL = 0,在第一个跳变沿进行数据采集;CPOL的高低决定串行同步时钟的空闲状态电平,CPOL = 0,为低电平。从图中可以看出,当SCLK第一个下降沿时开始传输数据,一个时钟周期传输8bit数据,使用SPI0,按位传输,高位在前,低位在后。

项目实战

上一节,我们没有用拓展板的这个LED灯,这节我们把这个灯(LED_SW)配置起来,把原来开发板那个灯去掉。

640.png

这个灯位于开发板的PB9端口


我们将在上一个工程的基础上添加SPI相关的配置后直接实现,打开上一节的工程:

1、修改配置为LED_SW灯

640.png

2、配置SPI2

640.png

640.png

640.png

3、配置LCD_WR_RS、LCD_RESET、LCD_POWER

640.png

4、生成工程、然后移植小熊派LCD例程

包含LCD驱动源代码

640.png

将LCD相关文件添加到Keil工程

640.png

然后编译完发现有一个错误:

640.png

LIGHT_SENSOR_I2C\LIGHT_SENSOR_I2C.axf: Error: L6218E: Undefined symbol SPI2_WriteByte (referred from lcd.o).

意思是在lcd程序文件里没有定义SPI2_WriteByte这个接口。

640.png

找到这个错误的地方,添加一个这样的函数,再编译,解决问题。    


接下来在main.c中添加头文件:

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "lcd.h"
#include "HzLib.h"
/* USER CODE END Includes */

接下来添加LCD显示逻辑:

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
    /* USER CODE BEGIN 1 */
    char display_buf[20] = {0};
    /* USER CODE END 1 */
    /* MCU Configuration--------------------------------------------------------*/
    /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    HAL_Init();
    /* USER CODE BEGIN Init */
    /* USER CODE END Init */
    /* Configure the system clock */
    SystemClock_Config();
    /* USER CODE BEGIN SysInit */
    /* USER CODE END SysInit */
    /* Initialize all configured peripherals */
    MX_GPIO_Init();
    MX_I2C1_Init();
    MX_USART1_UART_Init();
    MX_SPI2_Init();
    /* USER CODE BEGIN 2 */
    /*串口初始化后加这个延时,防止后面的printf打印乱码*/
    HAL_Delay(200);
    LCD_Init();
    LCD_Clear(BLACK);//清屏为黑色
    LCD_ShowString(5, 10, 240, 32, 32, "BearPi LuxTest");//显示字符串,字体大小32*32
    printf("光强读取测试实验\n");
    Init_BH750();
    timer_init(&lsensor.timer1, lsensor.timeout_cb, 1, 1);
    timer_start(&lsensor.timer1);
    /* USER CODE END 2 */
    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while (1)
    {
        /* USER CODE END WHILE */
        /* USER CODE BEGIN 3 */
        ReadBH1750(LUX_1_MODE);
        if(1 == lsensor.Conver_completed)
        {
            sprintf(display_buf, "%d%d%d%dLux", lsensor.Lux / 1000 % 100, lsensor.Lux / 100 % 10, lsensor.Lux / 10 % 10, lsensor.Lux % 10);
            LCD_ShowString(80, 50 + 24 + 32, 240, 32, 32, display_buf); //显示字符串,字体大小32*32
            if(lsensor.Lux > LIGHT_SENSOR_THREHOLD)
            {
                HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
            }
            else
            {
                HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
            }
        }
        timer_loop();
    }
    /* USER CODE END 3 */
}


640.png

这里这么来显示的主要原因是由于小熊派提供的例程里打印字符串不带清除功能,所以会有叠加效应,后面有时间解决,如果使用清除局部区域的函数,则会造成屏幕闪烁,体验感很不好。

运行结果

当光强小于设定阈值,则亮灯

640.png

当光强大于设定阈值,则灭灯

640.png

实际例程下载:

链接:https://pan.baidu.com/s/1D3AgGO_vThTgRn09SeHPIw
提取码:nskm

往期精彩

网红物联网开发板小熊派使用评测


超轻量级网红软件定时器multi_timer(51+stm32双平台实战)


基于小熊派光强传感器BH1750实践(multi_timer+状态机工程应用)

相关文章
|
11月前
|
SQL 关系型数据库 MySQL
MySQL基础:事务
本文详细介绍了数据库事务的概念及操作,包括事务的定义、开启、提交与回滚。事务作为一组不可分割的操作集合,确保了数据的一致性和完整性。文章还探讨了事务的四大特性(原子性、一致性、隔离性、持久性),并分析了并发事务可能引发的问题及其解决方案,如脏读、不可重复读和幻读。最后,详细讲解了不同事务隔离级别的特点和应用场景。
482 4
MySQL基础:事务
|
JavaScript
SpringBoot+Vue+ElementUI 实现视频播放 轮播图效果
这篇文章介绍了如何在SpringBoot+Vue+ElementUI项目中使用vue-awesome-swiper插件实现视频播放轮播图效果,包括安装插件、引入项目和使用案例的步骤。
SpringBoot+Vue+ElementUI 实现视频播放 轮播图效果
|
小程序 JavaScript Android开发
uniapp开发时可能会遇到的问题及解决方法,uniapp避坑指南!
uniapp开发时可能会遇到的问题及解决方法,uniapp避坑指南!
|
存储 数据可视化 定位技术
【ES数据可视化】kibana实现数据大屏
【ES数据可视化】kibana实现数据大屏
475 3
|
12月前
|
测试技术 程序员 C#
《黑神话:悟空》:从Unity到UE4 —— 游戏引擎迁移的挑战与机遇
【8月更文第26天】近年来,游戏行业的发展突飞猛进,特别是在图形表现力和技术实现上。《黑神话:悟空》是一款备受期待的动作角色扮演游戏,该游戏在早期开发阶段使用了Unity引擎,但为了追求更高的视觉质量和更强大的技术能力,开发团队决定将其迁移到Unreal Engine 4 (UE4)。本文将探讨这一迁移过程中的技术挑战与机遇。
679 1
|
存储 缓存 开发者
如何利用Pygame实现动画效果?
【6月更文挑战第10天】如何利用Pygame实现动画效果?
402 1
|
SQL 分布式计算 算法
【Hive】数据倾斜怎么解决?
【4月更文挑战第16天】【Hive】数据倾斜怎么解决?
|
消息中间件 缓存 网络协议
TCP协议的秘密武器:流量控制与拥塞控制
本文将深入探讨TCP协议的关键机制,包括流量控制和拥塞控制,以解密其在网络数据传输中的作用。通过了解TCP协议的工作原理,我们可以更好地理解网络通信的稳定性和可靠性,为我们的网络体验提供更安全、高效的保障。无论您是网络爱好者、技术从业者还是普通用户,本文将为您揭开TCP协议的神秘面纱,带您进入网络传输的奇妙世界。
428 0
TCP协议的秘密武器:流量控制与拥塞控制
|
编解码 运维 负载均衡
深入浅出RPC框架|青训营笔记
由于课程涉及到的RPC知识需要自己对其有较为全面的理解后才能比较好的get到课程中提及的各种框架设计的点,因此我建议阅读Kitex框架的源码,再结合课程目录去体会Kitex设计的初衷。
242 0
深入浅出RPC框架|青训营笔记
|
SQL 监控 druid
Spring Boot 整合 Druid 指南
Spring Boot 整合 Druid 指南
44082 3