|
|||||||||||
| 技術(shù)交流 | 電路欣賞 | 工控天地 | 數(shù)字廣電 | 通信技術(shù) | 電源技術(shù) | 測控之家 | EMC技術(shù) | ARM技術(shù) | EDA技術(shù) | PCB技術(shù) | 嵌入式系統(tǒng) 驅(qū)動編程 | 集成電路 | 器件替換 | 模擬技術(shù) | 新手園地 | 單 片 機 | DSP技術(shù) | MCU技術(shù) | IC 設(shè)計 | IC 產(chǎn)業(yè) | CAN-bus/DeviceNe |
C語言的16F877的IIC問題請教? |
| 作者:fineasy 欄目:單片機 |
下面是頭文件: void i2c_init() { TRISC3=1; // set SCL and SDA pins as inputs TRISC4=1; SSPCON = 0x38; // set I2C MASTER mode SSPCON2 = 0x00; //file://SSPADD = 0x6; // 400KHZ bus with 10MHZ XTAL - use 0x0C with 20MHZ XTAL SSPADD = 10; // 100K at 4MHZ clock STAT_CKE=1; // use I2C levels worked also with '0' STAT_SMP=1; // disable slew rate CONTROL worked also with '0' PSPIF=0; // clear SSPIF interrupt flag BCLIF=0; // clear bus collision flag } /******************************************************************************************/ void i2c_waitForIdle() { while (( SSPCON2 & 0x1F ) | STAT_RW ) {}; // wait for idle and not writing } /******************************************************************************************/ void i2c_start() { i2c_waitForIdle(); SEN=1; } /******************************************************************************************/ void i2c_repStart() { i2c_waitForIdle(); RSEN=1; } /******************************************************************************************/ void i2c_stop() { i2c_waitForIdle(); PEN=1; } /******************************************************************************************/ int i2c_read( unsigned CHAR ack ) { unsigned CHAR i2cReadData; i2c_waitForIdle(); RCEN=1; i2c_waitForIdle(); i2cReadData = SSPBUF; i2c_waitForIdle(); if ( ack ) { ACKDT=0; } else { ACKDT=1; } ACKEN=1; // send acknowledge sequence return( i2cReadData ); } /******************************************************************************************/ unsigned CHAR i2c_write( unsigned CHAR i2cWriteData ) { i2c_waitForIdle(); SSPBUF = i2cWriteData; return ( ! ACKSTAT ); // function returns '1' if transmission is acknowledged } 下面是讀寫函數(shù): void write_ext_EEPROM(unsigned CHAR DEVICE.html">DEVICE, unsigned CHAR address, unsigned CHAR data) { unsigned CHAR flag; while(1) { i2c_start(); flag=i2c_write(DEVICE.html">DEVICE); if (flag) break; //判定是否在寫EEPROM i2c_stop(); } i2c_write(address); i2c_write(data); i2c_stop(); //DelayMs(5); //等待寫EEPROM } /******************************************************************************************/ unsigned CHAR read_ext_EEPROM(unsigned CHAR DEVICE.html">DEVICE, unsigned CHAR address) { unsigned CHAR data; unsigned CHAR flag; while(1) { i2c_start(); flag=i2c_write(DEVICE.html">DEVICE); if (flag) break; //判定是否在寫EEPROM i2c_stop(); } i2c_write(address); i2c_repStart(); i2c_write(DEVICE.html">DEVICE+1); data=i2c_read(0); i2c_stop(); return(data); } void main() { unsigned CHAR i=0; unsigned CHAR data_hz[70]; i2c_init(); // init i2c while(i<=70) /* write 70 numbers to EEPROM 24LC01B*/ { write_ext_EEPROM(0xa0,i,i); // it to EEPROM data_hz[i]=read_ext_EEPROM(0xa0,i); i++; } TRISB=0x00; //portb out } 這是HT-PICC的一個范例程序,現(xiàn)在的問題是如不要寫EEPROM后延時,再送DEVICE后還是能收到ACK。 (根據(jù)IIC規(guī)約,器件在寫周期內(nèi)不應(yīng)答IIC總線,我以前用的匯編都是如此不加延時模式,能正常工作)。如果去掉 // data_hz[i]=read_ext_EEPROM(0xa0,i);發(fā)現(xiàn)是寫入后隔一位能寫正常,就是說寫70個數(shù)只有35個是正確寫入的。 while(1) { i2c_start(); flag=i2c_write(DEVICE.html">DEVICE); if (flag) break; //判定是否在寫EEPROM i2c_stop(); } 還是能有效。只是緊接著的一位寫入錯誤。請問是何原因?多謝!! |
|
|
| 免費注冊為維庫電子開發(fā)網(wǎng)會員,參與電子工程師社區(qū)討論,點此進入 |
Copyright © 1998-2006 m.58mhw.cn 浙ICP證030469號 |