[ESP32 IDF+Vscode]OLED多级菜单显示(摇杆控制)

news2024/11/15 19:51:15

ADC介绍

ESP32集成了两个 12SAR(逐次逼近寄存器)adc ,共支持18个测量通道。

1、两个 ADC 通道简介:

ADC1:

  • 支持 8 个通道,包括:GPIO32 - GPIO39(并非按顺序)

ADC2:

  • 支持 10 个通道,包括:GPIO0, GPIO2, GPIO4, GPIO12 - GPIO15, GOIO25 - GPIO27(并非按顺序)

ESP32 内置霍尔传感器,采用 ADC1 的通道0和3(GPIO36 和 GPIO39)。如果想要使用ESP32内置的霍尔传感器,请不要对这两个GPIO做任何配置! 

接线方式

Ps2---        ----ESP32

VRY                ADC_CHANNEL_6(GPIO 34)

VRX                ADC_CHANNEL_7(GPIO 35)

SW                  GPIO_NUM_12

效果

 

 

 代码

void Get_keyNum(void)
{
    uint8_t KeyNum = 0;
    BaseType_t err;
    //int val_x = adc1_get_raw(PS2_X_CHANNEL);

    if (adc1_get_raw(PS2_X_CHANNEL) ==4095) {
        Delay_ms(20);
        while (adc1_get_raw(PS2_X_CHANNEL)==4095);
        Delay_ms(20);
        KeyNum = 1;

    } else if (adc1_get_raw(PS2_X_CHANNEL)==0) {
        Delay_ms(20);
        while (adc1_get_raw(PS2_X_CHANNEL)==0);
        Delay_ms(20);
        KeyNum = 2;
    }
    // 检测SW按键是否按下
    if (btn_intr_flag == 1) {
        KeyNum = 3;
        btn_intr_flag = 0;
    }
    if((key_queue!=NULL)&&(KeyNum))
    {
        err=xQueueSend(key_queue,&KeyNum,10);
        if(err!= pdPASS)
        {
            printf("Send Failed\r\n");
        }
    }
    //printf("KeyNum:%d\n", KeyNum);
}

OLED

#include <stdio.h>
#include "menu.h"
#include "dht11.h"
#include "OLED.h"
#include "bmp.h"

#define Number 25
 
//定义时间,日期,星期变量
uint16_t hour = 17;
uint16_t minute = 51;
uint16_t second = 0;
uint16_t day = 27;
uint16_t month = 8;
uint16_t year = 23;
uint8_t week = 7;
 
 
//索引数组相关
void (*current_operation_index)(); //执行当前操作函数
uint8_t func_index = 0;
 

 
/*定义了索引数组,索引数组要配合主程序按键值进行选择*/
 Menu_table  table[26]=
{
	   //序号,下一项,确定,返回
    {0, 1, 4, 0,(*show1)},//一级界面    图片
    {1, 2, 11, 1,(*show2)},//一级界面   时间
    {2, 3, 12, 2,(*show3)},//一级界面   led
    {3, 0, 13, 3,(*show4)},//一级界面   游戏
		
		//图片的下层界面
	{4, 5, 4, 0, (*show5)},  //二级界面 猫
	{5, 6, 5, 0, (*show10)}, //二级界面
	{6, 7, 6, 0, (*show6)}, //二级界面
    {7, 8, 7, 0, (*show7)}, //二级界面
    {8, 9, 8, 0, (*show8)}, //二级界面
    {9, 10, 9, 0,( *show9)},    //二级界面
    {10, 4 ,10, 0, (*show12)},  //二级界面 
		
		//时间的下层界面
    {11, 11, 11, 1, (*show13)},  //二级界面  时间
    //LED的下层界面
    {12, 12, 2, 2,(*show14)}, //二级界面 		//控制led
		//游戏的下层界面
	{13, 13, 13, 3, (*show11)}, //二级界面 
		
};

 
//按键
void  Menu_key_set(uint8_t KeyNum)
{
    OLED_Clear();
    if(KeyNum == 1)
    {   
        func_index=table[func_index].next;//按键next按下后的索引号
        OLED_Clear();
    }
    if(KeyNum == 3)
    {
        func_index=table[func_index].enter;
        OLED_Clear();
    }
    if(KeyNum == 2)
    {   
        func_index=table[func_index].back;//按键next按下后的索引号
        OLED_Clear();
    }
	current_operation_index=table[func_index].current_operation;//执行当前索引号所对应的功能函数。
    (*current_operation_index)();//执行当前操作函数


}
 
 
 
//显示菜单函数
 
void show0(void)//眼睛
{
    OLED_DrawBMPFast(yanjing);
}
 
void show1(void)//图片
{
    OLED_DrawBMPFast(tupian);
 
}
 
void show2(void)//时间
{
    OLED_ShowCHinese(50,3,0);
    OLED_ShowCHinese(66,3,1);
     
}
 
void show3(void)//LED
{
    OLED_DrawBMPFast(led);

}
 
void show4(void)//游戏图标
{
    OLED_DrawBMPFast(youxiji);
}
 
//显示图片
void show5(void)
{
    OLED_DrawBMPFast(cat);
}
void show6(void)
{
    OLED_DrawBMPFast(baozi);
}
void show7(void)
{
    OLED_DrawBMPFast(baoziyi);
}
void show8(void)
{
    OLED_DrawBMPFast(daishu);
}
void show9(void)
{
 
    OLED_DrawBMPFast(mapi);
}
void show10(void)
{
    OLED_DrawBMPFast(dog);
}
//显示太空人
void show11(void)
{
 
    OLED_DrawBMPFast(gImage_1);
    Delay_ms(Number);
    OLED_DrawBMPFast(gImage_2);
    Delay_ms(Number);
    OLED_DrawBMPFast(gImage_3);
    Delay_ms(Number);
    OLED_DrawBMPFast(gImage_4);
    Delay_ms(Number);
    OLED_DrawBMPFast(gImage_5);
    Delay_ms(Number);
    OLED_DrawBMPFast(gImage_6);
    Delay_ms(Number);
    OLED_DrawBMPFast(gImage_7);
    Delay_ms(Number);
    OLED_DrawBMPFast(gImage_8);
    Delay_ms(Number);
    OLED_DrawBMPFast(gImage_9);
    Delay_ms(Number);
    OLED_DrawBMPFast(gImage_10);
    Delay_ms(Number);
    OLED_DrawBMPFast(gImage_11);
    Delay_ms(Number);
    OLED_DrawBMPFast(gImage_12);
    Delay_ms(Number);
    OLED_DrawBMPFast(gImage_13);
    Delay_ms(Number);
    OLED_DrawBMPFast(gImage_14);
    Delay_ms(Number);
    OLED_DrawBMPFast(gImage_15);
    Delay_ms(Number);
    OLED_DrawBMPFast(gImage_16);
    Delay_ms(Number);
    OLED_DrawBMPFast(gImage_17);
    Delay_ms(Number);
    OLED_DrawBMPFast(gImage_18);
    Delay_ms(Number);
    OLED_DrawBMPFast(gImage_19);
    Delay_ms(Number);
    OLED_DrawBMPFast(gImage_20);
    Delay_ms(Number);
}
void show12(void)
{
    OLED_ShowCHinese(50,3,9);
    OLED_ShowCHinese(66,3,10);
}
 
//显示时间
void show13(void)
{
    OLED_ShowCHinese(0,3,2);
    OLED_ShowCHinese(16,3,3);
    OLED_ShowChar(32,3,':',16);
    OLED_ShowNum(40,3,20,2,16);
    OLED_ShowNum(56,3,year/10,1,16);
    OLED_ShowNum(64,3,year%10,1,16);
    OLED_ShowChar(72,3,'-',16);
    OLED_ShowNum(80,3,month/10,1,16);
    OLED_ShowNum(88,3,month%10,1,16);
    OLED_ShowChar(98,3,'-',16);
    OLED_ShowNum(104,3,day/10,1,16);
    OLED_ShowNum(112,3,day%10,1,16);
    //显示时间
    OLED_ShowCHinese(0,1,0);
    OLED_ShowCHinese(16,1,1);
    OLED_ShowChar(32,1,':',16);
    OLED_ShowNum(40,1,hour/10,1,16);
    OLED_ShowNum(48,1,hour%10,1,16);
    OLED_ShowChar(56,1,':',16);
    OLED_ShowNum(64,1,minute/10,1,16);
    OLED_ShowNum(72,1,minute%10,1,16);
    OLED_ShowChar(80,1,':',16);
    OLED_ShowNum(88,1,second/10,1,16);
    OLED_ShowNum(96,1,second%10,1,16);
    //显示星期
    OLED_ShowCHinese(0,5,4);
    OLED_ShowCHinese(16,5,5);
    OLED_ShowChar(32,5,':',16);
    OLED_ShowNum(70,5,week,1,16);
}
 
//控制led
void show14(void)
{
    OLED_DrawBMPFast(dengbao);

}
//void show15(void)
//{
//}
//void show16(void)
//{
//}
 
//控制时间,日期与星期增加
void Date_Time(void)
{
        //显示日期
 
        //判断日期
        if(hour>=24)
        {
            day++;
            week++;
            if(week >= 7)week = 1;
            if(day==30)
            {
                month++;
                day = 0;
                if(month==12)
                {
                    year++;
                    month = 0;
                    if(year > 2050 || year < 2000) year = 0;
                }
            }
        }
}



 完整代码:

ESP32 IDF Vscode: ESP32开发 - Gitee.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1048015.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DataBinding双向绑定简介

一、简介 在Vue中使用的是MVVM架构。通过ViewModel可以实现M层和V层数据的双向绑定。Model层的数据发生变化后&#xff0c;会自动更新View层UI。UI层数据发生变化&#xff08;用户输入&#xff09;&#xff0c;可以驱动Model层的数据发生变化&#xff0c;借助于Vue框架中的View…

数学建模国赛/美赛常见赛题类型及建模方案(纯干货)(2)

目录 一&#xff0c;评价类问题 1&#xff0c;建模步骤如下图所示&#xff1a; 2&#xff0c;主客观评价问题的区别 3&#xff0c;如何选择合适的评价方法 二&#xff0c;预测类赛题 1&#xff0c;预测类赛题的基本解题步骤 2&#xff0c;预测类问题的区别 3&#xff0c;…

深兰科技荣获“2023年中国人工智能行业十大创新力企业奖”

近日&#xff0c;以“i时代智创未来”为主题的“CIAI 2023第八届中国国际人工智能大会“在上海普陀区隆重召开。 大会期间&#xff0c;举行了”2023年中国人工智能行业创新力企业评选“的颁奖典礼&#xff0c;深兰科技(上海)有限公司成功荣获“2023年中国人工智能行业十大创新力…

HTTP初识,fiddler的使用,URL各部分介绍,QueryString

目录 一、什么是HTTP 二、抓包工具 三、请求的首行 URL 四、URL的各部分详细介绍 一、什么是HTTP 现在网页上&#xff0c;我们常见的是https,但是在二十年前是以http为主&#xff0c;这个协议也叫超文本传输协议&#xff0c;文本->字符串&#xff0c;“超文本”->图片…

Nginx代理victoriametrics集群配置

1,首先安装nginx yum install -y nginx 2,生成密钥文件 安装htpasswd工具 yum install -y httpd-tools 生成密钥文件,prometheus为用户名 htpasswd -c /etc/nginx/conf.d/passwd prometheus 3,修改nginx配置文件nginx.conf,增加如下内容 upstream vmselect {server 10.…

PyTorch - Dataset 迭代数据接口 __getitem__ 异常处理

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/133378772 在模型训练的过程中&#xff0c;加载数据部分&#xff0c;极其容易出现异常&#xff0c;以及不可控的因素&#xff0c;需要通过异常捕获…

RabbitMQ(15672) 消息中间件 NOTE

目录 1、初识 RabbitMQ 消息队列 1.1 MQ 四大核心概念 1.2 消息的发送&#xff08;无交换机态&#xff09; 1.3 关于消息自动重新入队 1.3.1 消息的常见应答方法&#xff08;R&#xff09; 1.4 关于 RabbitMQ 的持久化、不公平分发以及预取值 2、RabbitMQ 消息的发布确认…

Timer/计时器发布者与订阅者, Subscribar/文本框订阅模式 的使用

1. Timer 计时器的操作 1.1 实现 /// 计时器 发布者与订阅者 struct TimerBootcamp: View {// 计时器 发布者 timer1/timer3/timer5 1.0 , timer2 2.0 , timer4 0.5let timer Timer.publish(every: 1, on: .main, in: .common).autoconnect()// ---1---// 计算性属性 当前…

线性代数(七) 矩阵分析

前言 从性线变换我们得出&#xff0c;矩阵和函数是密不可分的。如何用函数的思维来分析矩阵。 矩阵的序列 通过这个定义我们就定义了矩阵序列的收敛性。 研究矩阵序列收敛性的常用方法&#xff0c;是用《常见向量范数和矩阵范数》来研究矩阵序列的极限。 长度是范数的一个特…

C语言实现---通讯录

通讯录 前言1.初始化通讯录2.SHOW展示通讯录3.ADD添加联系人的函数4.DEL删除联系人的函数5.SEARCH查找联系人的函数6.MODIFY修改联系人的函数7.销毁通讯录8.整体代码展示1.头文件"contact.h"2.源文件"contact.c"3.测试文件"test.c" 前言 那么好…

解决键盘长按才有反应

问题分析&#xff1a; 排除键盘自身没有问题&#xff0c;那就应该是电脑设置的问题&#xff0c;目前我遇到的不小心长按shift键设置了【筛选键】 解决方式&#xff1a; 打开设置搜索筛选建&#xff0c;关闭&#xff0c;粘带键也会出现类似问题。

【go语言】结构体

结构体 结构体定义 type name struct{value1 type1value2 type2...... }组成结构体的数据称为字段&#xff0c;每一个字段有一个类型和一个名字&#xff0c;每一个字段的名字必须唯一&#xff0c;字段的类型任意。 创建结构体 type myStruct struct{i1 intf1 float32str st…

【软件测试】开发/测试模型

开发/测试模型 瀑布模型 设计&#xff1a;技术文档(设计那些接口&#xff0c;库表&#xff0c;mq&#xff0c;定时任务)&#xff0c;UI视觉稿 特点&#xff1a;线性的结构。 优点&#xff1a;每个阶段做什么&#xff0c;产出什么非常清晰 缺点&#xff1a;测试人员介入太晚…

了解CISP,看这篇文章就够了,附上CISP证书题库资料

前言 【点击此处领取CISP题库资料和网络安全学习资】 什么是CISP&#xff1f; CISP是中国信息安全测评中心依据中编办赋予的职能&#xff0c;建立和发展的一整套完整的信息安全保障人才培训体系&#xff0c;从2002年开始启动。 CISP (CertifiedInformation Security Profes…

分享55个C源码源代码总有一个是你想要的

分享55个C源码源代码总有一个是你想要的 链接&#xff1a;https://pan.baidu.com/s/1_zbaunqvmYRhCiX7hbiqmg?pwd8888 提取码&#xff1a;8888 1. 项目名称 apachesubversion版本控制系统 v1.10.3 Ceph分布式文件系统 v17.2.5 clip命令行插图处理器 v0.8 curve分布式存…

在前端设计中,子元素的基线和父元素的基线分别是什么意思?并利用Bootstrap的类align-items-baseline实现子元素在其父容器内基线对齐。

子元素的基线和父元素的基线是用于文本对齐的重要概念。让我解释一下它们分别指的是什么&#xff1a; 子元素的基线&#xff08;Baseline of Child Elements&#xff09;&#xff1a; 子元素的基线是指子元素内文本的底部边缘&#xff0c;特别是字母的底部边缘。在包含文本的元…

医药行业电力供应3大难题?教你如何破解

电力是现代社会不可或缺的基础设施之一&#xff0c;它支持着工业、商业和生活的各个方面。在这个数字化、电气化的时代&#xff0c;电力配电系统扮演着关键的角色&#xff0c;确保电能以可靠、高效、安全的方式分发到我们的家庭、企业和工厂。 然而&#xff0c;要保持电力分配的…

LeetCode 518.零钱兑换II 动态规划 + 完全背包 + 组合数

给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带符号整数。 示例…

DevOps持续集成与交付

概述 Jenkins是一个支持容器化部署的、使用Java运行环境的开源软件&#xff0c;使用Jenkins平台可以定制化不同的流程与任务、以自动化的机制支持DevOps领域中的CI与CD&#xff0c;在软件开发与运维的流程中自动化地执行软件工程项目的编译、构建、打包、测试、发布以及部署&a…

FileManager/本地文件增删改查, Cache/图像缓存处理 的操作

1. FileManager 本地文件管理器&#xff0c;增删改查文件 1.1 实现 // 本地文件管理器 class LocalFileManager{// 单例模式static let instance LocalFileManager()let folderName "MyApp_Images"init() {createFolderIfNeeded()}// 创建特定应用的文件夹func cr…