打印
[AT32F403/403A]

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

[复制链接]
3733|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hejun96|  楼主 | 2021-4-10 15:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 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[4];
u8 Refresh_SHT30_Data=0;
u8 humiture_buff1[20];
u8 humiture_buff2[20];

u8 Temperature_L=15;
u8 Humidity_L=50;
u8 Temperature_H=30;
u8 Humidity_H=80;
/*******************************************************************
函数:SHT30_Init
功能:
********************************************************************/
void SHT30_Init(void)
{
   GPIO_InitTypeDef  GPIO_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
功能:发送字节
********************************************************************/
void  IIC_SendByte(u8 byte)
{
        u8  BitCnt;
        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[6];
        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[0]=IIC_RcvByte();
                IIC_ACK();
                buff[1]=IIC_RcvByte();
                IIC_ACK();
                buff[2]=IIC_RcvByte();
                IIC_ACK();
                buff[3]=IIC_RcvByte();
                IIC_ACK();
                buff[4]=IIC_RcvByte();
                IIC_ACK();
                buff[5]=IIC_RcvByte();
                IIC_NACK();
                IIC_Stop();
        }
        tem = ((buff[0]<<8) | buff[1]);
        hum = ((buff[3]<<8) | buff[4]);
        
        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[0]=Temperature;
                humiture[2]=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小跑堂

使用特权

评论回复
评论
weict125 2021-4-13 22:25 回复TA
厉害 
沙发
别看我照片| | 2021-4-10 18:37 | 只看该作者
这个帖子的含金量确实很高的,不错的帖子,感谢楼主的分享。

使用特权

评论回复
板凳
嵌入小菜菜| | 2021-4-13 23:11 | 只看该作者
感谢楼主的分享,不错的,很棒的。

使用特权

评论回复
地板
084425| | 2021-4-14 20:09 | 只看该作者
厉害了

使用特权

评论回复
5
2020HXQ| | 2021-4-17 08:33 | 只看该作者
好像有灵感了,I2C循环读取函数

使用特权

评论回复
6
duckfans| | 2021-4-17 23:42 | 只看该作者
谢谢分享,不过有没有18B20的例子?

使用特权

评论回复
7
hejun96|  楼主 | 2021-5-26 10:50 | 只看该作者
duckfans 发表于 2021-4-17 23:42
谢谢分享,不过有没有18B20的例子?

DS18B20,单工通信的,这个应该也好做,我之前看到过雅特力专栏里面有一个帖子是DS18B20的,我自己的帖子暂时没有

使用特权

评论回复
8
HJD001| | 2021-9-7 11:20 | 只看该作者
SHT31A,18B20现货供应,价格美丽,V18664394396

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

55

帖子

2

粉丝