ESP32S3 IDF 对 16路输入输出芯片MCP23017做了个简单的测试
这次还是使用了idf老版本4.4.7,上次用了5.3,感觉不好用,官方的MCP23017芯片是英文版,真的很难读明白,可能是我英语水平不够吧。先看看每个寄存器的功能:

IODIRA 和 IODIRB: 输入/输出方向寄存器
IPOLA 和 IPOLB: 输入极性寄存器
GPINTENA 和 GPINTENB: GPIO 中断使能寄存器
DEFVALA 和 DEFVALB: 默认值寄存器
INTCONA 和 INTCONB: 中断控制寄存器
IOCONA 和 IOCONB: 配置寄存器
GPPUA 和 GPPUB: 上拉电阻寄存器
INTFA 和 INTFB: 中断标志寄存器
INTCAPA 和 INTCAPB: 中断捕获寄存器
GPIOA 和 GPIOB: 数据方向寄存器
OLATA 和 OLATB: 输出锁存器寄存器
寄存器说明
- 输入/输出方向寄存器 (IODIRA 和 IODIRB)
地址: IODIRA 的地址是 0x00,IODIRB 的地址是 0x01。
功能: 这些寄存器用于设置 Port A 和 Port B 上每个 GPIO 引脚的输入/输出方向。
0: 对应的引脚配置为输出。
1: 对应的引脚配置为输入。 - 输入极性寄存器 (IPOLA 和 IPOLB)
地址: IPOLA 的地址是 0x02,IPOLB 的地址是 0x03。
功能: 这些寄存器用于反转 Port A 和 Port B 上每个 GPIO 引脚的输入状态。
0: 对应的引脚保持原始输入状态。
1: 对应的引脚输入状态被反转。 - GPIO 中断使能寄存器 (GPINTENA 和 GPINTENB)
地址: GPINTENA 的地址是 0x04,GPINTENB 的地址是 0x05。
功能: 这些寄存器用于启用 Port A 和 Port B 上每个 GPIO 引脚的中断功能。
0: 对应的引脚的中断功能禁用。
1: 对应的引脚的中断功能启用。 - 默认值寄存器 (DEFVALA 和 DEFVALB)
地址: DEFVALA 的地址是 0x06,DEFVALB 的地址是 0x07。
功能: 这些寄存器用于设置 Port A 和 Port B 上每个 GPIO 引脚的默认比较值。当 GPIO 引脚的输入状态与默认值寄存器中的值不同时,会产生中断。 - 中断控制寄存器 (INTCONA 和 INTCONB)
地址: INTCONA 的地址是 0x08,INTCONB 的地址是 0x09。
功能: 这些寄存器用于配置 Port A 和 Port B 上每个 GPIO 引脚的中断触发方式(上升沿、下降沿或变化)。
0: 对应的引脚中断触发方式为变化。
1: 对应的引脚中断触发方式为上升沿或下降沿。 - 配置寄存器 (IOCONA 和 IOCONB)
地址: IOCONA 的地址是 0x0A,IOCONB 的地址是 0x0B。
功能: 这些寄存器用于配置全局设置,如中断行为、序列号等。 - 上拉电阻寄存器 (GPPUA 和 GPPUB)
地址: GPPUA 的地址是 0x0C,GPPUB 的地址是 0x0D。
功能: 这些寄存器用于启用 Port A 和 Port B 上每个 GPIO 引脚的内部上拉电阻。
0: 对应的引脚的上拉电阻禁用。
1: 对应的引脚的上拉电阻启用。 - 中断标志寄存器 (INTFA 和 INTFB)
地址: INTFA 的地址是 0x0E,INTFB 的地址是 0x0F。
功能: 这些寄存器用于指示 Port A 和 Port B 上每个 GPIO 引脚是否产生了中断。当某个引脚产生中断时,相应的位将被设置为 1。 - 中断捕获寄存器 (INTCAPA 和 INTCAPB)
地址: INTCAPA 的地址是 0x10,INTCAPB 的地址是 0x11。
功能: 这些寄存器用于存储 Port A 和 Port B 上每个 GPIO 引脚在产生中断时的输入状态。 - 数据方向寄存器 (GPIOA 和 GPIOB)
地址: GPIOA 的地址是 0x12,GPIOB 的地址是 0x13。
功能: 这些寄存器用于读取 Port A 和 Port B 上每个 GPIO 引脚的当前输入状态。 - 输出锁存器寄存器 (OLATA 和 OLATB)
地址: OLATA 的地址是 0x14,OLATB 的地址是 0x15。
功能: 这些寄存器用于设置 Port A 和 Port B 上每个 GPIO 引脚的输出状态。
代码,已经测试读写寄存器没有问题,输入可以检测(没用中断),也可以正常输出:
#include <driver/i2c.h>
#include <esp_log.h>#define I2C_MASTER_SCL_IO 15 /*!< gpio number for I2C master clock */
#define I2C_MASTER_SDA_IO 16 /*!< gpio number for I2C master data */
#define I2C_MASTER_NUM I2C_NUM_0 /*!< I2C port number for master dev */
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master do not need buffer */
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master do not need buffer */
#define I2C_MASTER_FREQ_HZ 400000 /*!< I2C master clock frequency */#define MCP23017_ADDRESS 0x20 /*!< I2C address of MCP23017 */static const char *TAG = "I2C_MASTER";void i2c_master_init() {i2c_config_t conf = {.mode = I2C_MODE_MASTER,.sda_io_num = I2C_MASTER_SDA_IO,.sda_pullup_en = GPIO_PULLUP_ENABLE,.scl_io_num = I2C_MASTER_SCL_IO,.scl_pullup_en = GPIO_PULLUP_ENABLE,.master.clk_speed = I2C_MASTER_FREQ_HZ,};i2c_param_config(I2C_MASTER_NUM, &conf);i2c_driver_install(I2C_MASTER_NUM, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
}void read_register(uint8_t reg, uint8_t *value)
{uint8_t data[1] = {reg};i2c_cmd_handle_t cmd = i2c_cmd_link_create();// 写入寄存器地址i2c_master_start(cmd);i2c_master_write_byte(cmd, (MCP23017_ADDRESS << 1) | I2C_MASTER_WRITE, true);i2c_master_write(cmd, data, 1, true);// 读取数据i2c_master_start(cmd);i2c_master_write_byte(cmd, (MCP23017_ADDRESS << 1) | I2C_MASTER_READ, true);i2c_master_read(cmd, value, 1, I2C_MASTER_LAST_NACK);i2c_master_stop(cmd);i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_PERIOD_MS);i2c_cmd_link_delete(cmd);
}void write_register(uint8_t reg, uint8_t value) {uint8_t data[2] = {reg, value};i2c_cmd_handle_t cmd = i2c_cmd_link_create();i2c_master_start(cmd);i2c_master_write_byte(cmd, (MCP23017_ADDRESS << 1) | I2C_MASTER_WRITE, true);i2c_master_write(cmd, data, sizeof(data), true);i2c_master_stop(cmd);i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_PERIOD_MS);i2c_cmd_link_delete(cmd);
}void set_output_direction(uint8_t port, uint8_t direction) {// 设置输出方向// 方向:0为输出,1为输入write_register(port == 0 ? 0x00 : 0x01, direction);
}void set_output_value(uint8_t port, uint8_t value) {// 设置输出值// value: 输出值//write_register(port == 0 ? 0x12 : 0x13, value);write_register(port == 0 ? 0x14 : 0x15, value);
}void example() {i2c_master_init();// 设置PORTA为全输出set_output_direction(0, 0x00);// 设置PORTA的输出值为0xFFset_output_value(0, 0x0f);
}void app_main() {i2c_master_init();// 设置PORT A B为全输出set_output_direction(0, 0x00);set_output_direction(1, 0x00);// 设置PORTA的输出值为0xf5 B为0xAFset_output_value(0, 0xf5);set_output_value(1, 0xAf);// 设置PORT A B为输入set_output_direction(0, 0xff);set_output_direction(1, 0xff);uint8_t data1[1] = {0};uint8_t data2[1] = {0};while (true){read_register(0x12, data1);read_register(0x13, data2);ESP_LOGI(TAG, "read register 0x12: %02X 0x13: %02X", data1[0], data2[0]);vTaskDelay(1000 / portTICK_PERIOD_MS);}}
希望对你有帮助。
相关文章:
ESP32S3 IDF 对 16路输入输出芯片MCP23017做了个简单的测试
这次还是使用了idf老版本4.4.7,上次用了5.3,感觉不好用,官方的MCP23017芯片是英文版,真的很难读明白,可能是我英语水平不够吧。先看看每个寄存器的功能: IODIRA 和 IODIRB: 输入/输出方向寄存器 IPOLA 和 I…...
【技术前沿】Flux.1部署教程入门--Stable Diffusion团队最前沿、免费的开源AI图像生成器
项目简介 FLUX.1 是一种新的开源图像生成模型。它由 Stable Diffusion 背后的团队 Black Forest Labs 开发。 官网中有以下功能开源供大家参考: FLUX.1 擅长在图像中准确再现文字,因此非常适合需要清晰文字或短语的设计。无论是标牌、书籍封面还是品牌…...
Redis 的 STREAM 和 RocketMQ 是两种不同的消息队列和流处理解决方案,它们在设计理念、功能和用途上有显著区别。以下是它们的主要区别:
20240813 Redis 的 STREAM 和 RocketMQ 是两种不同的消息队列和流处理解决方案,它们在设计理念、功能和用途上有显著区别。以下是它们的主要区别:1. 使用 Redis 的 Sorted Set 数据结构连接到 Redis示例用法添加事件获取滑动窗口内的事件移除过期事件连接…...
Visual Studio Code安装与C/C++语言运行(上)
Visual Studio Code(VS Code)作为微软开发的一款轻量级但功能强大的源代码编辑器,广泛应用于各种编程语言的开发,包括C/C。以下将详细介绍VS Code的安装过程以及与C/C语言运行环境的配置。 一、Visual Studio Code的安装 1. 准备…...
探索数据可视化,数据看板在各行业中的应用
数据可视化是一种通过图形化手段将数据呈现出来的技术,它将复杂的数据和信息转化为易于理解的图表、地图、仪表盘等视觉元素,使得数据的模式、趋势和关系更加直观地展现出来。通过数据可视化,用户可以快速识别重要信息、发现潜在问题…...
haralyzer 半自动,一次性少量数据采集快捷方法
使用场景:半自动,一次性少量数据采集需求在工作中还是不少遇到的,无论使用模拟的方式,或者破解都不太划算。其实这种需求,使用半自动爬虫是最简单的。不需要考虑网站反爬虫的问题,因为你使用的就是真实的浏…...
mall-admin-web-master前端项目下载依赖失败解决
碰壁后的总结 pythone 环境 2.XX版本,切记不要3.0以上的。node 16.x不能太高 错误案例 npm ERR! code 1 npm ERR! path D:\workspace\springBootMall\mall-admin-web-master\node_modules\node-sass npm ERR! command failed npm ERR! command C:\windows\system…...
【07】JVM是怎么实现invokedynamic的
在Java中,方法调用会被编译为invokeStatic,invokeSpecial,invokVirtual以及invokeInterface四种指令。这些指令与包含目标方法类名、方法名以及方法描述符的符号引用捆绑,在实际运行之前,JVM根据这个符号引用链接到具体…...
使用API有效率地管理Dynadot域名,查看参与的拍卖列表
前言 Dynadot是通过ICANN认证的域名注册商,自2002年成立以来,服务于全球108个国家和地区的客户,为数以万计的客户提供简洁,优惠,安全的域名注册以及管理服务。 Dynadot平台操作教程索引(包括域名邮箱&…...
Linux 基本指令讲解
linux 基本指令 clear 清屏 Alt Enter 全屏/退出全屏 pwd 显示当前用户所处路径 cd 改变目录 cd /root/mikecd … 返回上级目录cd - 返回最近所处的路径cd ~ 直接返回当前用户自己的家目 roor 中:/root普通用户中:/home/mike mkdir 创建一个文件夹(d) …...
PRE_EMPHASIS
PRE_EMPASIS属性用于提高高频信号的信号完整性 其通过传输线遭受高频损耗。发射机 预加重(pre_EMPASIS)功能允许对某些信号驱动器进行预加重 I/O标准。 提示:发射机的预加重可以与接收机的均衡相结合,以提高 整体信号完整性。 理想…...
【QT常用技术讲解】多线程处理+全局变量处理异步事件并获取多个线程返回的结果
前言 QTableView加入勾选项后(参考【QT常用技术讲解】QTableView添加QCheckBox、QPushButton),如果支持右键菜单功能,此时就有统一执行多个异步事件,并且统一输出到界面的需求了,本篇结合多线程共享全局变量…...
数组列表中的最大距离
给定 m 个数组,每个数组都已经按照升序排好序了。现在你需要从两个不同的数组中选择两个整数(每个数组选一个)并且计算它们的距离。两个整数 a 和 b 之间的距离定义为它们差的绝对值 |a-b| 。你的任务就是去找到最大距离 示例 1:…...
C语言新手小白详细教程(7)指针和指针变量
希望文章能够给到初学的你一些启发~ 如果觉得文章对你有帮助的话,点赞 关注 收藏支持一下笔者吧~ 阅读指南: 开篇说明1、指针的定义接下来我们用图示的形式来解释一下 指针:2、申明指针变量3、取地址符 &4、为指针…...
Kafka保证消息不丢失
Kafka保证消息不丢失 生产者发送消息到Broker丢失 设置异步发送 回调方法中的参数Exception e如果为空 代表发送成功,如果不为空代表发送失败出现异常 消息在Broker中丢失 kafka集群中存在分区机制 分区中分为leader和follower副本 leader负责读写,而follower只负责数据…...
数据结构+基数排序算法
一、问题描述 实现英文单词按字典序排列的基数排序算法 编写一个程序,采用基数排序方法将一组英文单词按字典顺序排 列。假设单词均由小写字母或空格构成,最长的单词有 MaxLen 个 字母,用相关数据进行测试并输出各趟的排序结果。 用例&#…...
C++ list【常用接口、模拟实现等】
1. list的介绍及使用 1.1 list的介绍 1.list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。 2.list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前…...
12.面试题——Spring Boot
1.Spring Boot是什么? Spring Boot 是 Spring 开源组织下的子项目,是 Spring 组件一站式解决方案,主要是简化了使用 Spring 的难度,简省了繁重的配置,提供了各种启动器,开发者能快速上手。 2.为什么要用 …...
【前端VUE】npm i 出现版本错误等报错 简单直接解决命令
前端vue npm i 安装时出现 报错原因 在新版本的npm中,默认情况下,npm install遇到冲突的peerDependencies时将失败。 解决办法 使用--force或--legacy-peer-deps可解决这种情况。 --force 会无视冲突,并强制获取远端npm库资源࿰…...
精彩回顾 | 风丘科技亮相2024名古屋汽车工程博览会
2024年7月17日-19日,风丘科技联合德国IPETRONIK亮相日本名古屋汽车工程博览会。该展会面向汽车行业不同应用场景,包括新的eAxle、FCEV、ADAS、测试测量系统和ECU测试等相关技术,是一个专为活跃在汽车行业前线的工程师和研究人员举办的汽车技术…...
ElevenLabs语音合成效果翻倍的秘密(行业未公开的声学参数调优矩阵)
更多请点击: https://intelliparadigm.com 第一章:ElevenLabs英文语音合成效果翻倍的核心洞察 关键瓶颈在于语音上下文建模粒度 ElevenLabs 的高质量语音合成并非单纯依赖更大模型参数量,而是通过细粒度的语义-韵律联合编码实现自然度跃升。…...
5分钟快速掌握Windows右键菜单终极管理神器ContextMenuManager
5分钟快速掌握Windows右键菜单终极管理神器ContextMenuManager 【免费下载链接】ContextMenuManager 🖱️ 纯粹的Windows右键菜单管理程序 项目地址: https://gitcode.com/gh_mirrors/co/ContextMenuManager 你是不是经常在右键文件时,面对几十个…...
别再只盯着wx.login了!SpringBoot后端实战:用getPhoneNumber接口搞定小程序用户手机号绑定
微信小程序用户手机号绑定:SpringBoot后端深度实践指南 在当今移动互联网生态中,微信小程序已成为连接用户与服务的重要桥梁。对于需要强实名认证或直接触达用户的业务场景(如电商交易、金融服务、政务办理等),仅依赖w…...
Steam Achievement Manager完整指南:快速解决游戏成就难题的终极工具
Steam Achievement Manager完整指南:快速解决游戏成就难题的终极工具 【免费下载链接】SteamAchievementManager A manager for game achievements in Steam. 项目地址: https://gitcode.com/gh_mirrors/st/SteamAchievementManager 核心关键词:S…...
AI原生产品管理:多智能体协作如何重塑产品开发工作流
1. 项目概述:当AI成为你的产品经理最近在GitHub上看到一个挺有意思的项目,叫NathanJCW/ai-native-pm-cortex。光看名字,你大概能猜到它想做什么——“AI原生的产品经理大脑”。这可不是一个简单的聊天机器人插件,它试图构建一个完…...
Apache Burr框架:构建可观测有状态数据应用的核心原理与实践
1. 项目概述:一个用于构建和评估数据产品的Python框架如果你正在处理数据密集型应用,比如推荐系统、个性化广告或者任何需要根据用户行为实时调整策略的场景,你肯定遇到过这样的困境:模型训练和离线评估做得再好,一旦上…...
如何永久保存你的微信聊天记录?WeChatExporter开源工具完整指南
如何永久保存你的微信聊天记录?WeChatExporter开源工具完整指南 【免费下载链接】WeChatExporter 一个可以快速导出、查看你的微信聊天记录的工具 项目地址: https://gitcode.com/gh_mirrors/wec/WeChatExporter 你是否曾经历过手机丢失、微信重装后珍贵聊天…...
基于xclaude-plugin框架的Claude自定义插件开发实战指南
1. 项目概述:Claude插件生态的“瑞士军刀”如果你最近在深度使用Claude,尤其是Claude Desktop应用,那你大概率已经感受到了插件生态的潜力与混乱。官方插件商店虽然方便,但总有些特定需求找不到现成的解决方案,或者找到…...
小米汽车Q3真车现身:科技巨头跨界造车的技术路径与市场挑战
1. 项目概述:从“Q3真车现身”看小米汽车的阶段性成果最近,小米汽车项目代号“Q3”的测试车辆在公开道路上被频繁捕获,这已经不是简单的谍照,而是接近量产状态的“真车”现身。作为一名长期关注汽车产业变革,特别是科技…...
动态目标跨镜无缝接力追踪技术白皮书
一、前言在全域视觉监控、智能安防、智慧园区、交通管控、工业巡检等核心场景中,动态目标(人员、车辆、设备等)的跨摄像头连续追踪是实现智能化管理的核心需求。当前行业常规追踪方案普遍存在轨迹断点、坐标漂移、身份错乱等痛点,…...
