完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一、概述
RVB2601是基于平头哥生态芯片CH2601的开发板,板载JTAG调试器,WiFi&BLE芯片W800,音频ADCES7210,音频DACES8156,128x64 OLED屏幕,RGB三色指示灯,用户按键,及兼容Arduino的扩展接口,功能很多,接口很丰富,通过短接片,从两排插针引出相应的功能,目前短接片已经插得满满的了,如果还需要一些I/O点,连接外围传感器、继电器,该怎么办? IO扩展有很多种方式,采用译码器,用74系列的74HC138(三八译码器),只需要3个IO口就可以扩展成8个输入口:输入极性。 串行数据移位,74HC595、74HC164同样也可以用少量IO口扩展成更多的IO口,而且支持级联,也是一种不错的选择: 总线接口,MCP23017(IIC接口)和MCP23S17(SPI接口)扩展模块:推荐使用I2C 串行接口的16位 I/O 扩展模块。 二、IIC串行接口 CH2601的内部设计有IIC总线,板子上的I2C总线与ES7210连接,ES7210芯片是四通道ADC采集芯片,在板子上连接了硅麦,ES7210的数据是通过I2S总线连接的CH2601,芯片的配置是通过IIC连接到CH2601,IIC接口被占用,只能另外想办法。 用普通I/O口,按照IIC的通信协议,软件模拟IIC时序逻辑,切换高低电平,实现IIC串行接口的功能,只需占用两个引脚,通过GPIO连接外设。具体实现方法请参考另外一篇博文,使用CDK在RVB2061上编写IIC软件驱动——快来测体温队。 三、扩展模块 IIC接口的MCP23017只需要两个IO口,便可以实现最多16*8=128个IO口的扩展,其中,16为每个芯片的最大IO口,8为最大地址数量,因为只有3个地址控制位,所以最大只能设置8个地址,MCP23017能够将16位并行数据转换为IIC接口的串型数据并可相互转化,MCP23017芯片IO口的模式可以任意设置为输入或输出模式,所以,我们可以在这扩展的最大的128个IO口中,任意搭配出不同的输入口和输出口。 接口电路: 模块控制接口采用的是双排接口,每个标号同时有两个排针,这样方便多个模块并联接线,免得从单片机开发板引出多根线到每个模块。 控制接口包括SCL、SDA、RST、ITA、ITB。 RST接到低电平时,芯片复位,在板上有一个10K欧姆的上拉电阻将RST拉到了VCC,如果不需要通过单片机控制芯片复位,在使用模块时,此引脚可不接线。 ITA、ITB是中断输出引脚,ITA对应GPIOA上的输入中断,ITB对应GPIOB 上的输入中断。不使用中断可不接,使用中断时可接到单片机的外部中断引脚上。ITA、ITB可联合在一起使用,即当16 个IO上任何一个中断输入产生中断时,ITA和ITB同时产生中断输出。具体在驱动函数的MCP23017 初始化函数中配置。ITA、ITB的输出类型可设置位 OD输出,推挽输出-高电平有效,推挽输出-低电平有效,具体在具体在驱动函数的MCP23017 初始化函数中 四、程序设计 扩展I/O功能实现: 1. 设置引脚模式:输入模式、输出模式、上拉输入模式(内部上拉电阻100KΩ); 2. 读取并设置引脚电平值; 3. 支持5种中断方式:高电平中断、低电平中断、上升沿中断、下降沿中断、双边沿跳变中断; 4. 支持2路中断信号输出:当端口A的某个引脚发生中断时,INTA引脚输出高电平,当端口B的某个引脚发生中断,INTB引脚输出高电平; 5. 轮询中断:可通过轮询中断函数,检测引脚是否发生中断,并执行相应的中断服务函数; 定义IIC接口操作函数: extern void OpenI2C(unsigned char sync_mode, unsigned char slew); extern void I2CStart(void); extern void I2CReStart(void); extern void I2CStop(void); extern unsigned char WaitForACK(void); extern void ACKI2C(void); extern unsigned char WriteI2C(unsigned char data_out); extern unsigned char ReadI2C(void); extern void nACK(void); extern unsigned char I2CDataReady(void); unsigned char WriteI2C( unsigned char data_out ) { unsigned char n; SCL_L; //SCL LOW... just in case for(n=0; n<8; n++) { if((data_out << n) & 0x80) { SDA_H; SCL_H; SCL_L; } else { SDA_L; SCL_H; SCL_L; } } return 0; } unsigned char ReadI2C(void) { unsigned char n, data_in; data_in = 0; for(n=0; n<8; n++) { SCL_H; data_in = ((data_in + SDA_LEVEL) << 1); SCL_L; } data_in = data_in >> 1; return(data_in); } 定义MSCP23017寄存器操作数: #define IODIRA 0x00 #define IODIRB 0x01 #define IPOLA 0x02 #define IPOLB 0x03 #define GPINTENA 0x04 #define GPINTENB 0x05 #define DEFVALA 0x06 #define DEFVALB 0x07 #define INTCONA 0x08 #define INTCONB 0x09 #define IOCONA 0x0A #define IOCONB 0x0B #define GPPUA 0x0C #define GPPUB 0x0D #define INTFA 0x0E #define INTFB 0x0F #define INTCAPA 0x010 #define INTCAPB 0x011 #define GPIOA 0x012 #define GPIOB 0x013 #define OLATA 0x014 #define OLATB 0x015 定义MCP23017操作函数: #define WrtCmd 0 #define RdCmd 1 unsigned char gAddrPins = 0; unsigned char I2CBaudGenerator = 125; unsigned char SerialMode = I2CMODE; unsigned char gControlByte = 0x40; void InitMCP( void ) { //Configure 23017 Write23X17(GPPUA, 0x0F); // Pullups Write23X17(IOCONA, 0x40); // Write23X17(IODIRA, 0xFF); //All inputs by default (this is the POR default) Write23X17(IODIRB, 0xFF); //All inputs by default (this is the POR default) } //**************************************** // I2CWriteByte(unsigned char addr, unsigned char byte) // Writes a byte to the 23017 //**************************************** void I2CWriteByte(unsigned char reg, unsigned char data) { I2CStart(); WriteI2C( gControlByte | WrtCmd | gAddrPins ); WaitForACK(); WriteI2C( reg ); WaitForACK(); WriteI2C( data ); WaitForACK(); I2CStop(); } //**************************************** // int I2CReadByte(unsigned char addr)) // Reads a byte from the 23008 //**************************************** unsigned char I2CReadByte(unsigned char reg) { unsigned char num; I2CStart(); WriteI2C( gControlByte | WrtCmd | gAddrPins ); WaitForACK(); WriteI2C( reg ); WaitForACK(); I2CReStart();; WriteI2C( gControlByte | RdCmd | gAddrPins ); WaitForACK(); num = ReadI2C(); nACK(); I2CStop(); return(num); } void Write23X17(unsigned char reg, unsigned char data) { I2CWriteByte(reg, data); // } unsigned char Read23X17(unsigned char reg) { unsigned char num; num = I2CReadByte(reg); return(num); } 五、参考资料 1、芯片手册 文章转载自:平头哥芯片开放社区 作者:sqhone |
|
相关推荐
|
|
只有小组成员才能发言,加入小组>>
【平头哥Sipeed LicheeRV 86开发板试用体验】Waft初体验
15662 浏览 1 评论
13713 浏览 4 评论
【平头哥Sipeed LicheeRV 86开发板试用体验】四、烧写waft系统&搭建waft测试环境
19633 浏览 2 评论
59038 浏览 19 评论
【限时福利】加入芯片开发社区,领100G电子工程师资料大礼包
87767 浏览 121 评论
邀请函 | 3月2日 来上海参加平头哥“玄铁RISC-V生态大会”
746浏览 0评论
读书分享会 | 玄铁RISC-V处理器入门与实战电子书免费下载!
643浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-27 05:57 , Processed in 0.638165 second(s), Total 62, Slave 48 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号