本人初次使用423.遇见奇怪问题。希望大家帮看看。 我们就接423的 VDD,GND,SCL、SDA。 驱动IC是51核单片机, 我们采用公司网上有个423-soft那个驱动和你最新给我的代码。 1:在INIT423后,都无法将423的 全部口(OCH、OCL ,IO ,)电平设定为0xaa,所有口全是高啊。像仅仅上电没有驱动一样啊。 2:假如定时(4秒)刷新全部口。一般情况下可以测试到全部口为0xaa。但时间长后发现还会乱。(5分钟后除OCL2亮外,其他都灭了)。 请帮忙。 extern void SYS_Delay_mS(int bMilliSec); #pragma NOAREGS // 如果MCS51在中断服务程序中调用CH423子程序,那么建议加入此编译选项 extern void Delay_10US(void); /* 延时0.1uS子程序,与单片机速度有关,对于双向I/O可以不需要延时,对于带上拉的准双向I/O建议加上延时 */ //#define DELAY_0_1US {} // MCS51<=10MHz #if 1 void _delay_453_i2c(void) { BYTE i; for(i=0;i<50;i++){} } #endif #define DELAY_0_1US _delay_453_i2c(); // MCS51>10MHz
/* 2线接口的连接,与实际电路有关 */ sbit CH423_SCL = P3^4; sbit CH423_SDA = P2^6;
/* 2线接口的位操作,与单片机有关 */
#define CH423_SCL_SET { CH423_SCL = 1; } #define CH423_SCL_CLR { CH423_SCL = 0; } #define CH423_SCL_D_OUT { } // 设置SCL为输出方向,对于双向I/O需切换为输出 #define CH423_SDA_SET { CH423_SDA = 1;} #define CH423_SDA_CLR { CH423_SDA = 0;} #define CH423_SDA_IN ( CH423_SDA ) #define CH423_SDA_D_OUT { } // 设置SDA为输出方向,对于双向I/O需切换为输出 #define CH423_SDA_D_IN { CH423_SDA = 1; } // 设置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_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_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位 // ************************************** // CH423初始化 // ************************************** void CH423_Init( void ) { CH423_SCL_D_OUT; CH423_SDA_SET; CH423_SDA_D_OUT; }
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; EA=0; 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; EA=1; }
unsigned char CH423_I2c_RdByte( void ) // 读一个字节数据 { unsigned char dat,i; EA=0; 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(CH423_SDA_IN) dat++; // 输入1位 CH423_SCL_CLR; } CH423_SDA_SET; DELAY_0_1US; CH423_SCL_SET; // 发出无效应答 DELAY_0_1US; CH423_SCL_CLR; EA=1; 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 ); } #if 1 // ************************************** // BCD码表 // **************************************
#define CH423_SYSTEM