本人初次使用423.遇見奇怪問題。希望大家?guī)涂纯础? 我們就接423的 VDD,GND,SCL、SDA。 驅(qū)動IC是51核單片機, 我們采用公司網(wǎng)上有個423-soft那個驅(qū)動和你最新給我的代碼。 1:在INIT423后,都無法將423的 全部口(OCH、OCL ,IO ,)電平設(shè)定為0xaa,所有口全是高啊。像僅僅上電沒有驅(qū)動一樣啊。 2:假如定時(4秒)刷新全部口。一般情況下可以測試到全部口為0xaa。但時間長后發(fā)現(xiàn)還會亂。(5分鐘后除OCL2亮外,其他都滅了)。 請幫忙。 extern void SYS_Delay_mS(int bMilliSec); #pragma NOAREGS // 如果MCS51在中斷服務(wù)程序中調(diào)用CH423子程序,那么建議加入此編譯選項 extern void Delay_10US(void); /* 延時0.1uS子程序,與單片機速度有關(guān),對于雙向I/O可以不需要延時,對于帶上拉的準(zhǔn)雙向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線接口的連接,與實際電路有關(guān) */ sbit CH423_SCL = P3^4; sbit CH423_SDA = P2^6;
/* 2線接口的位操作,與單片機有關(guān) */
#define CH423_SCL_SET { CH423_SCL = 1; } #define CH423_SCL_CLR { CH423_SCL = 0; } #define CH423_SCL_D_OUT { } // 設(shè)置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 { } // 設(shè)置SDA為輸出方向,對于雙向I/O需切換為輸出 #define CH423_SDA_D_IN { CH423_SDA = 1; } // 設(shè)置SDA為輸入方向,對于雙向I/O需切換為輸入
// CH423接口定義 #define CH423_I2C_ADDR1 0x40 // CH423的地址 #define CH423_I2C_MASK 0x3E // CH423的高字節(jié)命令掩碼
/* 設(shè)置系統(tǒng)參數(shù)命令 */
#define CH423_SYS_CMD 0x4800 // 設(shè)置系統(tǒng)參數(shù)命令,默認(rèn)方式 #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 // 控制雙向輸入輸出引腳的三態(tài)輸出,為1允許輸出
/* 設(shè)置低8位開漏輸出命令 */
#define CH423_OC_L_CMD 0x4400 // 設(shè)置低8位開漏輸出命令,默認(rèn)方式 #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則引腳不輸出
/* 設(shè)置高8位開漏輸出命令 */
#define CH423_OC_H_CMD 0x4600 // 設(shè)置低8位開漏輸出命令,默認(rèn)方式 #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則引腳不輸出
/* 設(shè)置雙向輸入輸出命令 */
#define CH423_SET_IO_CMD 0x6000 // 設(shè)置雙向輸入輸出命令,默認(rèn)方式 #define BIT_IO0_DAT 0x01 // 寫入雙向輸入輸出引腳的輸出寄存器,當(dāng)IO_OE=1,IO0為0輸出低電平,為1輸出高電平 #define BIT_IO1_DAT 0x02 // 寫入雙向輸入輸出引腳的輸出寄存器,當(dāng)IO_OE=1,IO1為0輸出低電平,為1輸出高電平 #define BIT_IO2_DAT 0x04 // 寫入雙向輸入輸出引腳的輸出寄存器,當(dāng)IO_OE=1,IO2為0輸出低電平,為1輸出高電平 #define BIT_IO3_DAT 0x08 // 寫入雙向輸入輸出引腳的輸出寄存器,當(dāng)IO_OE=1,IO3為0輸出低電平,為1輸出高電平 #define BIT_IO4_DAT 0x10 // 寫入雙向輸入輸出引腳的輸出寄存器,當(dāng)IO_OE=1,IO4為0輸出低電平,為1輸出高電平 #define BIT_IO5_DAT 0x20 // 寫入雙向輸入輸出引腳的輸出寄存器,當(dāng)IO_OE=1,IO5為0輸出低電平,為1輸出高電平 #define BIT_IO6_DAT 0x40 // 寫入雙向輸入輸出引腳的輸出寄存器,當(dāng)IO_OE=1,IO6為0輸出低電平,為1輸出高電平 #define BIT_IO7_DAT 0x80 // 寫入雙向輸入輸出引腳的輸出寄存器,當(dāng)IO_OE=1,IO7為0輸出低電平,為1輸出高電平
/* 讀取雙向輸入輸出命令 */
#define CH423_RD_IO_CMD 0x4D // 輸入I/O引腳當(dāng)前狀態(tài)
// 對外子程序 extern void CH423_WriteByte( unsigned short cmd ); // 寫出數(shù)據(jù) extern unsigned char CH423_ReadByte( void ); // 讀取數(shù)據(jù)
// 特定用途子程序 extern void CH423_Write( unsigned short cmd ); // 向CH423發(fā)出操作命令,該子程序與CH423_WriteByte不同,區(qū)別主要是前者先將命令碼高8位移位 // 下述定義僅適用于CH423_Write子程序,這樣定義是為了兼容I2C數(shù)據(jù),如果不考慮兼容,那么高8位應(yīng)該先左移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; // 發(fā)送起始條件的數(shù)據(jù)信號 CH423_SDA_D_OUT; // 設(shè)置SDA為輸出方向 CH423_SCL_SET; CH423_SCL_D_OUT; // 設(shè)置SCL為輸出方向 DELAY_0_1US; CH423_SDA_CLR; //發(fā)送起始信號 DELAY_0_1US; CH423_SCL_CLR; //鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù) }
void CH423_I2c_Stop( void ) // 操作結(jié)束 { CH423_SDA_CLR; DELAY_0_1US; CH423_SCL_SET; DELAY_0_1US; CH423_SDA_SET; // 發(fā)送I2C總線結(jié)束信號 DELAY_0_1US; }
void CH423_I2c_WrByte( unsigned char dat ) // 寫一個字節(jié)數(shù)據(jù) { unsigned char i; EA=0; for( i = 0; i != 8; i ++ ) // 輸出8位數(shù)據(jù) { 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; // 接收應(yīng)答 DELAY_0_1US; CH423_SCL_CLR; EA=1; }
unsigned char CH423_I2c_RdByte( void ) // 讀一個字節(jié)數(shù)據(jù) { unsigned char dat,i; EA=0; CH423_SDA_SET; CH423_SDA_D_IN; // 設(shè)置SDA為輸入方向 dat=0; for( i = 0; i != 8; i++ ) // 輸入8位數(shù)據(jù) { 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; // 發(fā)出無效應(yīng)答 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 ); // 發(fā)送數(shù)據(jù) CH423_I2c_Stop(); // 結(jié)束總線 } */ void CH423_WriteByte( unsigned short cmd ) // 寫出數(shù)據(jù) { CH423_I2c_Start(); // 啟動總線 CH423_I2c_WrByte( ( unsigned char )( cmd>>8 ) ); CH423_I2c_WrByte( ( unsigned char ) cmd ); // 發(fā)送數(shù)據(jù) CH423_I2c_Stop(); // 結(jié)束總線 }
unsigned char CH423_ReadByte() // 讀取數(shù)據(jù) { unsigned char din; CH423_I2c_Start(); // 啟動總線 CH423_I2c_WrByte( CH423_RD_IO_CMD ); // 此值為0x4D din=CH423_I2c_RdByte(); // 讀取數(shù)據(jù) CH423_I2c_Stop(); // 結(jié)束總線 return( din ); } #if 1 // ************************************** // BCD碼表 // **************************************
#define CH423_SYSTEM