生活随笔
收集整理的這篇文章主要介紹了
单片机GPIO软件模拟I2C通讯程序
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
文章原始地址:http://feotech.com/?p=98
本程序主要用于使用可編程芯片自身的IO管腳,模擬I2C通信的協(xié)議,實現(xiàn)I2C總線數(shù)據(jù)的傳輸.
/********************************************************************************* @file Virtual_I2C.C * @author Ryan Zhao* @version V1.0.0* @date 2017-04-20* @brief 軟件I/O模擬I2C總線通訊.******************************************************************************* @attention Null* *******************************************************************************//**
* @brief I2C引腳初始化.
* @param None.
* @retval None.
*/
void I2C_Init(void)
{ GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE );//使能GPIOB時鐘GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽輸出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7); //PB6,PB7 輸出高
}/**
* @brief 產(chǎn)生I2C開始信號.
* @param None.
* @retval None.
*/
void I2C_Start(void)
{SDA_OUT(); //SDA引腳設(shè)置為輸出模式I2C_SDA_H; //SDA引腳設(shè)置為高電平 I2C_SCL_H; //SCL引腳設(shè)置為高電平 Delay(); //軟件延時I2C_SDA_L;Delay(); //軟件延時I2C_SCL_L; //準(zhǔn)備發(fā)送或接收數(shù)據(jù)
} /**
* @brief 產(chǎn)生I2C停止信號.
* @param None.
* @retval None.
*/
void I2C_Stop(void)
{SDA_OUT();//SDA引腳設(shè)置為輸出模式I2C_SCL_l;I2C_SDA_l;Delay(); //軟件延時I2C_SCL_H; I2C_SDA_H;Delay();
}/**
* @brief 等待ACK信號.
* @param None.
* @retval 1:接收應(yīng)答成功;0:接收應(yīng)答失敗;
*/
unsigned char I2C_Wait_Ack(void)
{unsigned char ucErrTime=0;SDA_IN(); //SDA引腳設(shè)置為輸入模式 I2C_SDA_H;Delay(); I2C_SCL_H;Delay(); while(READ_SDA)//讀取SDA引腳電平狀態(tài){ucErrTime++;if(ucErrTime>250){I2C_Stop();return 0; //接收應(yīng)答失敗}}I2C_SCL_L; return 1; //接收應(yīng)答成功
} /**
* @brief 產(chǎn)生ACK信號.
* @param None.
* @retval None.
*/
void I2C_Ack(void)
{I2C_SCL_L;SDA_OUT(); //SDA引腳設(shè)置為輸出模式I2C_SDA_L;Delay(); I2C_SCL_H;Delay(); I2C_SCL_L;
}/**
* @brief 不產(chǎn)生ACK信號.
* @param None.
* @retval None.
*/
void I2C_NAck(void)
{I2C_SCL_L;SDA_OUT();I2C_SDA_H;Delay();I2C_SCL_H;Delay();I2C_SCL_L;
} /**
* @brief I2C發(fā)送一個字節(jié).
* @param None.
* @retval None.
*/
void I2C_Send_Byte(unsigned char txd)
{ unsigned char i; SDA_OUT(); I2C_SCL_L;for(i=0;i<8;i++){ if((txd&0x80)>>7){I2C_SDA_H;}else{I2C_SDA_L;}txd = txd<<1; Delay();I2C_SCL_H;Delay();I2C_SCL_L; Delay();}
} /**
* @brief I2C讀取一個字節(jié).
* @param None.
* @retval 讀取到的數(shù)據(jù)
*/
unsigned char I2C_Read_Byte(unsigned char ack)
{unsigned char i,receive=0;SDA_IN();//SDA設(shè)置為輸入for(i=0;i<8;i++ ){I2C_SCL=0; Delay();I2C_SCL=1;receive<<=1;if(READ_SDA){receive++; }Delay();} if (!ack){I2C_NAck();//發(fā)送nACK}else{I2C_Ack(); //發(fā)送ACK }return receive;
}
總結(jié)
以上是生活随笔為你收集整理的单片机GPIO软件模拟I2C通讯程序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。