Rust 语言开发 ESP32C3 并在 Wokwi 电子模拟器上运行(esp-hal 非标准库、LCD1602、I2C)

文章目录

  • esp-rs 简介
  • Github
  • Rust 包仓库
  • Rust 教程
  • Wokwi 电子模拟器
  • 开发环境
    • Rust 环境
    • esp-rs 环境
    • 创建 ESP32C3 项目
    • 项目结构
    • 编译项目命令
    • 运行模拟器
    • ESP32C3 烧录

esp-rs 简介

esp-rs 是一个专注于为 Espressif 系列芯片(如 ESP32、ESP32-S2、ESP32-C3 等)提供 Rust 语言支持的社区和项目。它的目标是为开发者提供一个高效、安全且易于使用的 Rust 开发环境,以便在 Espressif 芯片上进行嵌入式系统开发。

  • 构建工具
存储库描述
esp-rs/rust带有 Xtensa 支持的 Rust 编译器分支
esp-rs/rust-buildRust 编译器 fork 的预构建二进制文件以及安装脚本
  • 硬件抽象层
存储库描述
esp-rs/esp-idf-hal支持 Rust 标准库(std)
esp-rs/esp-hal不支持 Rust 标准库 ( no_std)

Github

  • esp-rs:https://github.com/esp-rs
  • esp-hal 非标准库:https://github.com/esp-rs/esp-hal
  • 本章示例项目源码:https://github.com/WuFengSheng/esp-rs-demo

Rust 包仓库

  • https://crates.io/

Rust 教程

  • https://rustwiki.org/zh-CN/book/
  • https://rustwiki.org/zh-CN/rust-by-example/index.html

Wokwi 电子模拟器

  • https://wokwi.com/projects/410182337086340097

在这里插入图片描述

开发环境

Rust 环境

  • 参考我的这篇文章 《使用 Rustup 管理 Rust 版本》
# 安装 nightly 版本
rustup install nightly
# 设置默认 Rust 版本
rustup default nightly
# 当前 Rust 版本
rustc --version

esp-rs 环境

  • espup安装

用于安装和维护使用 Rust 为 Espressif SoC 开发应用程序所需的工具链的工具。https://github.com/esp-rs/rust-build

cargo install espup
espup install
. $HOME/export-esp.sh
  • RISC-V 安装

以下指令专门针对基于 RISC-V 架构的 ESP32-C

rustup target add riscv32imc-unknown-none-elf
rustup component add rust-src --toolchain nightly
# 安装 cargo-generate
cargo install cargo-generate
cargo generate -h
# 安装 espflash
cargo install espflash
espflash --help
espflash flash --help

创建 ESP32C3 项目

cargo generate -a esp-rs/esp-template

在这里插入图片描述

项目结构

在这里插入图片描述

  • Cargo.toml
[dependencies]
esp-backtrace = { version = "0.14.0", features = ["esp32c3","exception-handler","panic-handler","println",
] }
esp-hal = { version = "0.20.1", features = [ "esp32c3" ] }
esp-println = { version = "0.11.0", features = ["esp32c3", "log"] }
log = { version = "0.4.21" }
  • main.rs
#![no_std]
#![no_main]
#![allow(dead_code)]use esp_backtrace as _;
use esp_hal::{clock::ClockControl, delay::Delay, peripherals::{Peripherals, I2C0}, Blocking,prelude::*, system::SystemControl, gpio::{Io, Level, Output},i2c::I2C
};const I2C_ADDR: u8 = 0x27; // LCD1602的I2C地址// LCD 指令
const LCD_CMD_CLEAR: u8 = 0x01;
const LCD_CMD_HOME: u8 = 0x02;
const LCD_CMD_ENTRY_MODE: u8 = 0x04;
const LCD_CMD_DISPLAY_CONTROL: u8 = 0x08;
const LCD_CMD_FUNCTION_SET: u8 = 0x20;
const LCD_CMD_SET_DDRAM_ADDR: u8 = 0x80;// LCD 控制位
const LCD_BACKLIGHT: u8 = 0x08;
const ENABLE: u8 = 0x04;
const RW_WRITE: u8 = 0x00;
const RS_DATA: u8 = 0x01;
const RS_COMMAND: u8 = 0x00;#[entry]
fn main() -> ! {let peripherals = Peripherals::take();let system = SystemControl::new(peripherals.SYSTEM);let clocks = ClockControl::max(system.clock_control).freeze();let delay = Delay::new(&clocks);esp_println::logger::init_logger_from_env();// Set GPIO0 as an output, and set its state high initially.let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);let mut led = Output::new(io.pins.gpio0, Level::High);// 初始化 I2Clet mut i2c: I2C<I2C0, Blocking> = I2C::new(peripherals.I2C0, io.pins.gpio6, io.pins.gpio5, 400.kHz(), &clocks);log::info!("The type of i2c is: {}", core::any::type_name_of_val(&i2c));// 初始化 LCDlcd_init(&mut i2c);lcd_write_string(&mut i2c, "Hello, World!");loop {log::info!("Hello world! \n");led.toggle();delay.delay(500.millis());}
}fn lcd_init(i2c: &mut I2C<I2C0, Blocking>) {// 设置 4-bit 模式lcd_command(i2c, 0x33); // 初始化指令lcd_command(i2c, 0x32); // 设置4-bit模式lcd_command(i2c, LCD_CMD_FUNCTION_SET | 0x08); // 2行显示lcd_command(i2c, LCD_CMD_DISPLAY_CONTROL | 0x0F); // 打开显示,有光标,会闪烁lcd_command(i2c, LCD_CMD_CLEAR); // 清屏lcd_command(i2c, LCD_CMD_ENTRY_MODE | 0x02); // 设置光标移动方向
}fn lcd_command(i2c: &mut I2C<I2C0, Blocking>, command: u8) {lcd_write(i2c, command, RS_COMMAND);
}fn lcd_data(i2c: &mut I2C<I2C0, Blocking>, data: u8) {lcd_write(i2c, data, RS_DATA);
}fn lcd_write(i2c: &mut I2C<I2C0, Blocking>, data: u8, mode: u8) {let high_nibble = data & 0xF0;let low_nibble = (data << 4) & 0xF0;lcd_send_nibble(i2c, high_nibble | mode);lcd_send_nibble(i2c, low_nibble | mode);
}fn lcd_send_nibble(i2c: &mut I2C<I2C0, Blocking>, nibble: u8) {// 发送高4位let data = nibble | LCD_BACKLIGHT;let _ = i2c.write(I2C_ADDR, &[data | ENABLE]);let _ = i2c.write(I2C_ADDR, &[data & !ENABLE]);
}fn lcd_write_string(i2c: &mut I2C<I2C0, Blocking>, s: &str) {for c in s.chars() {lcd_data(i2c, c as u8);}
}
  • diagram.json
{"version": 1,"editor": "wokwi","author": "WuFengSheng <469742978@qq.com>","parts": [{"type": "board-esp32-c3-devkitm-1","id": "esp","top": 0.59,"left": 0.67,"attrs": {"flashSize": "16"}},{"type": "wokwi-led","id": "led1","top": -20,"left": -50,"attrs": {"color": "red"}},{"type": "wokwi-resistor","id": "r1","top": 50,"left": -54.5,"rotate": 90,"attrs": {}},{"type": "wokwi-lcd1602","id": "lcd1","top": 46,"left": 132.07,"attrs": {"pins": "i2c"}},{"type": "wokwi-vcc","id": "vcc1","top": 20,"left": 105,"attrs": {}}],"connections": [["esp:TX","$serialMonitor:RX","",[]],["esp:RX","$serialMonitor:TX","",[]],["esp:GND.4","led1:C","black",["h0"]],["led1:A","r1:1","green",["v0"]],["r1:2","esp:0","green",["h0","v38"]],["vcc1:VCC","lcd1:VCC","red",["v0"]],["lcd1:GND","esp:GND.8","black",["h0"]],["lcd1:SDA","esp:6","green",["h0"]],["lcd1:SCL","esp:5","green",["h0"]]],"serialMonitor": {"display": "terminal","convertEol": true}
}

编译项目命令

cd esp-rs-demo
# 默认 debug
cargo build
# 或指定 release
cargo build --release

运行模拟器

注: VSCode 需要安装 wokwi 插件

在这里插入图片描述

ESP32C3 烧录

espflash flash --monitor target/riscv32imc-unknown-none-elf/debug/esp-rs-demo

在这里插入图片描述

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

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

相关文章

TypeScript 算法手册 - 【冒泡排序】

文章目录 TypeScript 算法手册 - 冒泡排序1. 冒泡排序简介1.1 冒泡排序定义1.2 冒泡排序特点 2. 冒泡排序步骤过程拆解2.1 比较相邻元素2.2 交换元素2.3 重复过程 3. 冒泡排序的优化3.1 提前退出3.2 记录最后交换位置案例代码和动态图 4. 冒泡排序的优点5. 冒泡排序的缺点总结 …

Unity3D播放GIF图片使用Animation来制作动画

系列文章目录 unity工具 文章目录 系列文章目录👉前言👉一、下载GIF动图,用PS制作导出帧动画图片👉二、使用Animation制作动画👉三、脚本控制动画播放👉壁纸分享👉总结👉前言 unity播放gif图片,本身是不支持的,但是可以使用其他方法来实现, 1.有一种使用System…

微信小程序hbuilderx+uniapp+Android 新农村综合风貌旅游展示平台

目录 项目介绍支持以下技术栈&#xff1a;具体实现截图HBuilderXuniappmysql数据库与主流编程语言java类核心代码部分展示登录的业务流程的顺序是&#xff1a;数据库设计性能分析操作可行性技术可行性系统安全性数据完整性软件测试详细视频演示源码获取方式 项目介绍 小程序端…

计算机网络:计算机网络概述 —— 网络拓扑结构

文章目录 网络拓扑总线型拓扑特点缺陷 星型拓扑特点缺陷 环型拓扑特点缺陷 网状型拓扑优点缺陷 树型拓扑特点缺陷 网络拓扑 网络拓扑指的是计算机网络中节点&#xff08;计算机、交换机、路由器等&#xff09;之间物理或逻辑连接的结构。网络拓扑定义了节点之间的布局、连接方…

JAVA基础语法 Day11

一、Set集合 Set特点&#xff1a;无序&#xff08;添加数据的顺序和获取出的数据顺序不一致&#xff09;&#xff0c;不重复&#xff0c;无索引 public class demo1 {public static void main(String[] args) {//1.创建一个集合//HashSet特点&#xff1a;无序&#xff0c;不重…

算法笔记(七)——哈希表

文章目录 两数之和判定是否互为字符重排存在重复元素存在重复元素 II字母异位词分组 哈希表&#xff1a;一种存储数据的容器&#xff1b; 可以快速查找某个元素&#xff0c;时间复杂度O(1)&#xff1b; 当频繁查找某一个数时&#xff0c;我们可以使用哈希表 创建一个容器&#…

SpringBoot使用EasyPoi根据模板导出word or pdf

1、导出效果 1.1 wrod 1.2 pdf 2、依赖 <!--word--><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-base</artifactId><version>4.3.0</version></dependency><dependency><groupId>cn.…

ESP32 Bluedroid 篇(1)—— ibeacon 广播

前言 前面我们已经了解了 ESP32 的 BLE 整体架构&#xff0c;现在我们开始实际学习一下Bluedroid 从机篇的广播和扫描。本文将会以 ble_ibeacon demo 为例子进行讲解&#xff0c;需要注意的一点是。ibeacon 分为两个部分&#xff0c;一个是作为广播者&#xff0c;一个是作为观…

C++(string类的实现)

1. 迭代器、返回capacity、返回size、判空、c_str、重载[]和clear的实现 string类的迭代器的功能就类似于一个指针&#xff0c;所以我们可以直接使用一个指针来实现迭代器&#xff0c;但如下图可见迭代器有两个&#xff0c;一个是指向的内容可以被修改&#xff0c;另一个则是指…

Swagger配置且添加小锁(asp.net)(笔记)

此博客是基于 asp.net core web api(.net core3.1)框架进行操作的。 一、安装Swagger包 在 NuGet程序包管理中安装下面的两个包&#xff1a; swagger包&#xff1a;Swashbuckle.AspNetCore swagger包过滤器&#xff1a;Swashbuckle.AspNetCore.Filters 二、swagger注册 在…

php与python建站的区别有哪些

php与Python建站的区别&#xff1a; 1、语言层面Python的特性比php好&#xff0c;更加规范。 2、Python的性能比php高。 3、有只需要启动服务的时候执行一次的代码&#xff0c;在php里每个请求都会被执行一次&#xff0c;Python不需要。虽然php可以通过缓存缩短这方面的差距…

使用CSS实现酷炫加载

使用CSS实现酷炫加载 效果展示 整体页面布局 <div class"container"></div>使用JavaScript添加loading加载动画的元素 document.addEventListener("DOMContentLoaded", () > {let container document.querySelector(".container&q…

在线css像素px到Em的转换器

具体请前往&#xff1a;在线Px转Em工具--将绝对像素(px)长度单位转换为相对长度em

热补丁反调试API Hook—上跳/下跳

以 IsDebuggerPresent 函数为例&#xff0c;可以看到可以上跳&#xff08;简单&#xff09;&#xff0c;也可以下跳&#xff08;复杂&#xff09;。 上跳&#xff1a; BYTE NewCodes[2] { 0xEB,0xF9 }; BYTE JmpCode[5] { 0xE9,0 }; BYTE oldCodes[2] { 0 };BOOL Mydebug() …

63.5 注意力提示_by《李沐:动手学深度学习v2》pytorch版

系列文章目录 文章目录 系列文章目录注意力提示生物学中的注意力提示查询、键和值注意力的可视化使用 show_heatmaps 显示注意力权重代码示例 代码解析结果 小结练习 注意力提示 &#x1f3f7;sec_attention-cues 感谢读者对本书的关注&#xff0c;因为读者的注意力是一种稀缺…

动手学深度学习(李沐)PyTorch 第 7 章 现代卷积神经网络

7.1 深度卷积神经网络&#xff08;AlexNet&#xff09; 在计算机视觉中&#xff0c;直接将神经网络与其他机器学习方法进行比较也许不公平。这是因为&#xff0c;卷积神经网络的输入是由原始像素值或是经过简单预处理&#xff08;例如居中、缩放&#xff09;的像素值组成的。但…

深圳楼市国庆“狂欢”:从“冷清”到“火爆”,谁导演了这场大戏

你知道吗&#xff1f;深圳那楼市&#xff0c;前面冷清得跟个大森林似的&#xff0c;楼里的灯都像是寂寞的眼睛&#xff0c;眨巴眨巴的&#xff0c;没人搭理。比如八月份那会儿&#xff0c;售楼中心冷清得能听见针掉地上的声音&#xff0c;工作人员闲得跟啥似的&#xff0c;大眼…

【VUE】案例:商场会员管理系统

编写vuedfr实现对会员进行基本增删改查 1. drf项目初始化 请求&#xff1a; POST http://127/0.0.0.1:8000/api/auth/ {"username":"cqn", "password":"123"}返回&#xff1a; {"username":"cqn", "token&q…

Ubuntu2404安装

Ubuntu是一款非常优秀的发行版本&#xff0c;起初她的优势主要在于桌面版&#xff0c;但是随着Centos 从服务版的支持的退出&#xff0c;Ubuntu server也在迅猛的成长&#xff0c;并且不断收获了用户&#xff0c;拥有了一大批忠实的粉丝。好了&#xff0c;废话不多说&#xff0…