25/1/13 嵌入式笔记 继续学习Esp32

PWM(Pulse Width Modulation,脉宽调制) 是一种通过快速切换高低电平来模拟中间电压值的技术。它广泛应用于控制 LED 亮度、电机速度、音频生成等场景。

analogWrite函数:用于在微控制器(如 Arduino)上生成模拟信号

使用analogWrite改变亮度。

#define POT 26
#define LED 13
//初始化电位计输入信号
int pot_value;
int led_value;

void setup(){
  pinMode(POT,INPUT);
  pinMode(POT,INPUT);  
}
void loop(){
  //读取电位计模拟输入值
  pot_value=analogRead(POT);
  //吧电位计模拟输入值转换为LED模拟输出
  led_value = pot_value/16;
  analogWrite(LED,led_value);
  delay(50);
}

使用LEDC外设

#define POT 26
#define LED 13
#define CHANNEL 0
#define RESOLUTION 12
#define FREQ 1000

//初始化电位计输入信号
int pot_value;//用于存储电位计读取的模拟值
int led_value;

void setup(){ 
  //设置ADC分辨率
  analogReadResolution(12);
  //配置输入衰减
  analogSetAttenuation(ADC_11db);
  //建立LEDC通道,配置LEDC分辨率
  ledcSetup(CHANNEL,1000,12);
  //关联GPIO与LEDC通道
  ledcAttachPin(LED,CHANNEL);
}
void loop(){
  //读取电位计模拟输入值
  pot_value=analogRead(POT);
  //输出PWM
  ledcWrite(CHANNEL,pot_value);
  delay(50);
}

I2C控制LED1602

设计理念是:信号线尽量少并且速率要尽量高,信号线少,可以减少引脚占用,这对早期的芯片(引脚很少)的很重要。

标准的I2C需要两根信号线:

SCL:时钟线,时钟都是有master提供的

SDA:双向数据线,发数据或者收数据(收发不能同时)

简单来说,只需要2根线,就可以对多台设备传输大量数据,减少单片机上IO口的占用。

TIP:需要将LiquidCrystal_I2C.h和.cpp文件放在一个目录下

库的使用:

显示文字在液晶屏上。

#include "LiquidCrystal_I2C.h"

//构造LCD对象,设置地址,列数,行数
LiquidCrystal_I2C lcd(0x27,16,2);

void setup(){ 
  //初始化LCD对象
  lcd.init();

  //打印内容
  lcd.backlight();
  lcd.print("Hello,world!");
}
void loop(){
  
}

通过串口显示

Serial.available()//判断串口缓冲区有没有数据,若大于0就读取了数据

Serial.read()//从串口读取一个字节的数据,并将其写入 LCD 显示屏。这通常用于将通过串口接收到的字符显示在 LCD 上。

Adafruit_SSD1306的使用

上述知识均来自小破站的

18. SPI 控制 OLED 液晶屏_哔哩哔哩_bilibili这里面。

使用步骤:

1.初始化OLED,调用构造函数,调用begin方法

2.初始化完成后,调用绘制类函数,当然可以设置颜色,字体

3.绘制完毕,调用显示类函数display。

#include <Arduino.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define WIDTH 128
#define HEIGH 64
#define OLED_MOSI 13 
#define OLED_SCK 18
#define OLED_DC 2 
#define OLED_CS 4
#define OLED_RESET 15


Adafruit_SSD1306 oled(WIDTH,HIGH,OLED_MOSI,OLED_SCK,
                      OLED_DC,OLED_RESET,OLED_CS);

//初始化进度
int progress=0;

void setup() {
  //OLED初始化
  oled.begin();
  //清除显示
  oled.clearDisplay();
  //绘制水平线
  oled.drawFastHLine(32,5,48,SSD1306_WHITE);
  //绘制斜线
  oled.drawLine(32,5,48,30,SSD1306_WHITE);
  //绘制矩形
  oled.drawRect(5,5,10,25,SSD1306_WHITE);
  //绘制实心矩阵
  oled.fillRect(75,5,10,30,SSD1306_WHITE);
  //设置光标位置
  oled.setCursor(5,50);
  //设置文本颜色
  oled.setTextColor(SSD1306_WHITE);
  //显示文字
  oled.println("Hello,world!");
  //显示内容
  oled.display();
}

void loop() {
  //清楚显示
  oled.clearDisplay();
  //设置光标位置
  oled.setCursor(25,40);
  //显示文字
  oled.println("Progress");
  //显示进度条边框
  oled.drawRoundRect(0,10,128,20,5,SSD1306_WHITE);
  //显示进度
  oled.fillRoundRect(5,15,progress,10,2,SSD1306_WHITE);
  //进度递增
if (progress<118)
{
  progress++;
}
else
{
  progress=0;
}
  //显示内容
  oled.display();
  //延时
  delay(50);
}

U8G2库控制OLED

平台支持性好,支持中文

#include <Arduino.h>
#include <U8g2lib.h>

//构造对象
U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI u8g2(U8G2_R0,18,13,4,2,15);

void setup() {
  //初始化OLED对象
  u8g2.begin();
  //开启中文字符集支持
  u8g2.enableUTF8Print();
  //设置字体
  u8g2.setFont(u8g2_font_wqy12_t_chinese2);

}

void loop() {
  //清除缓存区内容
  u8g2.clearBuffer();
  //绘制内容
  u8g2.setCursor(0,15);
  u8g2.print("Hello,World!");

  u8g2.setCursor(0,40);
  u8g2.print("你好,ESP32");
  //发送缓存区内容到OLED显示
}

按键控制菜单

#include <Arduino.h>
#include <U8g2lib.h>

#define BUTTON_UP 12
#define BUTTON_DOWN 14

void display_menu();

//定义菜单列表
char *menu[4] = {"Item 1","Item 2","Item 3","Item 4"};
//构造对象
U8G2_SSD1306_128X64_NONAME_1_4W_SW_SPI u8g2(U8G2_R0,18,13,4,2,15);

//初始化按键列表
unsigned int order = 0;
void setup() {
  //初始化OLED对象
  u8g2.begin();
  u8g2.setFont(u8g2_font_6x12_tr);

  //配置输出按键
  pinMode(BUTTON_UP,INPUT_PULLUP);
  pinMode(BUTTON_DOWN,INPUT_PULLUP);
}

void loop() 
{
  //判断按键是否按下,并记录位置
  if(!digitalRead(BUTTON_UP)){
    order = (order - 1 + 4)%4;
  }
  if(!digitalRead(BUTTON_DOWN)){
    order = (order + 1)%4;
  }
  display_menu(order);
  delay(80);
}
void display_menu(){
  u8g2.firstPage();
  do 
  {
    //绘制页面内容
    u8g2.drawStr(0,12,"Menu");
    u8g2.drawHLinie(0,14,128);
    for(int i=0;i<4;i++){
      if(i==index){
        u8g2.drawStr(5,(i+2)*12+2,">");
        u8g2.drawStr(20,(i+2)*12+2,menu[i]);
      }else{
      u8g2.drawStr(5,(i+2)*12+2,menu[i]);
      }
    }
  }while(u8g2.nextPage());

}
   

中断分类:

硬件中断,也称外部中断,一键中断响应外部硬件时间而发生,

软件中断:当触发软件事件时,会发生这种类型的中断。

在中断执行函数中不能用delay()函数

delay() 的工作原理
  • delay() 函数依赖于 Arduino 的 millis() 函数,后者通过定时器中断来更新时间。

  • 在 delay() 执行期间,程序会不断检查 millis() 的值,直到达到指定的延时时间。

  • 如果在 ISR 中使用 delay(),会导致以下问题:

    • 阻塞其他中断delay() 依赖于定时器中断,但在 ISR 中,定时器中断被禁用,导致 millis() 无法更新,delay() 会一直阻塞。

    • 影响系统实时性:ISR 应该尽快执行完毕,delay() 会延长 ISR 的执行时间,影响系统的响应能力。

简单来说delay是一个阻塞函数,他会暂停代码的执行,会中断积压。

定时器中断

ESP32通过定时器可以完成各种预设好的任务,ESP32定时器达到指定时间后也会产生中断,然后在回调函数内执行所需功能。

#define LED 2
#define LED_ONCE 4

hw_timer_t *timer = NULL;
hw_timer_t *timer_once = NULL;

// 定时中断函数:用于 LED 闪烁
void IRAM_ATTR timer_interrupt() {
  digitalWrite(LED, !digitalRead(LED)); // 切换 LED 状态
}

// 一次性定时中断函数:用于点亮 LED_ONCE
void IRAM_ATTR timer_once_interrupt() {
  digitalWrite(LED_ONCE, HIGH); // 点亮 LED_ONCE
}

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(LED_ONCE, OUTPUT);

  // 初始化定时器
  timer = timerBegin(0, 80, true);         // 使用定时器 0,分频系数 80,向上计数
  timer_once = timerBegin(1, 80, true);    // 使用定时器 1,分频系数 80,向上计数

  // 配置定时器中断
  timerAttachInterrupt(timer, &timer_interrupt, true);         // 绑定 timer_interrupt 到定时器 0
  timerAttachInterrupt(timer_once, &timer_once_interrupt, true); // 绑定 timer_once_interrupt 到定时器 1

  // 设置定时器周期(单位:微秒)
  timerAlarmWrite(timer, 1000000, true);         // 定时器 0 每 1 秒触发一次
  timerAlarmWrite(timer_once, 5000000, false);   // 定时器 1 在 5 秒后触发一次(仅一次)

  // 启用定时器报警
  timerAlarmEnable(timer);
  timerAlarmEnable(timer_once);
}

void loop() {
  // 主循环无需操作
}

软件定时器

#include <Ticker.h>
#define LED 2
#define LED_ONCE 4

//定义定时器对象
Ticker timer;
Ticker timer_once;

//切换指定引脚的电平状态
void toggle(int pin){
  digitalWrite(pin,!digitalRead(pin));
}


void setup() {
  pinMode(LED, OUTPUT);
  pinMode(LED_ONCE, OUTPUT);

  //配置定时器
  timer.attach(0.5,toggle,LED);
  timer_once.once(3,toggle,toggle,LED_ONCE);
}

void loop() {
  // 主循环无需操作
}

舵机转动

CHANNEL 是 ESP32 的 LEDC(LED PWM 控制器) 通道编号。ESP32 的 LEDC 模块提供了多个独立的 PWM 通道,可以用来生成 PWM 信号,控制设备如 LED 亮度、舵机角度等。

  • 通道 0 用于生成 PWM 信号,控制连接到 SERVO 引脚(GPIO 13)的设备(如舵机)。

#define FREQ 50
#define CHANNEL 0
#define RESOLUTION 8
#define SERVO 13
 
int calculatePWM(int degree){
  int min_width=0.5/20*pow(2,RESOLUTION);
  int max_width=2.5/20*pow(2,RESOLUTION);

  return (max_width-min_width)*degree/180+min_width;

}

void setup(){
  //建立LEDC通道
  ledcSetup(CHANNEL,FREQ,RESOLUTION);
  //关联GPIO口与LEDC通道
  ledcAttachPin(SERVO,CHANNEL);
}

void loop(){
  for (int i=0;i<=180;i+=10){
    //输出PWM,设置占空比
  ledcWrite(CHANNEL,calculatePWM(i));
  delay(500);
  }
}

ok!明天见!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

uniapp区域滚动——上划进行分页加载数据(详细教程)

##标题 用来总结和学习&#xff0c;便于自己查找 文章目录 一、为什么scroll-view?          1.1 区域滚动页面滚动&#xff1f;          1.2 代码&#xff1f; 二、分页功能&#xff1f;          2.1 如何实现&#xff…

【Git版本控制器--1】Git的基本操作--本地仓库

目录 初识git 本地仓库 认识工作区、暂存区、版本库 add操作与commit操作 master文件与commit id 修改文件 版本回退 撤销修改 删除文件 初识git Git 是一个分布式版本控制系统&#xff0c;主要用于跟踪文件的更改&#xff0c;特别是在软件开发中。 为什么要版本…

【STM32-学习笔记-7-】USART串口通信

文章目录 USART串口通信Ⅰ、硬件电路Ⅱ、常见的电平标准Ⅲ、串口参数及时序Ⅳ、STM32的USART简介数据帧起始位侦测数据采样波特率发生器 Ⅴ、USART函数介绍Ⅵ、USART_InitTypeDef结构体参数1、USART_BaudRate2、USART_WordLength3、USART_StopBits4、USART_Parity5、USART_Mode…

Spring MVC简单数据绑定

【图书介绍】《SpringSpring MVCMyBatis从零开始学&#xff08;视频教学版&#xff09;&#xff08;第3版&#xff09;》_springspringmvcmybatis从零开始 代码、课件、教学视频与相关软件包下载-CSDN博客 《SpringSpring MVCMyBatis从零开始学(视频教学版)&#xff08;第3版&…

初识JVM HotSopt 的发展历程

目录 导学 目前企业对程序员的基本要求 面向的对象 实战 学习目标 JVM 是什么 JVM 的三大核心功能 各大 JVM look 看一下虚拟机 HotSopt 的发展历程 总结 导学 目前企业对程序员的基本要求 面向的对象 实战 学习目标 JVM 是什么 JVM 的三大核心功能 即时编译 主要是…

【pytorch】注意力机制-1

1 注意力提示 1.1 自主性的与非自主性的注意力提示 非自主性提示&#xff1a; 可以简单地使用参数化的全连接层&#xff0c;甚至是非参数化的最大汇聚层或平均汇聚层。 自主性提示 注意力机制与全连接层或汇聚层区别开来。在注意力机制的背景下&#xff0c;自主性提示被称为查…

大数据技术Kafka详解 ⑤ | Kafka中的CAP机制

目录 1、分布式系统当中的CAP理论 1.1、CAP理论 1.2、Partitiontolerance 1.3、Consistency 1.4、Availability 2、Kafka中的CAP机制 C软件异常排查从入门到精通系列教程&#xff08;核心精品专栏&#xff0c;订阅量已达600多个&#xff0c;欢迎订阅&#xff0c;持续更新…

ESP-IDF学习记录(5) 画一块esp32-c3 PCB板

最近看了半个多月&#xff0c;趁着嘉立创官方活动&#xff0c;研究esp32-c3规格书&#xff0c;白嫖PCB 和元器件。原本计划按照官方推荐的搞个四层板&#xff0c;结果打样太贵&#xff0c;火速改成双层板&#xff0c;用了官方的券。小于10*10,也可以使用嘉立创的免费打样。 下面…

nginx 实现 正向代理、反向代理 、SSL(证书配置)、负载均衡 、虚拟域名 ,使用其他中间件监控

我们可以详细地配置 Nginx 来实现正向代理、反向代理、SSL、负载均衡和虚拟域名。同时&#xff0c;我会介绍如何使用一些中间件来监控 Nginx 的状态和性能。 1. 安装 Nginx 如果你还没有安装 Nginx&#xff0c;可以通过以下命令进行安装&#xff08;以 Ubuntu 为例&#xff0…

Netty 入门学习

前言 学习Spark源码绕不开通信&#xff0c;Spark通信是基于Netty实现的&#xff0c;所以先简单学习总结一下Netty。 Spark 通信历史 最开始: Akka Spark 1.3&#xff1a; 开始引入Netty&#xff0c;为了解决大块数据&#xff08;如Shuffle&#xff09;的传输问题 Spark 1.6&…

鸿蒙报错Init keystore failed: keystore password was incorrect

报错如下&#xff1a; > hvigor ERROR: Failed :entry:defaultSignHap... > hvigor ERROR: Tools execution failed. 01-13 16:35:55 ERROR - hap-sign-tool: error: Init keystore failed: keystore password was incorrect * Try the following: > The key stor…

IDEA的Git界面(ALT+9)log选项不显示问题小记

IDEA的Git界面ALT9 log选项不显示问题 当前问题idea中log界面什么都不显示其他选项界面正常通过命令查询git日志正常 预期效果解决办法1. 检查 IDEA 的 Git 设置2. 刷新 Git Log (什么都没有大概率是刷新不了)3. 检查分支和日志是否存在4. 清理 IDEA 缓存 (我用这个成功解决)✅…

ffmpeg硬件编码

使用FFmpeg进行硬件编码可以显著提高视频编码的性能&#xff0c;尤其是在处理高分辨率视频时。硬件编码利用GPU或其他专用硬件&#xff08;如Intel QSV、NVIDIA NVENC、AMD AMF等&#xff09;来加速编码过程。以下是使用FFmpeg进行硬件编码的详细说明和示例代码。 1. 硬件编码支…

65.在 Vue 3 中使用 OpenLayers 绘制带有箭头的线条

前言 在现代的前端开发中&#xff0c;地图已经成为许多项目的核心功能之一。OpenLayers 是一个强大的开源地图库&#xff0c;它提供了丰富的功能和高度的定制化支持。在本篇文章中&#xff0c;我将向大家展示如何在 Vue 3 中使用 OpenLayers 绘制带有箭头的线条。 我们将实现…

C++内存泄露排查

内存泄漏是指程序动态分配的内存未能及时释放&#xff0c;导致系统内存逐渐耗尽&#xff0c;最终可能造成程序崩溃或性能下降。在C中&#xff0c;内存泄漏通常发生在使用new或malloc等分配内存的操作时&#xff0c;但没有正确地使用delete或free来释放这块内存。 在日常开发过程…

Ubuntu上,ffmpeg如何使用cuda硬件解码、编码、转码加速

本文使用 Ubuntu 环境。Ubuntu 直接使用 APT 安装的就支持 CUDA 加速。本文使用这样下载的版本进行演示&#xff0c;你自己编译或者其他源的版本可能会不同。 ffmpeg 的一些介绍&#xff0c;以及 macOS 版本的 ffmpeg 硬件加速请见《macOS上如何安装&#xff08;不需要编译安装…

linux: 文本编辑器vim

文本编辑器 vi的工作模式 (vim和vi一致) 进入vim的方法 方法一:输入 vim 文件名 此时左下角有 "文件名" 文件行数,字符数量 方法一: 输入 vim 新文件名 此时新建了一个文件并进入vim,左下角有 "文件名"[New File] 灰色的长方形就是光标,输入文字,左下…

调用企业微信新建日程 API 报 api forbidden 的解决方案

报错详细信息&#xff1a; {"errcode":48002,"errmsg":"api forbidden, hint: [1266719663513970651415782], from ip: xxx.xxx.xxx.xxx, more info at https://open.work.weixin.qq.com/devtool/query?e48002" } 解决方案&#xff1a; 1. 登…

rtthread学习笔记系列(4/5/6/7/15/16)

文章目录 4. 杂项4.1 检查是否否是2的幂 5. 预编译命令void类型和rt_noreturn类型的区别 6.map文件分析7.汇编.s文件7.1 汇编指令7.1.1 BX7.1.2 LR链接寄存器7.1.4 []的作用7.1.4 简单的指令 7.2 MSR7.3 PRIMASK寄存器7.4.中断启用禁用7.3 HardFault_Handler 15 ARM指针寄存器1…

微软与腾讯技术交锋,TRELLIS引领3D生成领域多格式支持新方向

去年 11 月&#xff0c;腾讯推出 Hunyuan3D 生成模型&#xff0c;是业界首个同时支持文字和图像生成 3D 的开源大模型。紧接着不到一个月&#xff0c;微软便发布了全新框架 TRELLIS&#xff0c;加入 3D 资产生成领域的竞争中。TRELLIS 支持多格式输出&#xff0c;包括辐射场、3…