hejun96 发表于 2021-4-10 15:12

在AT32F403A上使用模拟IIC时序和SHT31A通信读温湿度

本帖最后由 hejun96 于 2021-6-11 09:38 编辑

#申请原创# 在AT32F403A上使用模拟GPIO时序和SHT31A通信读温湿度

1.初始化GPIO
#define SCL PBout(6)
#define SDA_OUT PBout(7)
#define SDA_IN PBin(7)

//IO方向操作
#define IIC_INPUT_MODE_SET(){GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=0x40000000;}///GPIOB->CRL|=8<<28;}//IO设置输入模式
#define IIC_OUTPUT_MODE_SET() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=0X30000000;}///GPIOB->CRL|=3<<28;}//IO设置输出模式

float humiture;
u8 Refresh_SHT30_Data=0;
u8 humiture_buff1;
u8 humiture_buff2;

u8 Temperature_L=15;
u8 Humidity_L=50;
u8 Temperature_H=30;
u8 Humidity_H=80;
/*******************************************************************
函数:SHT30_Init
功能:
********************************************************************/
void SHT30_Init(void)
{
   GPIO_InitTypeDefGPIO_InitStructure;
   
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);         //使能PB端口时钟
   
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;                                 //SCL端口配置
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //开漏输出
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;               //IO口速度为50MHz
   GPIO_Init(GPIOB, &GPIO_InitStructure);                                       //根据设定参数初始化GPIOA

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;                                 //SDA端口配置
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //开漏输出
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;               //IO口速度为50MHz
   GPIO_Init(GPIOB, &GPIO_InitStructure);                                       //根据设定参数初始化GPIOA

         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_15;                                 //SDA端口配置
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //开漏输出
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;               //IO口速度为50MHz
   GPIO_Init(GPIOB, &GPIO_InitStructure);
      
   GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7);//SDA/SCL拉高
GPIO_SetBits(GPIOB,GPIO_Pin_13);
GPIO_ResetBits(GPIOB,GPIO_Pin_15);

}      
/*******************************************************************
函数:IIC_ACK
功能:
********************************************************************/
void IIC_ACK(void)
{
IIC_OUTPUT_MODE_SET();
SCL=0;
delay_us(2);
SDA_OUT=0;
delay_us(2);   
SCL=1;
delay_us(2);                  
SCL=0;                     
delay_us(1);   
}

/*******************************************************************
函数:IIC_NACK
功能:
********************************************************************/
void IIC_NACK(void)
{
IIC_OUTPUT_MODE_SET();
SCL=0;
delay_us(2);
SDA_OUT=1;
delay_us(2);      
SCL=1;
delay_us(2);                  
SCL=0;                     
delay_us(1);   
}
/*******************************************************************
函数:IIC_wait_ACK
功能:
********************************************************************/
u8 IIC_wait_ACK(void)
{
    u8 t = 200;
    IIC_OUTPUT_MODE_SET();
    SDA_OUT=1;
    delay_us(1);
    SCL=0;
    delay_us(1);
    IIC_INPUT_MODE_SET();
    delay_us(1);
    while(SDA_IN)//
    {
      t--;
      delay_us(1);
      if(t==0)
      {
          SCL=0;
          return 1;
      }
      delay_us(1);
    }
    delay_us(1);      
    SCL=1;
    delay_us(1);
    SCL=0;            
    delay_us(1);   
    return 0;      
}
/*******************************************************************
函数:IIC_Start
功能:
********************************************************************/
void IIC_Start(void)
{
IIC_OUTPUT_MODE_SET();
SDA_OUT=1;
SCL=1;
delay_us(4);      
SDA_OUT=0;
delay_us(4);
SCL=0;
}

/*******************************************************************
函数:IIC_Stop
功能:
********************************************************************/
void IIC_Stop(void)
{
      IIC_OUTPUT_MODE_SET();
      SCL=0;
      SDA_OUT=0;
      delay_us(4);      
      SCL=1;
      delay_us(4);
      SDA_OUT=1;
      delay_us(4);
}

/*******************************************************************
函数:IIC_SendByte
功能:发送字节
********************************************************************/
voidIIC_SendByte(u8 byte)
{
      u8BitCnt;
      IIC_OUTPUT_MODE_SET();
      SCL=0;
      for(BitCnt=0;BitCnt<8;BitCnt++)
      {
                if(byte&0x80) SDA_OUT=1;
                else SDA_OUT=0;
                byte<<=1;
                delay_us(2);
                SCL=1;
                delay_us(2);
                SCL=0;
                delay_us(2);
      }
}
/*******************************************************************
函数:IIC_RcvByte
功能:接收字节
********************************************************************/
u8 IIC_RcvByte(void)
{
u8 retc;
u8 BitCnt;
retc=0;
IIC_INPUT_MODE_SET();
delay_us(1);                  
for(BitCnt=0;BitCnt<8;BitCnt++)
{
      SCL=0;
      delay_us(2);               
      SCL=1;               
      retc=retc<<1;
      if(SDA_IN) retc |=1;
      delay_us(1);
}
SCL=0;   
return(retc);
}
/*******************************************************************
函数:SHT30_read_result
功能:温湿度读取
********************************************************************/
void SHT30_read_result(u8 addr)
{
      u16 tem,hum;
      u16 buff;
      float Temperature=0;
      float Humidity=0;
      
      IIC_Start();
      IIC_SendByte(addr<<1 | write);
      IIC_wait_ACK();
      IIC_SendByte(0x2C);
      IIC_wait_ACK();
      IIC_SendByte(0x06);
      IIC_wait_ACK();
      IIC_Stop();
      delay_ms(50);
      IIC_Start();
      IIC_SendByte(addr<<1 | read);
      if(IIC_wait_ACK()==0)
      {
                buff=IIC_RcvByte();
                IIC_ACK();
                buff=IIC_RcvByte();
                IIC_ACK();
                buff=IIC_RcvByte();
                IIC_ACK();
                buff=IIC_RcvByte();
                IIC_ACK();
                buff=IIC_RcvByte();
                IIC_ACK();
                buff=IIC_RcvByte();
                IIC_NACK();
                IIC_Stop();
      }
      tem = ((buff<<8) | buff);
      hum = ((buff<<8) | buff);
      
      Temperature= (175.0*(float)tem/65535.0-45.0) ;// T = -45 + 175 * tem / (2^16-1)
      Humidity= (100.0*(float)hum/65535.0);// RH = hum*100 / (2^16-1)

      
      if((Temperature>=-20)&&(Temperature<=125)&&(Humidity>=0)&&(Humidity<=100))
      {
                humiture=Temperature;
                humiture=Humidity;

      }
      hum=0;
      tem=0;

   HMI1_SendNumber("x0.val=",7,Temperature*100,4);//温度,串口屏浮点型数据处理
   HMI1_SendNumber("x1.val=",7,Humidity*100,4);//湿度,串口屏浮点型数据处理

    currentDataPoint.valueTemperature =Temperature ;//Add Sensor Data Collection
    currentDataPoint.valueHumidity = Humidity ;//Add Sensor Data Collection


}void delay_us(u16 time)
{   
   u16 i=0;
   while(time--)
   {
      i=10;//
      while(i--) ;   
   }
}
//
void delay_ms(u16 time)
{   
   u16 i=0;
   while(time--)
   {
      i=10200;//
      while(i--) ;   
   }
}
延时函数可以用示波器抓,SHT31A发送完字节后在读字节前要延时久一点,我用了delay_ms(50);
建议在主循环中每2s调用SHT30_read_result,可用一个通用定时器的中断做2s中断一次@21小跑堂

别看我照片 发表于 2021-4-10 18:37

这个帖子的含金量确实很高的,不错的帖子,感谢楼主的分享。

嵌入小菜菜 发表于 2021-4-13 23:11

感谢楼主的分享,不错的,很棒的。

084425 发表于 2021-4-14 20:09

厉害了

2020HXQ 发表于 2021-4-17 08:33

好像有灵感了,I2C循环读取函数

duckfans 发表于 2021-4-17 23:42

谢谢分享,不过有没有18B20的例子?

hejun96 发表于 2021-5-26 10:50

duckfans 发表于 2021-4-17 23:42
谢谢分享,不过有没有18B20的例子?
DS18B20,单工通信的,这个应该也好做,我之前看到过雅特力专栏里面有一个帖子是DS18B20的,我自己的帖子暂时没有

HJD001 发表于 2021-9-7 11:20

SHT31A,18B20现货供应,价格美丽,V18664394396
页: [1]
查看完整版本: 在AT32F403A上使用模拟IIC时序和SHT31A通信读温湿度