软件I2C
I2C_GPIO.h
#ifndef _I2C_GPIO_H
#define _I2C_GPIO_H
#include "stm32f10x_lib.h"
#include "bitband.h"
#include "sys.h"
#define TIME_OUT_COUNT ((u32)72000)
#define GPIO_PORT_I2C GPIOB
#define RCC_I2C_PORT RCC_APB2Periph_GPIOB
#define I2C_1
#ifdef I2C_1
#define I2C_SCL_PIN GPIO_Pin_6
#define I2C_SDA_PIN GPIO_Pin_7
#else
#define I2C_SCL_PIN GPIO_Pin_10
#define I2C_SDA_PIN GPIO_Pin_11
#endif
#define I2C_SCL_1() GPIO_PORT_I2C->BSRR |= I2C_SCL_PIN /* SCL = 1 */
#define I2C_SCL_0() GPIO_PORT_I2C->BRR |= I2C_SCL_PIN /* SCL = 0 */
#define I2C_SDA_1() GPIO_PORT_I2C->BSRR |= I2C_SDA_PIN /* SDA = 1 */
#define I2C_SDA_0() GPIO_PORT_I2C->BRR |= I2C_SDA_PIN /* SDA = 0 */
#define I2C_SDA_READ() ((GPIO_PORT_I2C->IDR & I2C_SDA_PIN)!=0)
void I2C_GPIO_Config(void);
void I2c_Delay(u8 j);
void I2C_START(void);
void I2C_STOP(void);
void I2C_ACK(void);
void I2C_NACK(void);
u8 I2C_WAIT_ACK(void);
void I2C_SendByte(u8 data);
u8 I2C_ReadByte(void);
u8 I2C_CheckDevice(u8 Address);
u8 Checkok(u8 Addr_W);
u8 WaitStandby(u8 Addr_W);
u8 IfTimeout(void);
#endif
I2C_GPIO.c
#include "I2C_GPIO.h"
void I2C_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_I2C_PORT, ENABLE);
GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN | I2C_SDA_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIO_PORT_I2C, &GPIO_InitStructure);
I2C_STOP();
}
void I2c_Delay(u8 j)
{
u8 i;
for(i=0;i<j;i++)
{
}
}
void I2C_START(void)
{
I2C_SCL_1();
I2C_SDA_1();
I2c_Delay(10);
I2C_SDA_0();
I2c_Delay(10);
I2C_SCL_0();
I2c_Delay(10);
}
void I2C_STOP(void)
{
I2C_SDA_0();
I2C_SCL_1();
I2c_Delay(10);
I2C_SDA_1();
I2c_Delay(10);
}
void I2C_ACK(void)
{
I2C_SCL_0();
I2c_Delay(10);
I2C_SDA_0();
I2c_Delay(10);
I2C_SCL_1();
I2c_Delay(10);
I2C_SCL_0();
I2c_Delay(10);
I2C_SDA_1();
I2c_Delay(10);
}
void I2C_NACK(void)
{
I2C_SDA_1();
I2c_Delay(10);
I2C_SCL_1();
I2c_Delay(10);
I2C_SCL_0();
I2c_Delay(10);
}
u8 I2C_WAIT_ACK(void)
{
u8 ret;
I2C_SDA_1();
I2C_SCL_1();
I2c_Delay(10);
if( I2C_SDA_READ() )
{
ret=1; //非应答,从机忙
}
else
{
ret=0; //应答
}
I2C_SCL_0();
I2c_Delay(10);
return ret;
}
u8 I2C_ReadByte(void)
{
u8 value=0;
u8 i;
for(i=0;i<8;i++)
{
value=value<<1;
I2C_SCL_1();
I2c_Delay(10);
if( I2C_SDA_READ() )
{
value++;
}
I2C_SCL_0();
I2c_Delay(10);
}
return value;
}
//
void I2C_SendByte(u8 data)
{
u8 i;
for(i=0;i<8;i++)
{
if( data&0x80 ) //从高位开始发送
{
I2C_SDA_1();
}
else
{
I2C_SDA_0();
}
I2c_Delay(10);
I2C_SCL_1();
I2c_Delay(10);
I2C_SCL_0();
I2c_Delay(10);
if( i==7 )
{
I2C_SDA_1();
I2c_Delay(10);
}
data=data<<1;
}
}
u8 I2C_CheckDevice(u8 Address)
{
u8 ucACK;
I2C_GPIO_Config();
I2C_START();
I2C_SendByte(Address);
ucACK=I2C_WAIT_ACK();
I2C_STOP();
return ucACK;
}
//检查从机是否忙碌
u8 Checkok(u8 Addr_W)
{
if(I2C_CheckDevice(Addr_W)==0) // 表示从机空闲
{
return 1;//从机空闲
}
else
{
// I2C_STOP();
return 0;//从机忙碌
}
}
//检测写入数 完成
u8 WaitStandby(u8 Addr_W)
{
u32 wait_count = 0;
while(I2C_CheckDevice(Addr_W)) //表示从机忙碌
{
if((wait_count++)>0xFFFF)
{
return 1; //超时
}
}
return 0; //写入完成
}
//超时计时
u8 IfTimeout(void)
{
u32 timeout=TIME_OUT_COUNT;
while( (I2C_WAIT_ACK()==1)&timeout) //I2C_WAIT_ACK()==1时,非应答
{
timeout--;
}
if(timeout==0 )
{
return 1; //应答超时
}
else
{
timeout = TIME_OUT_COUNT;
return 0;
}
}