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测试等相关技术,是一个专为活跃在汽车行业前线的工程师和研究人员举办的汽车技术…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
群晖NAS如何在虚拟机创建飞牛NAS
套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...
