# RAPC-T **Repository Path**: graphwmz/rapc-t ## Basic Information - **Project Name**: RAPC-T - **Description**: 机协控制组仓库 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2024-12-01 - **Last Updated**: 2024-12-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 第 一 次 单 片 机 培 训 ## 一. 认 识 `ESP32`单 片 机 > ![看什么看](https://i-blog.csdnimg.cn/blog_migrate/3550e754ffcb8fa4453ad23804195388.png) ### 1. *什 么 是 单 片 机* ​ **一片半导体硅片集成:CPU、存储器、并行I/O、串行I/O、定时器/计数器、中断系统、系统时钟电路及系统总线的微型计算机(MCU)。具有微型计算机的属性,因而被称为单片机微型计算机,简称单片机。** ​ **单片机使用时,通常是处于测控系统的核心地位并嵌入其中,所以国际上通常把单片机称为嵌入式控制器(EMCU,Embedded MicroController Unit),或微控制器(MCU,MicroController Unit)。我国习惯于使用“单片机”这一名称。** ### 2 . 耳熟能详的单片机厂商及其芯片 a. **ST意法半导体:** 全球最大的ARM架构MCU厂商,世界第二大MCU供应商,意法半导体非常重视中国市场,广泛应用于工业控制、消费电子、物联网、通讯设备、医疗服务、安防监控等应用领域。常见芯片有STM32F103C8T6,STM32F4XX系列,STM32H7XX系列 b. **NXP恩智浦半导体:** 世界第一大MCU供应商,其MCU主要应用于汽车架构,视觉处理,多媒体和显示器,云计算和工业市场的多核soc。在工业和消费电子市场都拥有深厚的根基。常见芯片有MAC57D5xx系列,RT10xx和RT11xx系列 c. **STC宏晶微电子:**中国公司,51单片机性能偏弱且价格高,常见芯片STC89C52/52RC d. **GD兆易创新:**中国公司,目前主要业务为存储器、微控制器和传感器的研发、技术支持和销售。常见芯片GD32F303系列,GD32E517系列,GD32G5系列。 e. **WCH沁恒:**南京沁恒微电子股份有限公司,公司提供一系列基于自研专业接口IP和微处理器内核IP构建的芯片,致力于为客户提供万物互联、上下互通的芯片及解决方案。常见芯片CH32V003,ch340系列 f. **ESPRESSIF乐鑫:**ESPRESSIF乐鑫(乐鑫科技)是一家全球化的无晶圆厂半导体公司,专注于研发性能卓越、低功耗的无线通信芯片与模组。常见芯片有ESP8266(即将淘汰),ESP32C3,ESP32S2,ESP32S3,ESP32-woom-32模组系列。 g. **Arduino开源电子原型平台:**Arduino是一个便捷灵活、方便上手的开源电子原型平台,提供硬件和软件。拥有最丰富的传感器,开发板和模块支持,广泛用于教育和学习,艺术和创意,工业控制和机器人,有全球最庞大的开源社区。常见芯片:Arduino UNO,Arduino MEGA,Arduino NANO和支持Arduino固件的所有板子。 ### 3. 介 绍 一 下 我 们 要 用 的 ESP32 单片机 ![img](https://gitee.com/graphwmz/ttyyppoorraa-image/raw/master/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202024-11-13%20122638.png) #### **我们第二阶段学习单片机使用`ESP32S3N16R8`或`ESP32S3N8R2`** ![img](https://gitee.com/graphwmz/ttyyppoorraa-image/raw/master/ESP32-S3_DevKitC-1_pinlayout_v1.1.jpg) ​ 图为ESP32S3的引脚定义图 ### **为什么选择ESP32S3?** ![img](https://gitee.com/graphwmz/ttyyppoorraa-image/raw/master/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202024-11-13%20123354.png) ### 3. `ESP32` 有 哪 些 开 发 方 式 ​ 1.使用乐鑫官方提供的**ESP-IDF**平台开发,基于**C语言**和**ESP32-HAL**库。特点: ​ 2.使用**Arduino**固件开发,给板子烧录arduino固件后,可使用**C/C++和arduino**庞大的第三方库,特点: ​ 3.使用**MicroPython**开发,使用由C语言构建的Python 3语法的C++(乱),开发快速高效,特点: ​ 4,使用TinyGO开发,使用**谷歌Go语言**,当前 TinyGO 对 ESP32 的支持还**很不完善**,**比较鸡肋**,不支持 go routine,不支持网络和蓝牙等。相比 arduino 和 micropython,**实用性不强**。 ​ 5. 基于**国产RT-Thread**平台开发,特点: ## 二.点个灯先,成为点灯大师 [GPIO — Arduino-ESP32 2.0.14 documentation](https://espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/api/gpio.html) GPIO是什么? General Purpose Input Output 通用功能输出输出,用于电信号在电路中的输入输出,以方便控制电路 部件。 GPIO就是从芯片内部引出来一根功能复用的口线(电线) 功能复用是指:GPIO的引脚可以由CPU配置成不同的功能 比如:输入功能 输出功能 模拟功能 复用功能等等 ### 1. 工程模板 ```c++ #include void setup() { } void loop() { } ``` ### 2. 函数讲解 #### `setup()` ​ Arduino板子通电或复位后,即会开始执行setup() 函数中的程序,该部分只会执行一次。通常我们会在 setup() 函数中完成 ***Arduino的初始化设置,如配置I/O口状态,初始化串口等*** 操作。可以简单理解为配置 外设 #### `loop()` ​ 在setup() 函数中的程序执行完后,Arduino会接着执行loop() 函数中的程序。而loop()函数是一个**死循 环**,其中的程序会不断的重复运行。通常我们会在loop() 函数中**完成程序的主要功能**,如驱动各种模块, 采集数据等。 #### `pinMode()` ​ 函数原型: ```cpp void pinMode(uint8_t pin, uint8_t mode); /* pinMode函数是一个非常基础且重要的函数,它用于设置特定引脚(pin)的工作模式。Arduino开发板上的每个引脚都可以被配置为输入(INPUT)、输出(OUTPUT)或输入并启用内部上拉电阻(INPUT_PULLUP)模式。正确设置引脚模式是进行任何I/O操作前的必要步骤。 */ ``` ​ 参数: - pin:引脚的编号 - mode:引脚的工作模式 - INPUT_PULLUP 启用内部上拉电阻的上拉输入 - INPUT_DOWN 启用内部下拉电阻的下拉输入 - OUTPUT 将引脚配置为输出模式。在这种模式下,引脚可以输出高电平或低电平信号,用于控制外部电路。 #### `digitalWrite()` 函数原型 ```cpp void digitalWrite(uint8_t pin, uint8_t value); /* digitalWrite() 函数在Arduino编程中用于向指定的引脚(pin)写入数字高电平(HIGH)或低电平(LOW)。这个函数只能用于之前已经通过 pinMode() 函数设置为输出(OUTPUT)模式的引脚。 */ ``` 参数: - pin:需要写入数字值的引脚编号。 - value:要写入的数字值,可以是以下两种之一: - **HIGH**:向引脚输出高电平,通常对应于Arduino板的VCC电压(例如5V或3.3V,取决于板子)。 - **LOW**:向引脚输出低电平,通常对应于地(GND)电压,即0V。 ​ 上述***HIGH***和***LOW***分别可以用***1***和***0***代替 #### `delay()` ```cpp void delay(unsigned long ms); /* delay() 函数是一个非常基本且常用的函数,用于在程序中创建一个暂停或等待的时间间隔。这个函数使得程序的执行在指定的毫秒数内暂停,不执行任何其他操作 注意,这个延时函数是阻塞性的,这种阻塞行为意味着,如果你的程序中有多个任务需要并发执行,或者你需要在延时期间响应外部事件(如按钮按下或传感器读数变化),使用delay()函数可能会导致问题。例如,如果你在一个循环中使用delay()来控制LED的闪烁,那么在延时期间,程序将无法处理其他输入或执行其他任务。 */ ``` 参数: - ms:需要暂停的时间,单位是毫秒(ms)。1秒等于1000毫秒 ### 3. 直接点灯 **了解以上函数后,就可以开启我们的点灯之旅了** #### 空标题 ```cpp ``` #### 点灯1----点灯 ```cpp #include #define LED_R 3 #define LED_G 4 #define LED_B 5 void setup() { pinMode(LED_R, OUTPUT); pinMode(LED_G, OUTPUT); pinMode(LED_B, OUTPUT); } void loop() { digitalWrite(LED_R, 1); digitalWrite(LED_G, 1); digitalWrite(LED_B, 1); delay(1000); digitalWrite(LED_R, 0); digitalWrite(LED_G, 0); digitalWrite(LED_B, 0); delay(1000); } ``` #### 点灯2----流水灯1 ```cpp #include #define LED_R 3 #define LED_G 4 #define LED_B 5 void setup() { pinMode(LED_R, OUTPUT); pinMode(LED_G, OUTPUT); pinMode(LED_B, OUTPUT); } void loop() { digitalWrite(LED_R, 1); delay(750); digitalWrite(LED_G, 1); delay(750); digitalWrite(LED_B, 1); delay(750); digitalWrite(LED_R, 0); delay(750); digitalWrite(LED_G, 0); delay(750); digitalWrite(LED_B, 0); delay(750); } ``` #### 点灯3----流水灯2 ```cpp #include #define LED_R 3 #define LED_G 4 #define LED_B 5 void setup() { pinMode(LED_R, OUTPUT); pinMode(LED_G, OUTPUT); pinMode(LED_B, OUTPUT); } void loop() { digitalWrite(LED_R, 1); delay(500); digitalWrite(LED_R, 0); delay(500); digitalWrite(LED_G, 1); delay(500); digitalWrite(LED_G, 0); delay(500); digitalWrite(LED_B, 1); delay(500); digitalWrite(LED_B, 0); delay(500); } ``` #### 按键控制点灯 ![img](https://gcore.jsdelivr.net/gh/bigrich-luo/typora-picgo-images-1@master/images/202303121127685.png) `#define digitalToggle(x) digitalWrite(x, !digitalRead(x))` ```cpp #include // 宏定义主要是一种代码替换的机制,能够提高代码的可读性和可维护性 // 而变量定义则是用于在程序中存储和管理数据的标识符。 // 下面是宏定义 #define LED_R 3 #define LED_G 4 #define LED_B 5 #define LED_R_key 12 void setup() { pinMode(LED_R_key, INPUT_PULLUP); pinMode(LED_R, OUTPUT); } void loop() { if(digitalRead(LED_R_Key) == 0) { delay(15); while(digitalRead(LED_R_Key) == 0); delay(15); digitalWrite(LED_R, 1); delay(2000);//等待2秒看现象,不然循环速度太快,灯还没来得及亮就灭了。 } else if() { //其他逻辑 //delay(20); //while(); } } ``` #### 读取灰度传感器 #### 控制蜂鸣器 # 第二次单片机培训 ## 了解PWM和ADC img 注意,由于图示板子和买的板子不同,黄色的线接到你们板子上的GPIO4引脚上(G4引脚,面包板电源不画了) 注意,由于图示板子和买的板子不同,我们以图示板子的右侧和实际的板子对应,如G4引脚在实际板子上是从右往左数第4个引脚,对应图中的板子也是从右往左数。不要从左往右数 ## PWM实验原理 脉冲宽度调制(PWM),是英文 `Pulse Width Modulation` 的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在测量、通信到功率控制与变换的许多领域中。 PWM 通过调节输出不同频率(频率是指 1 秒钟内信号从高电平到低电平再回到高电平的次数(一个周期))、占空比(一个周期内高电平出现时间占总时间比例)的方波。以实现固定频率或平均电压输出。频率固定,改变占空比可改变输出电压,如下所示: ![img](https://gcore.jsdelivr.net/gh/bigrich-luo/typora-picgo-images-1@master/images/202303122325277.png) ## ADC实验原理 在学习 ADC 之前,我们要首先学习什么是模拟信号,什么是数字信号。 模拟信号(Analog Signal):模拟信号是连续变化的量或者信号,生活中接触到的信号基本都是模拟信号,温度变化,天体运动等等,这些都是连续的信息,都是模拟信号。模拟信号,简单的说就是用电信号模拟出其他的信号,比如用电信号模拟出图像,模拟出声音的声波。 数字信号(Digital Signal):数字信号是时间离散、数值离散的信号,数字信号存在采样,还存在量化,只能取到一些不连续的固定值,这也是数字信号和模拟信号之间可以进行相互转换的原因。 所以,总结就是模拟信号时间连续,幅值连续,数字信号时间离散,幅值离散。模拟电路就是使用、处理模拟信号的电路;数字电路就是使用、处理数字信号的电路。 img 举个简单的例子: 1. 指针时钟显示的就是时间的模拟信号,他表示时间是连续变化的, 2. 数字时钟显示的就是时间的数字信号,时间的显示是按照固定增量变化的,他可以显示 1、2、3,但是无法显示 1.1、2.1、等,所以在数字电路中使用的数字信号一般只能取 0 或 1,把 0 对应为低电平,把 1 对应为高电平,说白了就是有或者没有 数字信号是在模拟信号的基础上依次经过 `采样`、`量化`、`编码`而形成的。具体地说,`采样` 就是把输入的模拟信号按适当的时间间隔得到各个时刻的样本值;`量化` 是把经采样测得的各个时刻的值用二进制码来表示;`编码` 则是把量化生成的二进制数排列在一起形成顺序脉冲序列。 img ADC(Analog to Digital Converter)即模数转换器,它可以将模拟信号转换为数字信号。由于单片机只能识别二进制数字,所以外界模拟信号常常会通过 ADC 转换成其可以识别的数字信号。常见的应用就是将变化的电压转成数字信号。 ### 摇杆模块 ### 了解ESP32的LEDC外设 在 ESP32 上有一个 LEDC 外设模块专用于输出 PWM 波形。 LED PWM 控制器可以生成 16 路通道(0 ~ 15),波形的周期和占空比可配置。分为高低速两组,高速通道(0 ~ 7)由 80MHz 时钟驱动,低速通道(8 ~ 15)由 1MHz 时钟驱动。另外,每路 LED PWM 支持自动步进式地增加或减少占空比,可以用于 LED RGB 彩色梯度发生器。 作为刚入门的学习者,上面这段概念不理解也不影响我们后续的学习,我们需要了解的是 LEDC 的控制函数以及 PWM 信号的产生流程。 打开 `esp32_hal_led.h` 文件之后,我们可以看到 LEDC 的所有控制函数:(不重要,看不懂没事) ```cpp // 设置 LEDC 通道对应的频率和计数位数(占空比分辨率),返回最终频率 // 分辨率的意思就是把一个周期分成 2 的 分辨率 次方。 uint32_t ledcSetup(uint8_t channel, uint32_t freq, uint8_t bit_num); /* 第一个参数channel表示通道号,取值为0 ~ 15即可设置16个通道,其中高速通道(0 ~ 7)由80MHz时钟驱动,低速通道(8 ~ 15)由 1MHz 时钟驱动; 具体数量由板子决定,需要在培训中讲解 第二个参数freq为期望设置的频率; 第三个参数为占空比分辨率的计数位数,其取值为0 ~ 20(该值决定后面 ledcWrite 方法中占空比可写值,比如该值写10,则占空比最大可写1023 即(1< B[初始化 PWM 频率和分辨率] B --> C[将引脚连接到 PWM 通道] C --> D[设置 PWM 值] D --> E[结束] B -->|初始化频率和分辨率| F[设置通道8] C -->|连接引脚到通道| G[引脚19到通道8] D -->|设置PWM值| H[通道8的PWM值] ``` ## LEDC PWM使用示例 ### 呼吸灯 之前我们使用的 LED 做过流水灯的实验,这节课,我们学习制作呼吸灯,通过 LED 灯的亮度变化来验证 PWM 不同电压的输出。呼吸灯是指灯光在单片机的控制之下完成由亮到暗的逐渐变化,感觉好像是人在呼吸。 ```cpp #include // 宏定义主要是一种代码替换的机制,能够提高代码的可读性和可维护性 // 而变量定义则是用于在程序中存储和管理数据的标识符。 // 下面是宏定义 #define FREQ 2000 // 频率 #define CHANNEL 0 // 通道 #define RESOLUTION 8 // 分辨率 #define LED_R 19 // LED 引脚 void setup() { ledcSetup(CHANNEL, FREQ, RESOLUTION); // 设置通道 ledcAttachPin(LED, CHANNEL); // 将通道与对应的引脚连接 } void loop() { // 逐渐变亮 for (int i=0;i=0;i--) { ledcWrite(CHANNEL, i); // 输出PWM delay(5); } } ``` 这是一种输出特定信号来实现流水灯的方法 第二种简单一些 ```cpp #include // 宏定义 GPIO 输出引脚 #define LED_PIN 15 void setup() { // 配置 GPIO 输出引脚 pinMode(LED_PIN, OUTPUT); } void loop() { // 实现渐亮效果 for(int i=0;i<256;i++) { // 设置亮度模拟值 analogWrite(LED_PIN, i); // 延时 10ms delay(10); } // 实现渐灭效果 for(int i=255;i>=0;i--) { // 设置亮度模拟值 analogWrite(LED_PIN, i); // 延时 10ms delay(10); } } ``` ### 控制SG90舵机 施工中..... ### 调整电机转速 #### 认识TB6612FNG双路电机驱动 # 第三次单片机培训 ## 了解串口(UART/USART) ### 函数讲解 ## 串口使用示例 ### 串口发送 #### 串口发送字符 #### 串口发送数组 ### 串口接收 # 第四次单片机培训 ## 了解I2C,SPI IIC 是一种硬件设备间常用的接口通讯协议,全称是 Inter-Integrated Circuit,也可以写为 I2C。他的设计时的理念是:信号线尽量少并且速率要尽量高。 信号线少,可以减少引脚占用,这对早期的芯片(引脚很少)的很重要。 使用 IIC 接口时一共需要连接四根线,包括:VCC、GND、SDA、SCL,其中 SDA 和 SCL 需要占用 GPIO 管脚,连接到开发板上任何一组 IIC 接口的对应管脚都可以。 标准的 I2C 需要两根信号线: - SCL(Serial Clock):时钟线,时钟都是有 master 提供的 - SDA(Serial Data):双向数据线,发数据或者收数据(收发不能同时) 简单来说,只需要 2 根线,就可以对多台设备传输大量数据,减少单片机上 IO 口的占用。 ### 函数讲解 ## I2C使用示例 ### 点亮0.96寸LED屏 (SSD1306) #### OLED 屏幕 ​ OLED,即有机发光二极管(Organic Light Emitting Diode)。OLED 由于同时具备自发光,不需背光源、对比度高、厚度薄、视角广、反应速度快、可用于挠曲性面板、使用温度范围广、构造及制程较简单等优异之特性,被称为是第三代显示技术。 ​ LCD 都需要背光,而 OLED 不需要,因为它是自发光的。这样同样的显示 OLED 效果要来得好一些。以目前的技术,OLED 的尺寸还难以大型化,但是分辨率确可以做到很高。 ​ 我们今天用到的屏幕是 0.96 寸的 SSD1306 芯片驱动的 OLED 屏幕。ta的分辨率是 128*64,意思就是横向有 128 个像素点,纵向有 64 个。 ##### SSD1306 OLED使用示例: > 基于Adafruit OLED库 ```cpp #include #include void setup(){} void loop(){} ``` > 基于U8g2库 ```cpp #include #include <> void setup(){} void loop(){} ``` ### 连接MPU6050六轴姿态传感器 ### 使用VL53L0X微型TOF模块 # 第一次联合作业 ## 准备材料: **TT减速电机** x2;**3D打印底盘**(机构组)?还是买成品 x1;**寻迹模块** x1;**VL53L0X** x1; **TB6612FNG** x1; # 第二次联合作业 ## 准备材料: **SG90舵机** x2;**3D打印云台**(机构组)?还是买成品 x1;**MPU6050** x1;**VL53L0X** x1;