2014-09-26 114 views
1

我使用pic16f1704微控制器,我的編譯器是xc8。我一直在試圖獲得控制器與地址0x00的I2C通信。我的SCL引腳是RC0,SDA引腳是RC1。我發現xc8編譯器中的內置函數可以與pic16一起使用。我根據數據表做了以下代碼。但編譯我的代碼後,我無法獲得SCL和SDA波形。使用xc8編譯器的pic16f1704的I2C通信

請看我的代碼是否正確,請讓我知道我哪裏出錯了。

#include<xc.h> 
#pragma config FOSC=INTOSC, PLLEN=OFF, MCLRE=ON, WDTE=OFF 
#pragma config LVP=OFF, CLKOUTEN=OFF 
#define SCL  TRISC0 
#define SDA  TRISC1 
#define SCL_IN RC0  
#define SDA_IN RC1 
void init() 
{ 
SDA = SCL = 1; 
SCL_IN = SDA_IN = 1; //SDA & SCL at high state 
} 
void i2c_start(void) 
{ 
    SDA = 1;    // i2c start bit sequence 

    SCL = 1; 
    _delay(10000); 
    SDA = 0; 

    SCL = 1; 
    _delay(10000); 
} 
void i2c_stop(void) 
{ 
    SDA = 0;    // i2c stop bit sequence 
_delay(10000); 
    SCL = 1; 
    _delay(1000); 
    SDA = 1; 
_delay(10000); 
} 
void I2CWait() 
{ 
    while ((SSPCON2 & 0x1F) || (SSPSTAT & 0x04)); 

} 

void main() 
{ 
    OSCCONbits.SCS = 0x02; //set the SCS bits to select internal oscillator block 

    OSCCONbits.IRCF = 0x0F; //set OSCCON IRCF 

    BAUD1CONbits.BRG16=0; //BRGH IS NOT VALID IN SYNCHRONOUS TRANSMISSION 

    SPBRGH=0X00; 

    SPBRGL=0X19; 

     SLRCONC=0xff; //Slew rate IS LIMITED 

     ANSELC=0x00; //Digital mode is selected 



    SSPCLKPPS=0x10; 

    SSPDATPPS=0X11;  //PPL for input pins 

    RC0PPS=0X10; 
    RC1PPS=0X11;  //PPL for output pins 





    SSPCONbits.SSPM0=0; 
    SSPCON1bits.SSPM1=0; 
    SSPCON1bits.SSPM2=0; 
    SSPCON1bits.SSPM3=1; //selecting I2C master mode 

    SSP1STATbits.SMP=1; //SLEW RATE CONTROL 
    SSP1STATbits.CKE=1; //CLOCK EDGE SELECT BIT 
    SPEN=1; 
    ACKEN=1; 
    SSPCON1=0X28;   //sync. serial port enable bit is set along with I2C mastermode 
    SSPADD=0X27;   //calculated value 
    GIE=1; 
    PIE1=1; 
    TXIE=1; 
    init(); 
    SEN=1;    //start enable 
i2c_start(); 
I2CWait(); 
_delay(10000); 
SSPBUF=0X00; 
_delay(10000); 
PEN=1;     //stop enable 
i2c_stop(); 
} 

另請參閱啓動條件所需的這些類型的初始化。

void i2c_start(void) 
{ 
    SDA = 1;    // i2c start bit sequence 

    SCL = 1; 
    _delay(10000); 
    SDA = 0; 

    SCL = 1; 
    _delay(10000); 
} 

我認爲這是沒有必要的。當SEN(啓動使能)位置位時,控制器驅動SDA爲低電平,SCL保持高電平。

回答

0

你說:

我想是不是necessary.When SEN(開始啓用)位設置 控制器驅動SDA低,SCL仍然很高。

你是對的。但是,不僅對於啓動條件,而且對於重複啓動,停止等等,您都無法自己直接控制SCL和SDA引腳(即使在初始化功能中,只需將方向設置爲輸入)。

實例啓動條件:

void i2c_start(void) 
{ 
SSPCON2.SEN = 1;//start condition generation 
while(!PIR1.SSPIF);//wait until MSSP has finished 
PIR1.SSPIF = 0;//clear the flag 
}//at the exit of the function, start condition is complete 

的「起始條件使能」這個詞是不正確使用由Microchip:它不能夠啓動的條件,但它產生開始狀態...

所以你不必自己編寫SCL和SDA引腳,也不必使用延遲。您只需爲條件生成(SEN,RSEN,PEN)或緩衝區(SSPBUF)寫入正確的位,然後等待SSPIF位完成操作。

它與生成重複啓動和停止條件的方式相同。

在數據表的第318頁可以找到有關i2c主模式傳輸的完整信息。

希望它能幫到你, 關心。