欢迎您光临五金加工厂,如有问题请及时联系我们。

stm32f103普通io口可以作为i2c通信接口吗?

作者:五金加工
文章来源:本站

  可以,模拟i2c即可,举例:

  void IIC_Init(void)

  {ttttt

  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_APB2PeriphClockCmd(tRCC_APB2Periph_GPIOB, ENABLE );t

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6GPIO_Pin_7;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOB, &GPIO_InitStructure);

  IIC_SCL=1;

  IIC_SDA=1;

  }

  //产生IIC起始信号

  void IIC_Start(void)

  {

  SDA_OUT(); //sda线输出

  IIC_SDA=1;t t

  IIC_SCL=1;

  delay_us(4);

  IIC_SDA=0;//START:when CLK is high,DATA change form high to low

  delay_us(4);

  IIC_SCL=0;//钳住I2C总线,准备发送或接收数据

  }t

  //产生IIC停止信号

  void IIC_Stop(void)

  {

  SDA_OUT();//sda线输出

  IIC_SCL=0;

  IIC_SDA=0;//STOP:when CLK is high DATA change form low to high

  delay_us(4);

  IIC_SCL=1;

  IIC_SDA=1;//发送I2C总线结束信号

  delay_us(4);ttttttt t

  }

  //等待应答信号到来

  //返回值:1,接收应答失败

  // 0,接收应答成功

  u8 IIC_Wait_Ack(void)

  {

  u8 ucErrTime=0;

  SDA_IN(); //SDA设置为输入

  IIC_SDA=1;delay_us(1);t

  IIC_SCL=1;delay_us(1);t

  while(READ_SDA)

  {

  ucErrTime++;

  if(ucErrTime>250)

  {

  IIC_Stop();

  return 1;

  }

  }

  IIC_SCL=0;//时钟输出0 t

  return 0;

  }

  //产生ACK应答

  void IIC_Ack(void)

  {

  IIC_SCL=0;

  SDA_OUT();

  IIC_SDA=0;

  delay_us(2);

  IIC_SCL=1;

  delay_us(2);

  IIC_SCL=0;

  }

  //不产生ACK应答tt

  void IIC_NAck(void)

  {

  IIC_SCL=0;

  SDA_OUT();

  IIC_SDA=1;

  delay_us(2);

  IIC_SCL=1;

  delay_us(2);

  IIC_SCL=0;

  }ttttt tttt

  //IIC发送一个字节

  //返回从机有无应答

  //1,有应答

  //0,无应答ttt

  void IIC_Send_Byte(u8 txd)

  {

  u8 t;

  SDA_OUT(); t

  IIC_SCL=0;//拉低时钟开始数据传输

  for(t=0;t<8;t++)

  {

  IIC_SDA=(txd&0x80)>>7;

  txd<<=1; t

  delay_us(2); //对TEA5767这三个延时都是必须的

  IIC_SCL=1;

  delay_us(2);

  IIC_SCL=0;t

  delay_us(2);

  }t

  } t

  //读1个字节,ack=1时,发送ACK,ack=0,发送nACK

  u8 IIC_Read_Byte(unsigned char ack)

  {

  unsigned char i,receive=0;

  SDA_IN();//SDA设置为输入

  for(i=0;i<8;i++ )

  {

  IIC_SCL=0;

  delay_us(2);

  IIC_SCL=1;

  receive<<=1;

  if(READ_SDA)receive++;

  delay_us(1);

  }ttttt

  if (!ack)

  IIC_NAck();//发送nACK

  else

  IIC_Ack(); //发送ACK

  return receive;

  }

  void I2C_WriteByte(uint16_t addr,uint8_t data,uint8_t device_addr)

  {

  IIC_Start();

  if(device_addr==0xA0) //eeprom地址大于1字节

  IIC_Send_Byte(0xA0 + ((addr/256)<<1));//发送高地址

  else

  IIC_Send_Byte(device_addr);t //发器件地址

  IIC_Wait_Ack();

  IIC_Send_Byte(addr&0xFF); //发送低地址

  IIC_Wait_Ack();

  IIC_Send_Byte(data); //发送字节ttttttt

  IIC_Wait_Ack(); tt t

  IIC_Stop();//产生一个停止条件

  if(device_addr==0xA0) //

  delay_ms(10);

  else

  delay_us(2);

  }

  uint16_t I2C_ReadByte(uint16_t addr,uint8_t device_addr,uint8_t ByteNumToRead) //读寄存器或读数据

  {t

  uint16_t data;

  IIC_Start();

  if(device_addr==0xA0)

  IIC_Send_Byte(0xA0 + ((addr/256)<<1));

  else

  IIC_Send_Byte(device_addr);t

  IIC_Wait_Ack();

  IIC_Send_Byte(addr&0xFF); //发送低地址

  IIC_Wait_Ack();

  IIC_Start(); t

  IIC_Send_Byte(device_addr+1);t //发器件地址

  IIC_Wait_Ack();

  if(ByteNumToRead == 1)//LM75温度数据为11bit

  {

  data=IIC_Read_Byte(0);

  }

  else

  {

  data=IIC_Read_Byte(1);

  data=(data<<8)+IIC_Read_Byte(0);

  }

  IIC_Stop();//产生一个停止条件t

  return data;

  }

  

stm32f103普通io口可以作为i2c通信接口吗?

  

stm32f103普通io口可以作为i2c通信接口吗?

  

stm32f103普通io口可以作为i2c通信接口吗?

来源:文章来源于网络,如有侵权请联系我们删除。本文由五金加工编辑,欢迎分享本文,转载请保留出处和链接!