I2C 使用Microchip plib
本篇以dsPIC30F為主。plib 安裝
到Legacy PIC24 MCU & dsPIC DSC Peripheral Library下載最新的plib,然後她會要求將plib安裝到你電腦中xc16 complier的資料夾下(linux在”/opt/microchip/xc16”下)。函式概覽
安裝後文件會在xc16 complier的docs/periph_libs下。其中plib提供以下函式。
AckI2C還有一些MARCO
CloseI2C
ConfigIntI2C
DataRdyI2C
IdleI2C
MastergetsI2C
MasterputsI2C
MasterReadI2C
MasterWriteI2C
NotAckI2C
OpenI2C
RestartI2C
SlavegetsI2C
SlaveputsI2C
SlaveReadI2C
SlaveWriteI2C
StartI2C
StopI2C
EnableIntMI2C這份文件16 bit language tools第191頁開始有詳述這些函式的介面。所以本文主要會面向如何運用這些函式達成master與slave溝通。
DiableIntMI2C
SetPriorityIntMI2C
EnableIntSI2C
DisableIntSI2C
SetPriorityIntSI2C
I2C (dsPIC30F as Master with 7bit address)
reception
以下圖片來自於http://ww1.microchip.com/downloads/en/DeviceDoc/70046E.pdf對應到plib的流程為。(以下為我在i2cdevlib中所新增的片段,為一次讀多個bytes)。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Master |S |Device Addr+W| |Reg Addr| |S |Device Addr+R| | |NACK|P| | |
Slave | | |ACK| |ACK| | |ACK|DATA| | | |
請先透過ConfigIntI2C和OpenI2C設定好硬體參數。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
IFS0bits.MI2CIF = 0; | |
IEC0bits.MI2CIE = 0; | |
/*master Start*/ | |
StartI2C(); | |
/* Clear interrupt flag */ | |
/* Wait till Start sequence is completed */ | |
while(I2CCONbits.SEN); | |
/*master send AD+W*/ | |
/* Write Slave Address (Write)*/ | |
MasterWriteI2C(devAddr << 1 | 0x00); | |
/* Wait until address is transmitted */ | |
while(I2CSTATbits.TBF); // 8 clock cycles | |
/*Slave send Ack*/ | |
while(!IFS0bits.MI2CIF); // Wait for 9th clock cycle | |
IFS0bits.MI2CIF = 0; // Clear interrupt flag | |
while(I2CSTATbits.ACKSTAT); | |
/*Master send RA*/ | |
/* Write Register Address */ | |
MasterWriteI2C(regAddr); | |
/* Wait until address is transmitted */ | |
while(I2CSTATbits.TBF); // 8 clock cycles | |
/*Slave send ACK*/ | |
while(!IFS0bits.MI2CIF); // Wait for 9th clock cycle | |
IFS0bits.MI2CIF = 0; // Clear interrupt flag | |
while(I2CSTATbits.ACKSTAT); | |
/*Master Pause*/ | |
StopI2C(); | |
/* Wait till stop sequence is completed */ | |
while(I2CCONbits.PEN); | |
/*Master Start*/ | |
StartI2C(); | |
/* Wait till Start sequence is completed */ | |
while(I2CCONbits.SEN); | |
/*Master send AD+R*/ | |
/* Write Slave Address (Read)*/ | |
MasterWriteI2C(devAddr << 1 | 0x01); | |
/* Wait until address is transmitted */ | |
while(I2CSTATbits.TBF); // 8 clock cycles | |
/*Slave send Ack*/ | |
while(!IFS0bits.MI2CIF); // Wait for 9th clock cycle | |
IFS0bits.MI2CIF = 0; // Clear interrupt flag | |
while(I2CSTATbits.ACKSTAT); | |
data[0] = MasterReadI2C(); | |
unsigned int i; | |
for (i = 1 ; i < length ; i++ ){ | |
AckI2C(); | |
while(I2CCONbits.ACKEN == 1); | |
data[i] = MasterReadI2C(); | |
} | |
NotAckI2C(); | |
while(I2CCONbits.ACKEN == 1); | |
/*Master Pause*/ | |
StopI2C(); | |
/* Wait till stop sequence is completed */ | |
while(I2CCONbits.PEN); |
transmission
transmission只要全部都由Master端給資料即可。對應到plib的流程為。(以下為我在i2cdevlib中所新增的片段,為一次寫多個bytes)。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Master |S |Device Addr+W| |Reg Addr| |DATA| |P| | |
Slave | | |ACK| |ACK| |ACK | | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
IFS0bits.MI2CIF = 0; | |
IEC0bits.MI2CIE = 0; | |
/*Master Start*/ | |
StartI2C(); | |
/* Wait util Start sequence is completed */ | |
while(I2CCONbits.SEN); | |
/* Clear interrupt flag */ | |
IFS0bits.MI2CIF = 0; | |
/*Master send AD+W*/ | |
/* Write Slave address (Write)*/ | |
MasterWriteI2C(devAddr << 1 | 0x00); | |
/* Wait till address is transmitted */ | |
while(I2CSTATbits.TBF); // 8 clock cycles | |
/*Slave send ACK*/ | |
while(!IFS0bits.MI2CIF); // Wait for 9th clock cycle | |
IFS0bits.MI2CIF = 0; // Clear interrupt flag | |
while(I2CSTATbits.ACKSTAT); | |
/*Master send RA*/ | |
/* Write Slave address (Write)*/ | |
MasterWriteI2C(regAddr); | |
/* Wait till address is transmitted */ | |
while(I2CSTATbits.TBF); // 8 clock cycles | |
/*Slave send ACK*/ | |
while(!IFS0bits.MI2CIF); // Wait for 9th clock cycle | |
IFS0bits.MI2CIF = 0; // Clear interrupt flag | |
while(I2CSTATbits.ACKSTAT); | |
/*Master send data*/ | |
/* Transmit string of data */ | |
uint8_t i; | |
for (i = 0 ; i < length ; i++){ | |
MasterWriteI2C(data[i]); | |
/* Wait till address is transmitted */ | |
while(I2CSTATbits.TBF); // 8 clock cycles | |
/*Slave send ACK*/ | |
while(!IFS0bits.MI2CIF); // Wait for 9th clock cycle | |
IFS0bits.MI2CIF = 0; // Clear interrupt flag | |
} | |
StopI2C(); | |
/* Wait till stop sequence is completed */ | |
while(I2CCONbits.PEN); | |
Written with StackEdit.