OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4489|回复: 6

io扩展模块分享 MCP23017参考资料

[复制链接]

75

主题

458

帖子

4

精华

金牌会员

Rank: 6Rank: 6

积分
1635
金钱
1635
注册时间
2012-8-28
在线时间
71 小时
发表于 2020-8-29 13:31:37 | 显示全部楼层 |阅读模式
IMG_20200829_132416.jpg
IOCON寄存器默认全0
D7:(BANK位)0:寄存器连续 1:寄存器分组
D6:INT中断脚0 :INTA 与 PortA 关联, INTB 与 PortB 关联 ,1:并联输出。
D5:0顺序读取,地址指针自增,1单寄存器地址操作
D4:0使能SDA变化率控制
D3:硬件地址1外部设置,0强制地址为0;mcp23017不使用
D2:INT中断脚0:推挽,1开漏
D1:INT中断脚极性0低电平有效,1高电平有效。
D0:NC

IODIR       io方向 0:输出,1输入
IPOL           输入极性取反 0:正逻辑,1反逻辑
GPINTEN    电平变化中断使能0关,1开
DEFVAL        电平变化参考值
INTCON    中断控制脚0:与之前电平比较,1与参考值比较
GPPU        上拉电阻0:关,1:上拉
INTF            中断标志
INTCAP       中断时端口值(只读)
GPIO            端口输入输出值
OLAT            输出锁存 0低电平,1高电平
PORT

IOCON.BANK=1为独立映射地址。  PORTA 关联的寄存器从地址 00h - 0Ah
                                                           PORTB 关联的寄存器从 10h - 1Ah 映射
IOCON.SEQOP=1,默认:字节读取

起始    +    0100    +    A2A1A0    +    R/W     ACK   

R/W        0:写入,1:读出
GPION    读取端口上的值
OLATn    读取锁存器值(非实际值)

初始化:数据传送期间生成停止或重新启动条件 。
起始:SCL时钟高电平,SDA数据下降沿。
停止:SCL时钟高电平,SDA数据上升沿。

POR        上电复位
PORT    AB不区分
///////////////////////////////////////////////////////////////////////////////////////////////
16 位远程双向 I/O 端口
- I/O 引脚默认为输入引脚
• 高速 I2C™ 接口 (MCP23017)
- 100 kHz
- 400 kHz
- 1.7 MHz
• 高速 SPI 接口 (MCP23S17)
- 10 MHz (最高)
• 三个硬件地址引脚,最多可允许总线上连接 8 个器

• 可配置的中断输出引脚
- 可配置为高电平有效 (输出)、低电平有效
(输出)或开漏 (输出)
• INTA 和 INTB 可配置为独立或联合工作
• 可配置的中断源
- 根据已配置寄存器默认值或引脚电平变化而发
生电平变化中断
• 用于配置输入端口数据极性的 “极性反转”寄存

• 外部复位输入
• 待机电流低: 1 μA (最大值)
• 工作电压:
- 1.8V 至 5.5V ( -40°C 至 +85°C)
- 2.7V 至 5.5V ( -40°C 至 +85°C)
- 4.5V 至 5.5V ( -40°C 至 +125°C)
封装
• 28 引脚 PDIP ( 300 mil)
• 28 引脚 SOIC ( 300 mil)
• 28 引脚 SSOP
• 28 引脚 QFN
//////////////////////////////////////////////////////
&#8226; 1         GPB0        双向 I/O 引脚。    <20ma
2           GPB1
3           GPB2
4           GPB3
5           GPB4
6           GPB5
7           GPB6
8           GPB7
9       Vdd    电源 1.8~5.5v     <125ma
10     Vss    GND接地            <150ma
11     NC空
12       SCL时钟
13       SDA数据
14    NC空

28           GPA7
27           GPA6
26           GPA5
25           GPA4
24           GPA3
23           GPA2
22           GPA1
21           GPA0
20        INTA         PORTA 的中断输出。可被配置为高电平有效、低电平有效或开漏输出。
19        INTB         PORTB 的中断输出。
18        !RESET     低电平复位
17        A2      地址脚
16        A1
15        A0
//////////////////////////////////////////////////////////////////////////////////////////////
VDD            V+
IO DIR A/B  端口方向(输入输出)
POR             复位状态
S                启动
SR                  重新启动
W                    写入
R                    读取
ACK              应答
P                    停止
OP            操作码
ADDR        硬件地址
Dout            模块输出
Din              模块输入
OLATn        输出锁存

IOCON.SEQOP=0,默认:顺序模式
PORTA
PORTB
IOCON.BANK  配置别名地址。 0:默认顺序地址
IOCON.SEQOP 字节模式或顺序模式        //字节模式: 连续访问同一地址。


两个中断引脚 INTA 和 INTB


   上电复位( POR)
IOCON.SEQOP =0默认顺序模式。
字节模式:    禁止地址指针自动递增。 (连续访问同一地址的功能。 )
顺序模式:    可使地址指针自动递增。

MCP23017 IIC接口16路IO扩展模块资料v1.2.rar

6.48 MB, 下载次数: 154

QQ750273008有好的资料记得发给我哦。。。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

75

主题

458

帖子

4

精华

金牌会员

Rank: 6Rank: 6

积分
1635
金钱
1635
注册时间
2012-8-28
在线时间
71 小时
 楼主| 发表于 2020-8-29 13:37:18 | 显示全部楼层
做遥控玩具,控制扩展io很不错的。 128个引脚可以控制很多开关信号了。,或者大家推荐个更便宜更好的io扩展模块。
QQ750273008有好的资料记得发给我哦。。。
回复 支持 反对

使用道具 举报

75

主题

458

帖子

4

精华

金牌会员

Rank: 6Rank: 6

积分
1635
金钱
1635
注册时间
2012-8-28
在线时间
71 小时
 楼主| 发表于 2020-8-29 13:40:46 | 显示全部楼层
DC24v控制只找到485模块和硬石科技的板子。还是没找到类似贝加莱分布式io模块那样的东西。老外的产品还是又小又好除了贵
QQ750273008有好的资料记得发给我哦。。。
回复 支持 反对

使用道具 举报

19

主题

113

帖子

0

精华

高级会员

Rank: 4

积分
988
金钱
988
注册时间
2013-4-21
在线时间
307 小时
发表于 2020-8-29 17:39:50 | 显示全部楼层
关注我,会给你惊喜,分布式IO,RS485接口,Modbus协议,继电器输出,了解一下
淘宝小店(一嵌在线):https://shop126340021.taobao.com
QQ:3287952605
QQ群:491729196
回复 支持 反对

使用道具 举报

75

主题

458

帖子

4

精华

金牌会员

Rank: 6Rank: 6

积分
1635
金钱
1635
注册时间
2012-8-28
在线时间
71 小时
 楼主| 发表于 2020-9-8 00:38:47 | 显示全部楼层
iic用4条线:
1:VDD电源  1.8~5.5V
2:VSS地公共端
3:SCL时钟线         //MCP23017速度100,400khz,1.7MHz
4:SDA数据线

接线:(SDA,SCL)的连接,两条总线都需要1~10K的上拉电阻。
空闲:SDA,SCL都是高电平。
开始:SCL时钟线在高电平,SDA数据线下降沿;
结束:SCL时钟线高电平,SDA数据线上升沿;
传输:SCL时钟线在低电平时,准备数据线的电平;SCL时钟线在上升沿给出数据后,SCL保持低电平(让其他器件知道总线还在使用)。
写数据:先发启动信号,再发8位操作码(0100+A2+A1+A0+(w0))验证ACK信号,再发8位寄存器地址并验证ACK,再发8位要设置的数据并验证ACK,最后发结束码。
读数据:先发启动信号,再发8位操作码(0100+A2+A1+A0+(w0))验证ACK信号,再发8位寄存器地址并验证ACK,再发启动信号,再发读操作码,再读出字节,再发停止信号。
读数据的补充:有些模块读寄存器地址后,指针会自增。所以需要定位寄存器地址。用写寄存器地址的方法定位好寄存器,再直接重新发启动信号(导致写操作被打断。但此时模块的指针地址还停在该地址上),此时再发读数据的,操作码后,模块会输出该寄存器地址上的数据。

//IIC起始信号,SDA下降沿
void iic_start()
{
    SDA_OUT_Mode(); //设置SDA为输出
    SDA=1;
    SCL=1;    //两高电平,空闲状态
    delay_us(4);
    SDA=0;//下降沿开始
    delay_us(4);
    SCL=0;//占用总线通道,不让其他主机使用该总线
}

//IIC停止信号,SDA上升沿
void iic_stop()
{
    SDA_OUT_Mode();//设置SDA为输出
    SCL=0;
    SDA=0;
     delay_us(4);
    SCL=1;
    delay_us(4);
    SDA=1;//上升沿,结束
}

//IIC发送一个字节
void iic_write_byte(u8 c)//要和起始信号配合使用
{
   u8 i;
   SDA_OUT_Mode();//设置SDA为输出
   SCL=0;//拉低时钟开始数据传输
   for(i=0;i<8;i++)
   {
      SDA_Control((c&0x80)>>7);//数据变化
      c<<=1;
      delay_us(2);
      SCL=1;//数据生效
      delay_us(2);
      SCL=0;//为下个数据准备
      delay_us(2);
    }//跳出后SCL要为0
}

//等待ACK应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
u8 iic_wait_ack(void)//检查1bit
{
    u8 outTime=0;//超时
    SDA_IN_Mode(); //设置SDA为输入
    SCL=1;
    delay_us(1);
    while(SDA_Read())//由模块拉低
    {
       outTime++;
       if(outTime>250)
       {
          iic_stop();
          return 1;
        }
    }
    SCL=0;//时钟输出0
    return 0;
}

//产生ACK应答
void iic_ack(void)
{
    SCL=0;
    SDA_OUT_Mode();
    SDA=0; //ACK信号
    delay_us(2);
    SCL=1;//数据生效
    delay_us(2);
    SCL=0;//继续占用总线
}
//不产生ACK应答
void iic_nack(void)
{
    SCL=0;
    SDA_OUT_Mode();
    SDA=1;
    delay_us(2);
    SCL=1;//数据生效
    delay_us(2);
    SCL=0;//继续占用总线
}

//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
u8 iic_read_byte(unsigned char ack)
{
    unsigned char i,receive=0;
    SCL=0;//拉低时钟开始数据传输
    SDA_IN_Mode(); //设置SDA为输入
    for(i=0;i<8;i++ )
    {
       SCL=1;//读出D7
       delay_us(2);
       receive<<=1;
       if(SDA_Read())receive++;  //读取数据
       SCL=0;//释放锁定,开始下一个数据检测
       delay_us(2);
   }
   /*
   if (!ack) iic_nack();//发送nACK
   else  iic_ack(); //发送ACK
   */
   return receive;
}

//根据地址写数据
void IIC_Write(u8 addr,uint8_t data)
{
     iic_start();  //起始信号
     iic_write_byte(I2C_SLAVE_ADDRESS7&0xFE);//发器件地址,低位为0,表示写
     iic_wait_ack(); //等待应答
     iic_write_byte(addr); //发送数据地址
     iic_wait_ack();
     iic_write_byte(data);//发送数据
     iic_wait_ack();
     iic_stop();//产生一个停止条件
}

//根据地址读取数据
u8 IIC_Read(u8 addr)  //读寄存器或读数据
{
     u8 data;
     iic_start();//起始信号
     iic_write_byte(I2C_SLAVE_ADDRESS7&0xFE);//发器件地址,低位为0,表示写
     iic_wait_ack();//等待应答
     iic_write_byte(addr); //发送数据地址
     iic_wait_ack();
     iic_start();
     iic_write_byte(I2C_SLAVE_ADDRESS7|0x01);//发器件地址,低位为1,表示读
     iic_wait_ack();
     data=iic_read_byte(0);//读取一个字节
     iic_stop();//产生一个停止条件
     return data;
}

///////////////////////////////////////////////////////////
QQ750273008有好的资料记得发给我哦。。。
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

初级会员

Rank: 2

积分
112
金钱
112
注册时间
2019-10-20
在线时间
33 小时
发表于 2021-8-14 14:38:35 | 显示全部楼层
tks,在github找了各种语言的mcp资料,中断的程序写得让人困惑,另外你用的usb 转i2c 是ch系列芯片吗?买了个cp2112,官方提供一个exmp demo和dll,没时间搞上位机,一直找不到便宜的直接调试工具
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

初级会员

Rank: 2

积分
112
金钱
112
注册时间
2019-10-20
在线时间
33 小时
发表于 2021-8-14 14:42:34 | 显示全部楼层
资料里居然有中文版的datasheet,大赞啊,鬼佬废话多,有道充值也看得糊里糊涂的
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-26 10:46

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表