在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小跑堂 这个帖子的含金量确实很高的,不错的帖子,感谢楼主的分享。 感谢楼主的分享,不错的,很棒的。 厉害了 好像有灵感了,I2C循环读取函数 谢谢分享,不过有没有18B20的例子? duckfans 发表于 2021-4-17 23:42
谢谢分享,不过有没有18B20的例子?
DS18B20,单工通信的,这个应该也好做,我之前看到过雅特力专栏里面有一个帖子是DS18B20的,我自己的帖子暂时没有 SHT31A,18B20现货供应,价格美丽,V18664394396
页:
[1]