IO口不够了?基于I2C的 IO扩展芯片驱动和开发

 

目录

目录

前言

芯片介绍

开发平台准备

撰写测试程序


前言

有时候会遇到接口不够用的情况,那这个情况的话,我们就可以考虑一下使用芯片来扩展。MCP23016这一款芯片国内用的好像不多,也许是成本,也许是现在MCU引脚多数时候都够用,直接选个适合项目的MCU就可以,所以我基本没有找到什么开源资料。

 

所以今天就来讲一讲这一个芯片的使用

芯片介绍

 这一个芯片的作用很明确了,16位IO扩展,还带有中断,3个硬件地址引脚,能自由切换,也就是你最多可以使用3块这个芯片在一条I2C总线上。

这一款其实是我在公司仓库捡到的,捡了五六片,看了一下Datasheet好像还不错,所以就拿来开发一下。目前来看对于电源的支持也不错,2.0-5.5V,基本涵盖常用的几家的MCU

 

开发平台准备

为了使用这个芯片,我画了一张原理图,这个原理图验证后可知是正确的,如果你是简单用一用,可以放心的参考

当然随之的还有一个PCB,我也通过线上方式制作了出来

连接后长这样,我顺便试了一下我设计的另一个电源模块

开发环境是Arduino,我这人比较懒一点所以有库当然是用库了,为了直接先获取到现在的I2C地址,我使用这一段代码来遍历并得出MCP23016的I2C地址

#include <Wire.h>
 
void setup(){
  Wire.begin();
  Serial.begin(9600);
  Serial.println("\nI2C Scanner");
}
void loop(){
  byte error, address;
  int nDevices;
  Serial.println("Scanning...");
  nDevices = 0;
  for (address = 1; address < 127; address++ ){
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
    if (error == 0){
      Serial.print("I2C device found at address 0x");
      if (address < 16)
        Serial.print("0");
      Serial.print(address, HEX);
      Serial.println(" !");
      nDevices++;
    }else if (error == 4){
      Serial.print("Unknow error at address 0x");
      if (address < 16)
        Serial.print("0");
      Serial.println(address, HEX);
    }
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
  delay(5000); // wait 5 seconds for next scan
}

我正常的把IO扩展板连接到A4(SDA)和A5(SCL),烧录这段程序,打开串口以及PC端的界面,得到当前的地址是0x27

 

撰写测试程序

这个芯片是通过I2C,不管懂不懂先回顾一下I2C通讯用到的信号含义,我直接找一张贴这里

Arduino的I2C用起来很方便,可以先写一个I2C模版,这模版基本讲明一个写数据的过程


#include <Wire.h>

void setup() {
  Wire.begin(); // join i2c bus (address optional for master)
}

byte cmd = 0;
byte set = 0;

void loop() {
  Wire.beginTransmission(0x27); // transmit to device 
  Wire.write(cmd );        // sends byte
  Wire.write(set );              // sends byte
  Wire.endTransmission();    // stop transmitting


  delay(500);
}

然后,回过头来看数据表,我们刚才已经得知目前设置的地址是0x27了,在呼叫I2C设备后,需要传输要写数据的地址,下面这个表就说明各个指令对应的设置的功能,可以看作是选单

而下面这一张表则注明功能设置,如果要测试,我们最先需要做的事情就是设定GP0和GP1这两个寄存器,Value on POR是说刚上电时候的默认配置。

GP:通用接口

OLAT:输出锁存器

IPOL:输入极性

IODIR:输入输出设置

INTCAP:中断设置

IOCON:设置IOCON0就会设置IOCON1

依据上面这个表,可以了解到,我们应该要先对IO口进行设置,也就是使用这一段代码

  Wire.begin(); // join i2c bus (address optional for master)
  Wire.beginTransmission(0x27);  //设备的地址,门牌号
  Wire.write(0x06);  // 和I2C设备说明,我们要设置IO口
  Wire.write(0x00);  // 设置为0x00,也就是P0.0-P0.7全部输出
  Wire.write(0xFF);  // 设置为0xFF,也就是P1.0-P1.7全部输入
  Wire.endTransmission(); 

然后,再设置输出端口的寄存器,我设置了一个0x03,也就是0000 0011,如果设置好那么P0.0和P0.1会有电平

   Wire.beginTransmission(0x27); 
  Wire.write(0x00);        
  Wire.write(0x03); 
  Wire.endTransmission();  

 设置完成后是这样,可以正常的使用

 

这个代码的完整版本我放这里

//配置MCP23016 IO扩展板输出的代码
#include <Wire.h>

void setup() {
  Wire.begin(); // join i2c bus (address optional for master)
  Wire.beginTransmission(0x27);  // setup out direction registers
  Wire.write(0x06);  // 
  Wire.write(0x00);  // 
  Wire.write(0xFF);  //
  Wire.endTransmission();
}

byte cmd = 0x01;
byte set = 0x07;
byte set2 = 0x01;

void loop() {


   Wire.beginTransmission(0x27); 
  Wire.write(0x00);        
  Wire.write(0x03); 
  Wire.endTransmission();  


  delay(500);
}

有一点是,这一基于I2C通讯的芯片可以连续进行配置,比如我设置0x00,那如果传送两个字节,就可以把0x01也一块给配置了,其实也就是先低位再高位

 

首先,需要了解CMT2310A芯片的功能,以及STC8H1K28单片机的IO相关寄存器的使用方法。 CMT2310A芯片主要用于驱动蓝牙音频设备,它包含一个32位RISC处理器完整的蓝牙协议栈。STC8H1K28单片机是一款高性能、低功耗的8位单片机,具有自带ISP(In-System Programming)功能多个IO,可以用于控制各种外围设备。 接下来,我们可以按照以下步骤来实现STC8H1K28单片机驱动CMT2310A芯片: 1. 通过STC8H1K28单片机的IO连接CMT2310A芯片,包括UART、模拟音频输入输出、I2C等。其中,UART用于与CMT2310A芯片进行数据交换,模拟音频接用于控制音频输入输出,I2C用于配置CMT2310A芯片的相关参数。 2. 在STC8H1K28单片机上编写软件程序,通过读写相关寄存器的方式,实现控制CMT2310A芯片的功能。包括初始化、配置、音频数据输入输出等。 3. 调试优化程序,确保STC8H1K28单片机与CMT2310A芯片的通信稳定可靠,音频输入输出正常。 4. 可以根据具体的应用需求,增加其他功能,如蓝牙配对、码率控制等。 需要注意的是,在使用STC8H1K28单片机驱动CMT2310A芯片时,需要对CMT2310A芯片进行一定的了解,包括其内部处理器结构、数据传输协议等,才能根据需要进行合理的数据读写操作。同时,还需要注意软件编程的可读性、可维护性扩展性,以便后期的调试维护工作。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值