stm32 基于蓝桥物联网赛 oled屏使用

news/2025/3/12 8:28:39/

oled屏是物联网赛道必考的题目,其综合了I2C协定等等知识,不讲原理,纯讲应用,现在开始。

补充资源代码

资源包给我们的代码是不全的,比如oled屏中的OLED_Write函数并没有定义,因此我们需要先将该函数补全。这个补全的代码可以写在I2C.c文件中,注意,要写在代码插销里面。该代码是要死记硬背的,没有技巧可言。。。

void OLED_Write(uint8_t ucType,uint8_t ucData)
{uint16_t pdata[2] = {0};pdata[0] = ucType;pdata[1] = ucData;HAL_I2C_Master_Transmit(&hi2cl,0x78,pdata,2,10);}

当我们补充完代码以后,就应该初始化oled了,在main函数里面写上OLED_Init函数。

task.h文件

我们平 平时使用oled屏幕,一般不会只使用它的一个功能,因此我们需要设置状态机。我们另开一个.c和.h文件,用于编写我们的任务函数。

oled状态机

首先我们先定义一个枚举参数,里面保存着状态机的状态,分为主状态和时间显示状态。令主状态为0,则时间显示状态就为1.oled一般来说贯彻整个项目,因此我们extern一个状态变量,使其可以在整个项目中使用,便于变化。

typedef enum      //oled屏幕的状态(状态机
{State_Main = 0,State_Time_Num
}interface;extern interface state; //定义一个全文件变量,可以被项目中所有文件使用

按键当前状态

 按键状态我们使用经典三段式,up表示按键松开,down表示按键按下,old表示的是旧状态。结合经典三段消抖代码,可以做到有效消除机械抖动。

typedef struct
{uint8_t Key_Up;uint8_t Key_Down;uint8_t Key_Old;
}Key_State;

任务时间gap(刷新率)

定义一个结构体,里面用于存放两个事件的刷新频率,在两个任务开始的时候,都会进行判断。这两个参数会在滴答计时器里面进行累加。因为此次我们代码想要实现的就是数字的累加,因此额外定义了一个参数来存放时间参数。

typedef struct           //定义一个结构体,保存事件的运行间隔时间,在systick中断函数中进行累加。
{uint16_t Oled_Time;uint16_t Key_Time;}Task_Time;extern Task_Time task_time;
extern uint16_t Time_Num;
	task_time.Key_Time++;task_time.Oled_Time++;Time_Num++;//滴答中断中补充代码

 宏定义

在.h文件中实现一些宏定义,首先定义oled和按键的刷新时间,这代表了oled和按键工作函数每几秒工作一次。接着是按键的宏定义。无需严格写成这样子,只要三个数据不同即可。

#define Oled_Min_Time 200		//定义oled和按键的最小刷新时间
#define Key_Min_Time	20		#define Asw_None 0x00    //定义按键,为后续的逻辑运算做准备
#define Asw_1 0x01					//二进制为0001
#define Asw_2 0x02 			//二进制为0010  #define 后面不需要加;号

task.c文件

全局参数定义

定义四大件,即使在.h文件中已经定义过,但是在.c文件中还是得在定义一次。定义过去的状态是为了实现刷新,如果我们没有进行合理的刷新,会导致屏幕在切换的时候处于叠加状态,这是显然不行的。

interface state = State_Main; 			//定义当前状态
interface old_state = State_Main;       //定位过去状态
Task_Time task_time;					//gap时间
Key_State Key;							//按键状态uint16_t Time_Num;

 OLED处理函数

oled函数中需要实现的就是屏幕显示的问题。首先定义oled的数据缓冲区,这是一个uint8_t类型的数组,一般来说只需要20个单位即可。接着判断是否已经到了刷新时间,如果到了,即oled累加以后的时间已经大于最小刷新时间了,那就刷新即工作一次,接着把oled屏的时间置零。如果没到,那就直接return,不刷新屏幕。接着进入switch选择,选择的目标是我们设定的state,state的改变由按键处理函数决定。如果当前设定为主界面,那就判断现在的界面和老界面是否一样,如果不一样,那就把老界面改为新界面的状态,保持状态一致,并且把老界面进行一次清理;接着将想要显示的写入数据缓冲中,然后break;时间界面也是同理。在处理完这些后,显示oled。

void Oled_Proc()
{uint8_t Oled_buf_line1 [20] = {0};			//定义第一行要显示的数据uint8_t Oled_buf_line2 [20] = {0};			//定义第二行要显示的数据if(task_time.Oled_Time < Oled_Min_Time)	return;				//判断是否到了刷新时间task_time.Oled_Time = 0;															//如果到了刷新时间,就把记时清零switch(state)																				//判断目前状态{							case State_Main:if(state!=old_state)                           //如果当前状态和之前状态不一样,就刷新oled{old_state = state;OLED_Clear();}sprintf((char*)Oled_buf_line1,"HELLO WORLD");		//主页面就打印hello world,把数据写入line1缓冲区break;case State_Time_Num:if(state!=old_state){old_state = state;OLED_Clear();}sprintf((char*)Oled_buf_line1,"Time:%05d",Time_Num);	//时间界面打印时间,所以把时间数据写入line2缓存区break;}OLED_ShowString(0,0,Oled_buf_line1,16);									//oled的显示OLED_ShowString(0,0,Oled_buf_line2,16);	
}

按键处理函数 

按键处理函数刚开始也是同理,先判断按键刷新时间到了没,接着定义一个代表按键的值,Key_Value.因为目前我们任务要的是asw1按下,那么我们就判断asw的状态,如果asw按下(即asw为reset状态),则把Key_Value设置为Asw_1.如果不是,那就把他设置为Asw_None。接着就是经典三段防抖。up的判断逻辑是先确定是否有状态的改变(Key_Value ^ Key.Key_Old),然后与上Key_Value,这是判断现在是松按键的时刻。down也是同理。而oled_old只要每次在最后刷新一下即可。接着就是朴实无华的检测,如果按下以后是Asw_1那就切换页面,如果不是,那就不进if

void Key_Proc()
{if(task_time.Key_Time < Key_Min_Time)	return;						//判断是否到key_proc的刷新时间task_time.Key_Time = 0;uint16_t Key_Value;if(HAL_GPIO_ReadPin(ASW1_GPIO_Port,ASW1_Pin) == GPIO_PIN_RESET)      //判断按下的是不是asw1,如果是,就赋值,如果不是甚至没按,就为0{Key_Value = Asw_1;}else   {Key_Value = Asw_None;}Key.Key_Up = Key_Value &(Key_Value ^ Key.Key_Old);					//三段经典消除按键抖动Key.Key_Down = ~Key_Value &(Key_Value ^ Key.Key_Old);	Key.Key_Old = Key_Value;if(Key.Key_Down == Asw_1)																		//确定按下了,就开始切换工作{if(state == State_Main) state = State_Time_Num;else state = State_Main;Key.Key_Down = Asw_None;																		//复位key_down}				
}


http://www.ppmy.cn/news/1578559.html

相关文章

【python高并发】高速将图片提交到flask、fastapi等主流服务框架

一、摘要 高性能,高并发的读取图片,并将图片传输到服务器的应用场景很多,比如上传图片到网站,将图片提交到后台推理等。这篇文章实现一种多线程并发方式将图片提交到后台。 二、多线程发送请求的实现方法 1. 使用ThreadPoolExecutor线程池 通过线程池管理并发请求,避免…

【前端基础】:HTML

认识 HTML 标签 HTML 代码是由 “标签” 构成的. 形如: <body>hello</body>标签名 (body) 放到 <> 中 大部分标签成对出现. 为开始标签, 为结束标签 少数标签只有开始标签, 称为 “单标签”. 开始标签和结束标签之间, 写的是标签的内容. (hello) 开始标签中…

正则表达式快速入门

原文链接&#xff1a;https://kashima19960.github.io/2025/03/10/正则表达式快速入门/ 前言 我写这篇文章&#xff0c;用来记录我平时使用正则表达式的方法&#xff0c;这样我在分享知识给大家的同时&#xff0c;也复习了一遍正则表达式。在你学习某个知识的时候&#xff0c;…

前端开发中的设计模式:观察者模式的应用与实践

1. 引言 1.1 设计模式的重要性 设计模式是软件开发中经过验证的解决方案&#xff0c;能够帮助开发者解决常见的设计问题。在前端开发中&#xff0c;合理使用设计模式可以提高代码的可维护性、可扩展性和复用性。 1.2 本文的目标 本文旨在深入探讨观察者模式在前端开发中的应…

Python数据分析之机器学习基础

Python 数据分析重点知识点 本系列不同其他的知识点讲解&#xff0c;力求通过例子让新同学学习用法&#xff0c;帮助老同学快速回忆知识点 可视化系列&#xff1a; Python基础数据分析工具数据处理与分析数据可视化机器学习基础 五、机器学习基础 了解机器学习概念、分类及…

HTML左右分页2【搬代码】

HTML左右分页2 html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>左右分页布局</title>&l…

清华同方国产电脑能改windows吗_清华同方国产系统改win7教程

清华同方国产电脑能改windows吗&#xff1f;清华同方国产电脑如果采用的是兆芯kx-6000系列或kx-7000系列以及海光c86 3250 3350 X86架构处理器可以安装windows。在安装win7时bios中要关闭“安全启动”和开启legacy传统模式支持&#xff0c;如果是NVME接口的固态硬盘&#xff0c…

Tomcat+Servlet运行后出现404错误解决方案

TomcatServlet运行后出现404错误解决方案 一、错误效果复现 后续的解决方案&#xff0c;仅仅针对我遇到的情况。对不能涵盖大部分情况感到抱歉。 二、错误分析 先看看源代码&#xff1f; package com.example.secondclass.Servlet; import java.io.*; import jakarta.servl…