STM32F1的I2C使用

11 篇文章 0 订阅

I2C:

串行的8位双向数据传输位速率,在标准模式下可达100kbit/s,快速模式下可达400kbit/s,高速模式下可达3.4Mbit/s。

特点:
1.通信线少,布线简单
2.总线可以并联多个设备,不需要增加通信线,扩展性好
3.协议简单,通信速度中等,还可以用IO口模拟


模拟I2C:

STM32F1模拟标准I2C

//初始化i2c两个引脚
void MYI2C_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructing;
	RCC_APB2PeriphClockCmd(I2C_SDA_RCC , ENABLE);
	RCC_APB2PeriphClockCmd(I2C_SCL_RCC , ENABLE);
	
	GPIO_InitStructing.GPIO_Mode  = GPIO_Mode_Out_OD;  
	GPIO_InitStructing.GPIO_Pin   = SDA_PIN;
	GPIO_InitStructing.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(SDA_PORT, &GPIO_InitStructing);
	
	GPIO_InitStructing.GPIO_Pin   = SCL_PIN;
	GPIO_Init(SCL_PORT, &GPIO_InitStructing);
}

//配置为输入模式
void GPIO_SDA_INPUT(void)
{
	GPIO_InitTypeDef GPIO_InitStructing;
	RCC_APB2PeriphClockCmd(I2C_SDA_RCC , ENABLE);
	
	GPIO_InitStructing.GPIO_Mode  = GPIO_Mode_IPU;  
	GPIO_InitStructing.GPIO_Pin   = SDA_PIN;
	GPIO_InitStructing.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(SDA_PORT, &GPIO_InitStructing);
}

//配置为输出模式
void GPIO_SDA_OUTPUT(void)
{
	GPIO_InitTypeDef GPIO_InitStructing;
	RCC_APB2PeriphClockCmd(I2C_SDA_RCC , ENABLE);
	
	GPIO_InitStructing.GPIO_Mode  = GPIO_Mode_Out_OD;  
	GPIO_InitStructing.GPIO_Pin   = SDA_PIN;
	GPIO_InitStructing.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(SDA_PORT, &GPIO_InitStructing);
}

//输出0/1
void SDA_OUT(bool num)
{
	if(num)
	{
		GPIO_SetBits(SDA_PORT, SDA_PIN);
	}
	else
	{
		GPIO_ResetBits(SDA_PORT, SDA_PIN);
	}
}

//读取引脚高低
bool SDA_IN(void)
{
	bool flag = 1;
	uint32_t count = 0;
	
	GPIO_SDA_INPUT();
	
	while(count < 80)
	{
		count++;
		flag &= GPIO_ReadInputDataBit(SDA_PORT, SDA_PIN);
	}
	
	delay();
	GPIO_SDA_OUTPUT();
	
	return flag;
}




//时钟输出
void SCL_OUT(bool num)
{
	if(num){
		GPIO_SetBits(SCL_PORT, SCL_PIN);
	}
	else{
		GPIO_ResetBits(SCL_PORT, SCL_PIN);
	}
}

//开始
void IIC_start(void)
{
	SDA_OUT(1);
	SCL_OUT(1);
	delay();
	SDA_OUT(0);
	delay();
	SCL_OUT(0);
}
//停止
void IIC_Stop(void)
{
	SCL_OUT(0);	
	SDA_OUT(0);
	SCL_OUT(1);
	delay();
	SDA_OUT(1);
}
//应答
void IIC_Ack(unsigned char ackbit)
{
	SCL_OUT(0);
	
	if(ackbit) 
	{	
		SDA_OUT(0);
	}
	else 
	{
		SDA_OUT(1);
	}
	delay();
	SCL_OUT(1);
	delay();
	SCL_OUT(0);
}
//等待应答
bool IIC_WaitAck(void)
{
	SDA_OUT(1);
	delay();
	SCL_OUT(1);
	delay();
	while(SDA_IN())    
	{   
		SCL_OUT(0);
		IIC_Stop();
		return 0;
	}
	
	SCL_OUT(0);
	return 1;
}
//发送一个字节
void IIC_SendByte(unsigned char byt)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{   
		if(byt&0x80) 
		{	
			SDA_OUT(1);
		}
		else 
		{
			SDA_OUT(0);
		}
		delay();
		SCL_OUT(1);
		byt <<= 1;
		delay();
		SCL_OUT(0);
	}
}
//读取一个字节
unsigned char IIC_RecByte(void)
{
	unsigned char da = 0;
	unsigned char i;
	
	for(i=0;i<8;i++)
	{   
		SCL_OUT(1);
		delay();
		da <<= 1;
		if(SDA_IN()) 
		da |= 0x01;
		SCL_OUT(0);
		delay();
	}
	return da;
}

针对AT24C02的一个应用

void AT24_write(uint8_t adr,uint8_t data)
{
	IIC_start();
	IIC_SendByte(0xa0);//0xa0 + AT24C02器件地址  0xa0表示写
	IIC_WaitAck();
	IIC_SendByte(adr);//写入的地址
	IIC_WaitAck();
	IIC_SendByte(data);//写入的数据
	IIC_WaitAck();
	IIC_Stop();
	delay();
}

uint8_t AT24_read(uint8_t adr)
{
	uint8_t data;
	
	IIC_start();
	IIC_SendByte(0xa0);//0xa0 + AT24C02器件地址  0xa0表示写
	IIC_WaitAck();
	IIC_SendByte(adr);//想要读取的地址
	IIC_WaitAck();
	
	IIC_start();
	IIC_SendByte(0xa1);//0xa1 + AT24C02器件地址  0xa1表示读
	IIC_WaitAck();
	data = IIC_RecByte();//读取的数据
	IIC_Ack(0);
	IIC_Stop();
	delay();
	
	return data;
}

硬件I2C:

采用的是STM32F1的硬件I2C

配置硬件:

//配置引脚
void I2C_GPIO_Config(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}
//初始化 
void I2C1_Init(void)
{
	I2C_InitTypeDef I2C_InitStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
	I2C_DeInit(I2C1);
	I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;//I2C主机模式
	I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;//I2C快速模式
	I2C_InitStructure.I2C_OwnAddress1 = 0xff;//自身地址
	I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;//使能应答
	I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//定义从机地址位数7bit
	I2C_InitStructure.I2C_ClockSpeed = 10000;//I2C通信速率10k
	I2C_Init(I2C1, &I2C_InitStructure);//初始化
	I2C_Cmd(I2C1, ENABLE);//使能
}

对AT24C2的应用:

//I2C写入
void I2C1_Write(u8 addr, u8 data)  //写入的地址   写入的数据
{	
	I2C_AcknowledgeConfig(I2C1,ENABLE); 
	I2C_GenerateSTART(I2C1,ENABLE); 
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)){;}//
	I2C_Send7bitAddress(I2C1,0xa0,I2C_Direction_Transmitter); //0xa0 + AT24C02器件地址  0xa0表示写
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){;} 
	I2C_SendData(I2C1,addr); 
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){;} 
	I2C_SendData(I2C1,data);
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){;} 
	I2C_GenerateSTOP(I2C1,ENABLE); 
}
 
 //读取I2C
u8 I2C1_Read(u8 nAddr)//读取的地址
{
	I2C_AcknowledgeConfig(I2C1,ENABLE); 
	I2C_GenerateSTART(I2C1,ENABLE); //开始
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)){;} //在高速率下,可能会卡在这
	I2C_Send7bitAddress(I2C1,0xa0,I2C_Direction_Transmitter); //0xa0 + AT24C02器件地址  0xa0表示写
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){;}//EV6
	I2C_SendData(I2C1,nAddr);//
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){;} 
	 
	I2C_GenerateSTART(I2C1,ENABLE); //
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)){;} 
	I2C_Send7bitAddress(I2C1,0xa1,I2C_Direction_Receiver); //0xa1 + AT24C02器件地址  0xa1表示读
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)){;} 
	I2C_AcknowledgeConfig(I2C1,DISABLE); //
	I2C_GenerateSTOP(I2C1,ENABLE); //
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)){;} 
	return I2C_ReceiveData(I2C1); //
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值