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

 

目录

目录

前言

芯片介绍

开发平台准备

撰写测试程序


前言

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

 

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

芯片介绍

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

IO口不够了?基于I2C的 IO扩展芯片驱动和开发_第1张图片

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

IO口不够了?基于I2C的 IO扩展芯片驱动和开发_第2张图片

 

开发平台准备

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

IO口不够了?基于I2C的 IO扩展芯片驱动和开发_第3张图片

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

IO口不够了?基于I2C的 IO扩展芯片驱动和开发_第4张图片

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

IO口不够了?基于I2C的 IO扩展芯片驱动和开发_第5张图片

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

#include 
 
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

IO口不够了?基于I2C的 IO扩展芯片驱动和开发_第6张图片

 

撰写测试程序

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

IO口不够了?基于I2C的 IO扩展芯片驱动和开发_第7张图片

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


#include 

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设备后,需要传输要写数据的地址,下面这个表就说明各个指令对应的设置的功能,可以看作是选单

IO口不够了?基于I2C的 IO扩展芯片驱动和开发_第8张图片

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

IO口不够了?基于I2C的 IO扩展芯片驱动和开发_第9张图片

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();  

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

IO口不够了?基于I2C的 IO扩展芯片驱动和开发_第10张图片

 

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

//配置MCP23016 IO扩展板输出的代码
#include 

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也一块给配置了,其实也就是先低位再高位

IO口不够了?基于I2C的 IO扩展芯片驱动和开发_第11张图片

 

你可能感兴趣的:(硬件开发)