I2C英文名為inter-Integrated Circuit,是用于多設備通訊的兩線式串行總線,分為主機Master和從機Slave,通常有一個主機和多個從機,從機之間可通過地址進行區(qū)分,不同種類的設備地址不同。I2C分別是時鐘線SCL和數(shù)據(jù)線SDA,其中SCL和SDA由主機控制,可設置成開漏輸出模式。
STM32 IO口模擬I2C實例代碼1:
#define IIC_SCL_1 GPIO_SetBits(GPIOB, GPIO_Pin_6) /* SCL = 1 */
#define IIC_SCL_0 GPIO_ResetBits(GPIOB, GPIO_Pin_6) /* SCL = 0 */
#define IIC_SDA_1 GPIO_SetBits(GPIOB, GPIO_Pin_7) /* SDA = 1 */
#define IIC_SDA_0 GPIO_ResetBits(GPIOB, GPIO_Pin_7) /* SDA = 0 */
#define IIC_READ_SDA() GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_7) /* 讀SDA口線狀態(tài) */
//初始化IIC
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD ; //開漏輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
IIC_Stop();
}
//產生IIC起始信號
//SCL為高電平時SDA由高變低
void IIC_Start(void)
{
IIC_SDA_1;
IIC_SCL_1;
delay_us(4);
IIC_SDA_0;
delay_us(4);
IIC_SCL_0;
}
//產生IIC停止信號
//SCL為高電平時SDA由低變高
//IIC空閑時SCL和SDA均輸出高電平,這樣不會干擾其他設備的收發(fā)
void IIC_Stop(void)
{
IIC_SDA_0;
IIC_SCL_1;
delay_us(4);
IIC_SDA_1;
}
//等待應答信號到來
//返回值:1,接收應答失敗
// 0,接收應答成功
{
uint8_t errCount = 0;
uint8_t ack = 0;
IIC_SDA_1;
delay_us(4);
IIC_SCL_1;
delay_us(4);
while(IIC_READ_SDA())
{
errCount++;
if(errCount 》 250){
ack = 1;
break;
}
}
IIC_SCL_0;
return ack;
}
//產生應答ACK
//SCL為高電平時SDA為低電平表示應答
void IIC_Ack(void)
{
IIC_SDA_0;
delay_us(4);
IIC_SCL_1;
delay_us(4);
IIC_SCL_0;
delay_us(4);
IIC_SDA_1; //釋放SDA
}
//產生非應答NACK
//SCL為高電平時SDA為高電平表示非應答
void IIC_NAck(void)
{
IIC_SDA_1;
delay_us(4);
IIC_SCL_1;
delay_us(4);
IIC_SCL_0;
delay_us(4);
}
//IIC發(fā)送一個字節(jié)
void IIC_WriteByte(uint8_t txd)
{
uint8_t i;
IIC_SCL_0;
for(i = 0; i 《 8; i++)
{
(txd & 0x80) ? IIC_SDA_1 : IIC_SDA_0;
txd 《《= 1;
delay_us(4);
IIC_SCL_1;
delay_us(4);
IIC_SCL_0;
delay_us(4);
}
IIC_SDA_1;
}
//讀1個字節(jié),ack=1時,發(fā)送ACK,ack=0,發(fā)送NACK
uint8_t IIC_ReadByte(uint8_t ack)
{
uint8_t i, rcv = 0;
for(i = 0; i 《 8; i++)
{
rcv 《《= 1;
IIC_SCL_1;
delay_us(4);
if(IIC_READ_SDA()){
rcv++;
}
IIC_SCL_0;
delay_us(4);
}
ack ? IIC_Ack() : IIC_NAck();
return rcv;
}
STM32 IO口模擬I2C實例代碼2:
#define I2C_Speed 100000#define I2C_EE I2C1#define uStatus 0x80#define dTime 5#define I2C_EE_GPIO GPIOB#define I2C_EE_SCL GPIO_Pin_5#define I2C_EE_SDA GPIO_Pin_4#define I2C_EE_CLK RCC_APB1Periph_I2C1#define SCL_H GPIOB-》BSRR = GPIO_Pin_5#define SCL_L GPIOB-》BRR = GPIO_Pin_5#define SDA_H GPIOB-》BSRR = GPIO_Pin_4#define SDA_L GPIOB-》BRR = GPIO_Pin_4#define SCL_read GPIOB-》IDR & GPIO_Pin_5#define SDA_read GPIOB-》IDR & GPIO_Pin_4static unsigned int cntForInitial = 0;static unsigned char fSigStatus = 0;//static bool LedStatus = true;void I2C_Init(){GPIO_InitTypeDef GPIO_InitStructure;//* Configure I2C_EE pins: SCL and SDAGPIO_InitStructure.GPIO_Pin = I2C_EE_SCL | I2C_EE_SDA;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;GPIO_Init(I2C_EE_GPIO, &GPIO_InitStructure);}static void i2c_start(){SDA_H;SCL_H;DelayUs(dTime);SDA_L;DelayUs(dTime);SCL_L;DelayUs(dTime);// LedStatus = !LedStatus;//f_LCT1(LedStatus);}/*******************************************************************Fuction:Stop i2c*******************************************************************/static void i2c_stop(){SDA_L;SCL_H;DelayUs(dTime);SDA_H;DelayUs(dTime);SCL_H;DelayUs(dTime);}/*******************************************************************Fuction:i2c Master wait for ackOnly ack*******************************************************************/static unsigned char i2c_rd_ack(){unsigned char flag = 0;SDA_H;SCL_H;DelayUs(dTime/2);flag = SDA_read;DelayUs(dTime/2);SCL_L;DelayUs(dTime/2);if(flag == 1)return 0;return 1;}/*******************************************************************Fuction:i2c Byte transmissionOnly Send,no ack,no stop*******************************************************************/static unsigned char i2c_sb(unsigned char Byte){unsigned char cnt;SCL_L;for(cnt=0;cnt《8;cnt++){if(Byte&0x80)SDA_H;elseSDA_L;DelayUs(dTime);SCL_H;DelayUs(dTime);SCL_L;Byte 《《= 1;DelayUs(dTime);}return i2c_rd_ack();}/*******************************************************************Fuction:i2c Byte receiveReturn Byte*******************************************************************/static unsigned char i2c_rb(){unsigned char cnt;unsigned char Byte=0;SDA_H;for(cnt=0;cnt《8;++cnt){Byte 《《= 1;DelayUs(dTime);SCL_H;DelayUs(dTime);if(SDA_read)Byte |= 0x01;SCL_L;DelayUs(dTime);}return Byte;}/*******************************************************************Fuction:i2c ACK Master send*******************************************************************/static void i2c_wr_ack(unsigned char ACK){if(ACK)SDA_H;elseSDA_L;SCL_H;DelayUs(dTime);SCL_L;DelayUs(dTime);}/*******************************************************************Fuction:i2c Byte receiveReturn Byte*******************************************************************/uint8_t ReadReg(unsigned int addr){uint8_t temp;i2c_start();if(!i2c_sb(BRG_DEV_ADDR)){i2c_stop();return 0;}if(!i2c_sb((uint8_t)(addr 》》 8))){i2c_stop();return 0;}if(!i2c_sb((uint8_t)(addr & 0xFF))){i2c_stop();return 0;}i2c_start();if(!i2c_sb(BRG_DEV_ADDR |0x01)){i2c_stop();return 0;}temp = i2c_rb();i2c_wr_ack(1);i2c_stop();return temp;}unsigned char WriteReg8(unsigned int addr,unsigned char wData){i2c_start();if(!i2c_sb(BRG_DEV_ADDR)){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(addr 》》 8))){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(addr & 0xFF))){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(wData))){i2c_stop();return 0;}i2c_stop();//DelayUs(1);return 1; }unsigned char WriteReg16(unsigned int addr,unsigned char wData1,unsigned char wData2){i2c_start();if(!i2c_sb(BRG_DEV_ADDR)){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(addr 》》 8))){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(addr & 0xFF))){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(wData2))){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(wData1))){i2c_stop();return 0;}i2c_stop();DelayUs(1);return 1; }unsigned char WriteReg32(unsigned int addr,unsigned char wData1,unsigned char wData2,unsigned char wData3,unsigned char wData4){i2c_start();if(!i2c_sb(BRG_DEV_ADDR)){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(addr 》》 8))){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(addr & 0xFF))){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(wData4))){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(wData3))){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(wData2))){i2c_stop();return 0;}if(!i2c_sb((unsigned char)(wData1))){i2c_stop();return 0;}i2c_stop();DelayUs(1);return 1;}
以上是STM32 IO口模擬I2C的源代碼,希望對用戶有所幫助。
本文整合自CSDN、博客園
責編AJX
-
STM32
+關注
關注
2266文章
10876瀏覽量
354923 -
源代碼
+關注
關注
96文章
2944瀏覽量
66673
發(fā)布評論請先 登錄
相關推薦
評論