ESP32S3 IDF 对 16路输入输出芯片MCP23017做了个简单的测试

news2024/9/21 0:42:35

这次还是使用了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: 输出锁存器寄存器

寄存器说明

  1. 输入/输出方向寄存器 (IODIRA 和 IODIRB)
    地址: IODIRA 的地址是 0x00,IODIRB 的地址是 0x01。
    功能: 这些寄存器用于设置 Port A 和 Port B 上每个 GPIO 引脚的输入/输出方向。
    0: 对应的引脚配置为输出。
    1: 对应的引脚配置为输入。
  2. 输入极性寄存器 (IPOLA 和 IPOLB)
    地址: IPOLA 的地址是 0x02,IPOLB 的地址是 0x03。
    功能: 这些寄存器用于反转 Port A 和 Port B 上每个 GPIO 引脚的输入状态。
    0: 对应的引脚保持原始输入状态。
    1: 对应的引脚输入状态被反转。
  3. GPIO 中断使能寄存器 (GPINTENA 和 GPINTENB)
    地址: GPINTENA 的地址是 0x04,GPINTENB 的地址是 0x05。
    功能: 这些寄存器用于启用 Port A 和 Port B 上每个 GPIO 引脚的中断功能。
    0: 对应的引脚的中断功能禁用。
    1: 对应的引脚的中断功能启用。
  4. 默认值寄存器 (DEFVALA 和 DEFVALB)
    地址: DEFVALA 的地址是 0x06,DEFVALB 的地址是 0x07。
    功能: 这些寄存器用于设置 Port A 和 Port B 上每个 GPIO 引脚的默认比较值。当 GPIO 引脚的输入状态与默认值寄存器中的值不同时,会产生中断。
  5. 中断控制寄存器 (INTCONA 和 INTCONB)
    地址: INTCONA 的地址是 0x08,INTCONB 的地址是 0x09。
    功能: 这些寄存器用于配置 Port A 和 Port B 上每个 GPIO 引脚的中断触发方式(上升沿、下降沿或变化)。
    0: 对应的引脚中断触发方式为变化。
    1: 对应的引脚中断触发方式为上升沿或下降沿。
  6. 配置寄存器 (IOCONA 和 IOCONB)
    地址: IOCONA 的地址是 0x0A,IOCONB 的地址是 0x0B。
    功能: 这些寄存器用于配置全局设置,如中断行为、序列号等。
  7. 上拉电阻寄存器 (GPPUA 和 GPPUB)
    地址: GPPUA 的地址是 0x0C,GPPUB 的地址是 0x0D。
    功能: 这些寄存器用于启用 Port A 和 Port B 上每个 GPIO 引脚的内部上拉电阻。
    0: 对应的引脚的上拉电阻禁用。
    1: 对应的引脚的上拉电阻启用。
  8. 中断标志寄存器 (INTFA 和 INTFB)
    地址: INTFA 的地址是 0x0E,INTFB 的地址是 0x0F。
    功能: 这些寄存器用于指示 Port A 和 Port B 上每个 GPIO 引脚是否产生了中断。当某个引脚产生中断时,相应的位将被设置为 1。
  9. 中断捕获寄存器 (INTCAPA 和 INTCAPB)
    地址: INTCAPA 的地址是 0x10,INTCAPB 的地址是 0x11。
    功能: 这些寄存器用于存储 Port A 和 Port B 上每个 GPIO 引脚在产生中断时的输入状态。
  10. 数据方向寄存器 (GPIOA 和 GPIOB)
    地址: GPIOA 的地址是 0x12,GPIOB 的地址是 0x13。
    功能: 这些寄存器用于读取 Port A 和 Port B 上每个 GPIO 引脚的当前输入状态。
  11. 输出锁存器寄存器 (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的输出值为0xFF
    set_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为0xAF
    set_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);
    }
    

}

希望对你有帮助。

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

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

相关文章

B端界面升级就是升级颜值,错了,这样想就片面啦。

在B端应用的发展中&#xff0c;界面升级是非常重要的一环。然而&#xff0c;界面级不仅仅是为了提升外观颜值&#xff0c;还需要关注用户体验、功能增强和效率提升等方面。 虽然美观的界面可以吸引用户的眼球&#xff0c;但如果功能不完善&#xff0c;用户可能会选择其他产品。…

LVS负载均衡(twenty-six day)

一、LVS &#xff08;一&#xff09;什么是LVS linux virtural server的简称&#xff0c;也就是linxu虚拟机服务器&#xff0c;这是一个由章文岩博士发起的开源项目&#xff0c;官网是http://www.linuxvirtualserver.org,现在lvs已经是linux内核标准的-部分&#xff0c;使用lv…

vue 实现上浮气泡效果

一、 效果 二、代码 1.用 li 来做每个气泡 <div class"dataSea_middle_bottom"><ul><liv-for"(item,index) in keyBusiness":key"index"class"pops animal"><p class"fb">{{ item.name}}</p>…

Java面试题(一)----Java基础

基础 Java中和equals有什么区别&#xff1f; 一个是运算符&#xff0c;一个是方法。 如果比较的对象是基本数据类型&#xff0c;则比较数值是否相等&#xff1b;如果比较的是引用数据类型&#xff0c;则比较的是对象的内存地址是否相等。 因为Java只有值传递&#xff0c;对于…

SQL Zoo 9-.Window functions

以下数据均来自SQL Zoo 1.Show the lastName, party and votes for the constituency S14000024 in 2017.&#xff08;显示2017年选区“S14000024”的姓氏、政党和选票&#xff09; SELECT lastName, party, votesFROM geWHERE constituency S14000024 AND yr 2017 ORDER BY…

开启IDEA打开新项目时窗口提示

1.背景 实际开发中很多时候,我们会同时打开多个项目,或者项目切换, 这时候有2中情况,打开新窗口或者在当前窗口打开(即:关闭当前窗口,打开新窗口) 具体是那种情况,要根据实际场景,因此我们希望可以弹框提示: 是打开新窗口,还是在当前窗口打开 具体设置如下: 2.步骤 3.测试…

中国科技统计年鉴,数据覆盖1991-2022年多年份

基本信息. 数据名称: 中国科技统计年鉴 数据格式: excel 数据时间: 1991-2022年 数据几何类型: xlsx 数据坐标系: WGS84 数据来源&#xff1a;国家统计局 数据预览&#xff1a; 数据可视化.

zabbix“专家坐诊”第251期问答

问题一 Q&#xff1a;zabbix模板自带的监控项很多都不需要&#xff0c;也不用删除&#xff0c;就是怎么让他们都不展示出来 A&#xff1a;禁用掉 Q&#xff1a;还是在的&#xff0c;我想要就看不见&#xff0c;不是不启用&#xff0c;想要效果跟删除一样&#xff0c;看不见&am…

我在高职教STM32——I2C通信之SHT20传感器(1)

大家好,我是老耿,高职青椒一枚,一直从事单片机、嵌入式、物联网等课程的教学。对于高职的学生层次,同行应该都懂的,老师在课堂上教学几乎是没什么成就感的。正是如此,才有了借助CSDN平台寻求认同感和成就感的想法。在这里,我准备陆续把自己花了很多心思设计的教学课件分…

go-zero中基本配置及获取参数

一、使用配置文件启动项目 1、在项目的etc文件夹下分别创建开发环境和测试环境的配置文件,这里简单点使用不同的端口 2、配置Makefile文件启动命令来启动不同配置文件 runDev:go run users.go -f etc/application-dev.yml runProd:go run users.go -f etc/application-prod.ym…

RC电路(三):零点和极点

一、零极点定义 零点和极点是在自动控制原理中用于描述系统特性的概念。‌ 零点&#xff08;Zero&#xff09;&#xff1a;‌在传递函数的分子多项式等于零的解。即当系统的输入信号等于零时&#xff0c;‌输出信号不为零的情况下&#xff0c;‌输入信号与输出信号相等的点。‌…

人工智能系统测试生命周期详解之测试数据准备

前面的文章里我们已经整体介绍过了人工智能测试的生命周期&#xff0c;它需要经历测试需求的分析、测试环境的准备、数据的准备与验证、测试的执行预分析以及上线后的监控这样一个过程。前面的文章已经为大家介绍了人工智能系统测试生命周期的“需求分析”环节和“测试环境准备…

SPSS-主成分分析实践

相信各位小伙伴都知道主成分分析的原理&#xff0c;我们今天用SPSS来实现一下主成分分析 主成分分析步骤 对原来的全部指标进行标准化&#xff0c;以消除变量在水平和量纲的影响根据标准化的数据矩阵求出相关系数矩阵求出协方差矩阵的特征根和特征向量确定主成分&#xff0c;…

DRM(Direct Rendering Manager)直接渲染管理

DRM是Linux 内核的一个子系统&#xff0c;负责与现代显卡的GPU进行交互。DRM 公开了一个API (libdrm)&#xff0c;用户空间程序可以使用该API 向 GPU 发送命令和数据并执行诸如配置显示器模式设置之类的操作。DRM 最初是作为X 服务器直接渲染基础架构的内核空间组件开发的&…

大规模复杂场景三维重建与理解——学习笔记

一、完整的大规模复杂场景三维重建与理解系统 一个完整的大规模复杂场景三维重建与理解系统包含“自主式场景数据获取->高精度联合位姿解算->完整化三维几何重建->细粒度三维语义分割->结构化三维矢量表达->全天候长时定位定姿->高时效地图增量更新”等模块。…

2022年第一至第四批专精特新“小巨人”企业数据,企业名称、经营范围、公示批次等字段可查询

基本信息. 数据名称: 第一至第四批专精特新“小巨人”企业数据 数据格式: Shpxlsx 数据时间: 2022年 数据几何类型: 点 数据坐标系: WGS84坐标系 数据来源&#xff1a;《中国城市统计年鉴》中统计的工业企业数相关数据&#xff0c;对象为地级及以上的城市&#xff0c;统计…

【书生大模型实战营第三期 | 进阶岛第2关-Lagent 自定义你的 Agent 智能体】

学习心得&#xff1a;Lagent 自定义你的 Agent 智能体 摘要 Lagent 是一个为大语言模型设计的轻量级开源智能体框架&#xff0c;它不仅支持多种智能体范式&#xff0c;如 AutoGPT、ReAct&#xff0c;还集成了多种工具&#xff0c;包括但不限于 Arxiv 搜索、Google 搜索等。通…

电子行业数字工厂管理系统解决方案

电子行业数字工厂管理系统解决方案是针对电子企业特定需求而设计的一套综合管理系统&#xff0c;旨在通过数字化手段提升生产效率、优化资源配置、降低运营成本&#xff0c;并确保高品质产品的输出。以下是一个详细的电子行业数字工厂管理系统解决方案的概述&#xff1a; 一、系…

C语言:字符函数,字符串函数

在编程的过程中&#xff0c;我们经常要处理字符和字符串&#xff0c;为了方便操作字符和字符串&#xff0c;C语言标准库中提供了一系列库函数。 一. 字符分类函数 C语言中有一系列的函数是专门做字符分类的&#xff0c;也就是一个字符是属于什么类型的字符的。 这些函数的使用…

你知道AI模型是如何学习的吗?

在人工智能的广阔天地中&#xff0c;AI模型的学习方式不仅决定了其智能行为的深度和广度&#xff0c;更是推动技术进步和应用创新的关键动力。随着AI技术的飞速发展&#xff0c;我们越来越意识到&#xff0c;深入了解AI的学习机制对于把握其潜能至关重要。 我们将从基础概念出…