本帖最后由 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小跑堂
|