文章
博客 网店

 STM32G0 LL库示例-I2C(软)




//IIC端口操作宏
#define  IIC2_SDA LL_GPIO_IsInputPinSet(GPIOB,LL_GPIO_PIN_7)
#define  IIC2_SDA_H  LL_GPIO_SetOutputPin(GPIOB , LL_GPIO_PIN_7)
#define  IIC2_SDA_L  LL_GPIO_ResetOutputPin(GPIOB , LL_GPIO_PIN_7)          
#define  IIC2_SCL_H LL_GPIO_SetOutputPin(GPIOA , LL_GPIO_PIN_0)
#define  IIC2_SCL_L LL_GPIO_ResetOutputPin(GPIOA , LL_GPIO_PIN_0) 

//总线延时
static void iic_delaybus(void)
{
  uint8_t i;
  for(i=0;i<10;i++)
    __nop();
}

//初始化端口
void iic_init(void)
{
 //SCL,SDA 初始化
  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

  LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_7);
  LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_0);

  GPIO_InitStruct.Pin = LL_GPIO_PIN_7;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  
 GPIO_InitStruct.Pin = LL_GPIO_PIN_0;
  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

//时钟线保持高时数据线从高变低为开始信号
void iic_start(void)
{
  IIC2_SDA_H;       
  IIC2_SCL_H;
  iic_delaybus();
  IIC2_SDA_L;           
  iic_delaybus();
  IIC2_SCL_L;         
  iic_delaybus();  
}

//时钟线保持高时数据线从低变高为停止信号
void iic_stop(void)
{  
  IIC2_SDA_L;    
  IIC2_SCL_H;
  iic_delaybus();
  IIC2_SDA_H;    
  iic_delaybus();

}
//向IIC总线发送一字节数据并返回是否有ACK应答
uint8_t  iic_writebyte(uint8_t c)
{
  uint8_t i,ack;

  for(i=0;i<8;i++)  
  {
    if(c&0x80)
      IIC2_SDA_H;   
    else  
      IIC2_SDA_L;                
    IIC2_SCL_H;       
    iic_delaybus();        
    IIC2_SCL_L; 
    c<<=1;
    iic_delaybus();
  }
  
  IIC2_SDA_H;  //设置为输入
  iic_delaybus();   
   IIC2_SCL_H;
  iic_delaybus();  //等待数据稳定
  if(IIC2_SDA)  //读数据
    ack=IIC_NOT_ACK;     //失败
  else 
    ack=IIC_ACK;        
  IIC2_SCL_L;
  iic_delaybus();//函数尾部确保有延时

  return ack;
}
//从IIC总线读一字节
uint8_t  iic_readbyte(uint8_t ack)
{
  uint8_t i,ret=0;

  IIC2_SDA_H; //确保输入状态
  for(i=0;i<8;i++)
  {                
    IIC2_SCL_H;                
    iic_delaybus();
    ret<<=1;
    if(IIC2_SDA)
      ret++; 
    IIC2_SCL_L;
    iic_delaybus(); 
  }

  if(ack==IIC_ACK)  //应答
    IIC2_SDA_L;            
  else    // 非应答
    IIC2_SDA_H;
  iic_delaybus();
  IIC2_SCL_H;
  iic_delaybus();                  
  IIC2_SCL_L;                     
  iic_delaybus();   //函数尾部确保有延时

  return(ret);
}  


头文件定义:

#define IIC_ACK      1
#define IIC_NOT_ACK    0



芯艺工作室    蒙ICP备06005492号
Copyright© 2004-2023 ChipArt Studio All Rights Reserved