当前位置:网站首页>CH423要如何使用,便宜的国产IO扩展芯片
CH423要如何使用,便宜的国产IO扩展芯片
2022-06-27 00:10:00 【arenascat】
目录
前言
有时候会遇到IO不够用的情况,例如说驱动LED灯,那么有没有什么便宜的,容易买到的芯片?我这次就考虑使用WCH的CH423S,这是一个比较新的IO扩展芯片。
这一个芯片有最多24个输出引脚,双向IO有8个,可以说非常够用,价格在1.5元上下,并且货有不少。
特点
●通过两线串行接口远程扩展出8个通用输入输出引脚GPIO和16个通用输出引脚GPO。
●内置电流驱动级,连续驱动电流不小于15mA,OC引脚输出1/16脉冲灌电流不小于120mA。
●静态显示驱动方式支持24只发光管LED或者3位共阳数码管。
●分时动态扫描显示驱动方式支持128只发光管LED或者16位共阴数码管,支持亮度控制。
●双向I/O引脚在输入方式下具有输入电平变化时产生中断的功能,中断输出低电平有效。
●16个通用输出引脚可以选择推挽输出或者开漏输出。●支持3V~5V电源电压,支持低功耗睡眠,可以被输入电平变化唤醒。
●高速2线串行接口,时钟速度从0到1MHz,兼容两线I2C总线,节约引脚。
●提供DIP28S和SOP28两种无铅封装,兼容RoHS。
看一下原理图的部分,几乎不需要外围电路就可以可靠的运行。
如何使用
我根据官方的代码进行了一点修改,使得它非常的容易使用
代码如下,直接抄的官方例子然后简单修改,我用的是Arduino IDE来测试这一个芯片。
// 硬件相关定义, 请根据实际硬件修改本文件
#ifndef CH423_H
#define CH423_H
#include <arduino.h>
#define DELAY_0_1US {delayMicroseconds(5);}
/* 2线接口的连接,与实际电路有关 */
unsigned int CH423_SCL = 5;
unsigned int CH423_SDA = 6;
/* 2线接口的位操作,与单片机有关 */
#define CH423_SCL_SET { digitalWrite(CH423_SCL,HIGH); }
#define CH423_SCL_CLR { digitalWrite(CH423_SCL,LOW); }
#define CH423_SCL_D_OUT { pinMode(CH423_SCL,OUTPUT); } // 设置SCL为输出方向,对于双向I/O需切换为输出
#define CH423_SDA_SET { digitalWrite(CH423_SDA,HIGH);}
#define CH423_SDA_CLR { digitalWrite(CH423_SDA,LOW);}
//#define CH423_SDA_IN { digitalRead(CH423_SDA) }
#define CH423_SDA_D_OUT { pinMode(CH423_SDA,OUTPUT); } // 设置SDA为输出方向,对于双向I/O需切换为输出
#define CH423_SDA_D_IN { pinMode(CH423_SDA,INPUT); } // 设置SDA为输入方向,对于双向I/O需切换为输入
// CH423接口定义
#define CH423_I2C_ADDR1 0x40 // CH423的地址
#define CH423_I2C_MASK 0x3E // CH423的高字节命令掩码
/* 设置系统参数命令 */
#define CH423_SYS_CMD 0x4800 // 设置系统参数命令,默认方式
#define BIT_X_INT 0x08 // 使能输入电平变化中断,为0禁止输入电平变化中断;为1并且DEC_H为0允许输出电平变化中断
#define BIT_DEC_H 0x04 // 控制开漏输出引脚高8位的片选译码
#define BIT_DEC_L 0x02 // 控制开漏输出引脚低8位的片选译码
#define BIT_IO_OE 0x01 // 控制双向输入输出引脚的三态输出,为1允许输出
/* 设置低8位开漏输出命令 */
#define CH423_L_CMD 0x0400 // 设置低8位推挽输出命令,默认方式
#define CH423_OC_L_CMD 0x4400 // 设置低8位开漏输出命令,默认方式
#define BIT_OC0_L_DAT 0x01 // OC0为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC1_L_DAT 0x02 // OC1为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC2_L_DAT 0x04 // OC2为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC3_L_DAT 0x08 // OC3为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC4_L_DAT 0x10 // OC4为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC5_L_DAT 0x20 // OC5为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC6_L_DAT 0x40 // OC6为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC7_L_DAT 0x80 // OC7为0则使引脚输出低电平,为1则引脚不输出
/* 设置高8位开漏输出命令 */
#define CH423_H_CMD 0x0600 // 设置低8位推挽输出命令,默认方式
#define CH423_OC_H_CMD 0x4600 // 设置低8位开漏输出命令,默认方式
#define BIT_OC8_L_DAT 0x01 // OC8为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC9_L_DAT 0x02 // OC9为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC10_L_DAT 0x04 // OC10为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC11_L_DAT 0x08 // OC11为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC12_L_DAT 0x10 // OC12为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC13_L_DAT 0x20 // OC13为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC14_L_DAT 0x40 // OC14为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC15_L_DAT 0x80 // OC15为0则使引脚输出低电平,为1则引脚不输出
/* 设置双向输入输出命令 */
#define CH423_SET_IO_CMD 0x6000 // 设置双向输入输出命令,默认方式
#define BIT_IO0_DAT 0x01 // 写入双向输入输出引脚的输出寄存器,当IO_OE=1,IO0为0输出低电平,为1输出高电平
#define BIT_IO1_DAT 0x02 // 写入双向输入输出引脚的输出寄存器,当IO_OE=1,IO1为0输出低电平,为1输出高电平
#define BIT_IO2_DAT 0x04 // 写入双向输入输出引脚的输出寄存器,当IO_OE=1,IO2为0输出低电平,为1输出高电平
#define BIT_IO3_DAT 0x08 // 写入双向输入输出引脚的输出寄存器,当IO_OE=1,IO3为0输出低电平,为1输出高电平
#define BIT_IO4_DAT 0x10 // 写入双向输入输出引脚的输出寄存器,当IO_OE=1,IO4为0输出低电平,为1输出高电平
#define BIT_IO5_DAT 0x20 // 写入双向输入输出引脚的输出寄存器,当IO_OE=1,IO5为0输出低电平,为1输出高电平
#define BIT_IO6_DAT 0x40 // 写入双向输入输出引脚的输出寄存器,当IO_OE=1,IO6为0输出低电平,为1输出高电平
#define BIT_IO7_DAT 0x80 // 写入双向输入输出引脚的输出寄存器,当IO_OE=1,IO7为0输出低电平,为1输出高电平
/* 读取双向输入输出命令 */
#define CH423_RD_IO_CMD 0x4D // 输入I/O引脚当前状态
// 对外子程序
extern void CH423_WriteByte( unsigned short cmd ); // 写出数据
extern unsigned char CH423_ReadByte( void ); // 读取数据
// 特定用途子程序
extern void CH423_Write( unsigned short cmd ); // 向CH423发出操作命令,该子程序与CH423_WriteByte不同,区别主要是前者先将命令码高8位移位
// 下述定义仅适用于CH423_Write子程序,这样定义是为了兼容I2C数据,如果不考虑兼容,那么高8位应该先左移1位
#define CH423_DIG0 0x1000 // 数码管位0显示
#define CH423_DIG1 0x1100 // 数码管位1显示
#define CH423_DIG2 0x1200 // 数码管位2显示
#define CH423_DIG3 0x1300 // 数码管位3显示
#define CH423_DIG4 0x1400 // 数码管位4显示
#define CH423_DIG5 0x1500 // 数码管位5显示
#define CH423_DIG6 0x1600 // 数码管位6显示
#define CH423_DIG7 0x1700 // 数码管位7显示
#define CH423_DIG8 0x1800 // 数码管位8显示
#define CH423_DIG9 0x1900 // 数码管位9显示
#define CH423_DIG10 0x1A00 // 数码管位10显示
#define CH423_DIG11 0x1B00 // 数码管位11显示
#define CH423_DIG12 0x1C00 // 数码管位12显示
#define CH423_DIG13 0x1D00 // 数码管位13显示
#define CH423_DIG14 0x1E00 // 数码管位14显示
#define CH423_DIG15 0x1F00 // 数码管位15显示
#endif
void CH423_I2c_Start( void ) // 操作起始
{
CH423_SDA_SET; // 发送起始条件的数据信号
CH423_SDA_D_OUT; // 设置SDA为输出方向
CH423_SCL_SET;
CH423_SCL_D_OUT; // 设置SCL为输出方向
DELAY_0_1US;
CH423_SDA_CLR; //发送起始信号
DELAY_0_1US;
CH423_SCL_CLR; //钳住I2C总线,准备发送或接收数据
}
void CH423_I2c_Stop( void ) // 操作结束
{
CH423_SDA_CLR;
DELAY_0_1US;
CH423_SCL_SET;
DELAY_0_1US;
CH423_SDA_SET; // 发送I2C总线结束信号
DELAY_0_1US;
}
void CH423_I2c_WrByte( unsigned char dat ) // 写一个字节数据
{
unsigned char i;
for( i = 0; i != 8; i++ ) // 输出8位数据
{
if( dat&0x80 ) { CH423_SDA_SET; }
else { CH423_SDA_CLR; }
DELAY_0_1US;
CH423_SCL_SET;
dat<<=1;
DELAY_0_1US; // 可选延时
CH423_SCL_CLR;
}
CH423_SDA_SET;
DELAY_0_1US;
CH423_SCL_SET; // 接收应答
DELAY_0_1US;
CH423_SCL_CLR;
}
unsigned char CH423_I2c_RdByte( void ) // 读一个字节数据
{
unsigned char dat,i;
CH423_SDA_SET;
CH423_SDA_D_IN; // 设置SDA为输入方向
dat=0;
for( i = 0; i != 8; i++ ) // 输入8位数据
{
DELAY_0_1US; // 可选延时
CH423_SCL_SET;
DELAY_0_1US; // 可选延时
dat<<=1;
if(digitalRead(CH423_SDA)==HIGH)
{
dat++; // 输入1位
}
CH423_SCL_CLR;
}
CH423_SDA_SET;
DELAY_0_1US;
CH423_SCL_SET; // 发出无效应答
DELAY_0_1US;
CH423_SCL_CLR;
return(dat);
}
void CH423_Write( unsigned short cmd ) // 写命令
{
CH423_I2c_Start(); // 启动总线
CH423_I2c_WrByte( ( ( unsigned char )( cmd>>7 ) & CH423_I2C_MASK ) | CH423_I2C_ADDR1 );
CH423_I2c_WrByte( ( unsigned char ) cmd ); // 发送数据
CH423_I2c_Stop(); // 结束总线
}
void CH423_WriteByte( unsigned short cmd ) // 写出数据
{
CH423_I2c_Start(); // 启动总线
CH423_I2c_WrByte( ( unsigned char )( cmd>>8 ) );
CH423_I2c_WrByte( ( unsigned char ) cmd ); // 发送数据
CH423_I2c_Stop(); // 结束总线
}
unsigned char CH423_ReadByte() // 读取数据
{
unsigned char din;
CH423_I2c_Start(); // 启动总线
CH423_I2c_WrByte( CH423_RD_IO_CMD ); // 此值为0x4D
din=CH423_I2c_RdByte(); // 读取数据
CH423_I2c_Stop(); // 结束总线
return( din );
}
void Test()
{
CH423_WriteByte(CH423_SYS_CMD | BIT_IO_OE );//默认模式
CH423_WriteByte(CH423_SET_IO_CMD | BIT_IO1_DAT);//IO1输出
CH423_WriteByte(CH423_OC_L_CMD | BIT_OC0_L_DAT );//OC0输出
delay(1300);
CH423_WriteByte(CH423_SET_IO_CMD );//清空输出
CH423_WriteByte(CH423_OC_L_CMD );//清空输出
delay(1300);
}
如果要使用,那么只需要修改这几个地方,首先是通讯的两线的引脚
/* 2线接口的连接,与实际电路有关 */
unsigned int CH423_SCL = 5;
unsigned int CH423_SDA = 6;
然后就可以使用了,为了方便测试我配置了一个Test函数,可以让OC0和IO1都输出高电平其他则不输出。
下面以一些例子来说明如何初始化以及控制CH423s的输出
例子1 配置输出
一开始,先配置为默认模式,发送设置系统参数命令,设置双向引脚IO0到IO7为输出模式
CH423_WriteByte(CH423_SYS_CMD | BIT_IO_OE );//默认模式
然后,配置IO1为输出
CH423_WriteByte(CH423_SET_IO_CMD | BIT_IO1_DAT);
这样就可以实现IO1输出高电平。
例子2 配置OC1输出
CH423在上电的时候,OC0到OC15这些引脚默认下被配置为推挽输出
所以只需要
CH423_WriteByte(CH423_OC_L_CMD | BIT_OC1_L_DAT );//OC1输出
就可以让OC1输出高电平,其他低电平
例子3 配置OC14输出
因为有16个输出脚位(加8个双向一共24)所以说需要使用另一个代码来配置OC8到OC15
CH423_WriteByte(CH423_OC_H_CMD | BIT_OC14_L_DAT );//OC14输出
边栏推荐
- 目前哪个证券公司炒股开户是最好最安全的?
- In the Internet industry, there are many certificates with high gold content. How many do you have?
- Reading graph augmentations to learn graph representations (lg2ar)
- 剑指 Offer 10- II. 青蛙跳台阶问题
- MATLAB data type - character type
- 2022健康博览会,山东养生保健展会,产后健康、睡眠健康展
- Lwip之定时机制
- 新型冠状病毒变异Delta毒株的模拟(MindSPONGE应用)
- idea 热启动失效解决方案
- Is it safe for CITIC Securities Commission to open an online account and speculate in stocks
猜你喜欢
随机推荐
Record a bug caused by a line break
Competition Registration | one of the key ai+ scientific computing competitions - China open source scientific software creativity competition, competing for 100000 bonus!
Deep learning method for solving mean field game theory problems
全网最全的混合精度训练原理
接口测试框架实战(一) | Requests 与接口请求构造
墨者学院-X-Forwarded-For注入漏洞实战
Lambda expression
中信证券佣金 网上开户炒股安全吗
Big guys talk about the experience sharing of the operation of the cutting-edge mindspore open source community. Come up with a small notebook!
技术干货|什么是大模型?超大模型?Foundation Model?
05 | 规范设计(下):commit 信息风格迥异、难以阅读,如何规范?
超硬核!华为智慧屏上的家庭相册竟可以自动精准分类?
“message“:“Bad capabilities. Specify either app or appTopLevelWindow to create a session“
Kubernetes visual interface dashboard
Other service registration and discovery
Concepts de base de données Oracle
Employment prospect of GIS and remote sensing specialty and ranking selection of universities in 2022
CPU的异常处理
Understanding of "the eigenvectors corresponding to different eigenvalues cannot be orthogonalized"
滑环选型选购时需要注意的技巧