楼上的发错了那个是SHT21,楼主要的是SHT11,我来发个例程。
----------------
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "usart1.h"
#include "stdio.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define SDA_H() GPIO_SetBits(GPIOB,GPIO_Pin_0)
#define SDA_L() GPIO_ResetBits(GPIOB,GPIO_Pin_0)
#define SCK_H() GPIO_SetBits(GPIOB,GPIO_Pin_1)
#define SCK_L() GPIO_ResetBits(GPIOB,GPIO_Pin_1)
//读SDA数据
#define SDA_R() GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)
/* Private macro -------------------------------------------------------------*/
#define noACK 0 //无应答
#define ACK 1 //应答
#define STATUS_REG_W 0x06 //000 0011 0
#define STATUS_REG_R 0x07 //000 0011 1
#define MEASURE_TEMP 0x03 //000 0001 1
#define MEASURE_HUMI 0x05 //000 0010 1
#define RESET 0x1e //000 1111 0
/* Private variables ---------------------------------------------------------*/
enum {TEMP,HUMI};
uint8_t Test_Timetick = 0;
uint16_t Test_Counter = 0;
/* Private function prototypes -----------------------------------------------*/
void RCC_Config(void);
void USART1_Config(void);
void SHT10_Config(void);
void SHT10_SDAIn(void);
void SHT10_SDAOut(void);
void SHT10_Delay(void);
uint8_t SHT10_WriteByte(uint8_t value);
uint8_t SHT10_ReadByte(uint8_t Ack);
void SHT10_Start(void);
void SHT10_ConReset(void);
uint8_t SHT10_Measure(uint16_t* pValue, uint8_t* pCheckSum, uint8_t mode);
void SHT10_Cal(uint16_t Temp,uint16_t Hum, float* pTempValue,float* pHumValue);
/* Private functions ---------------------------------------------------------*/
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] 主程序
* @param 无
* @retval 无
*/
int main(void)
{
//温度结果 16bit
uint16_t TempValue;
//湿度结果 16bit
uint16_t HumValue;
//温度转换结果
float TempResult;
//湿度转换结果
float HumResult;
//校验值
uint8_t CheckValue = 0x00;
//错误
uint8_t error = 0x00;
//初始化RCC
RCC_Config();
USART1_Config();
SHT10_Config();
printf("Start\n");
while(1)
{
if(Test_Timetick)
{
Test_Timetick = 0;
Test_Counter ++;
//延时2000ms
if(Test_Counter > 2000)
{
Test_Counter = 0;
printf("启动转换!\n");
//SHT10 连接
SHT10_ConReset();
//获得温度和湿度数据,16位格式
error += SHT10_Measure(&TempValue,&CheckValue,TEMP);
error += SHT10_Measure(&HumValue,&CheckValue,HUMI);
//温度湿度计算,浮点数形式
SHT10_Cal(TempValue ,HumValue,&TempResult,&HumResult);
//通过串口输出,温度和湿度数据
printf("温度 %2.1fC 湿度 %2.1f%%\n",TempResult,HumResult);
}
}
}
}
/**
* @brief 初始化Systick定时器
* @param None
* @retval None
*/
void RCC_Config(void)
{
//Systick时钟每1ms触发一次
if (SysTick_Config(SystemCoreClock / 1000))
{
//
while (1);
}
}
/**
* @brief 初始化SHT10 IO口
* @param None
* @retval None
*/
void SHT10_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB ,ENABLE);
//PB0 SDA 推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//PB1 SCK 推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/**
* @brief 配置为输入状态
* @param None
* @retval None
*/
void SHT10_SDAIn(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//PB0 SDA 浮动输入,外部有上拉电阻
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/**
* @brief 配置为输出状态
* @param None
* @retval None
*/
void SHT10_SDAOut(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//PB0 SDA 推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/**
* @brief 配置为输出状态
* @param 写数据
* @retval 应答
*/
uint8_t SHT10_WriteByte(uint8_t value)
{
uint8_t i,error=0;
//SDA输出
SHT10_SDAOut();
for( i = 0x80 ; i>0 ; i/=2)
{
if ( i & value)
SDA_H();
else
SDA_L();
SHT10_Delay();
SCK_H();
SHT10_Delay();
SCK_L();
SHT10_Delay();
}
//SDA输入
SHT10_SDAIn();
SCK_H();
error = SDA_R(); //读应答位
SCK_L();
return error;
}
/**
* @brief 读数据
* @param 应答
* @retval 返回数据
*/
uint8_t SHT10_ReadByte(uint8_t Ack)
{
uint8_t i,val=0;
//输入状态
SHT10_SDAIn();
for (i=0x80;i>0;i/=2)
{
SHT10_Delay();
SCK_H();
SHT10_Delay();
if (SDA_R())
val=(val | i); //读数据
SCK_L();
}
//输出状态
SHT10_SDAOut();
if(Ack)
SDA_L(); //应答为低电平
else
SDA_H();
SHT10_Delay();
SCK_H();
SHT10_Delay();
SCK_L();
SHT10_Delay();
return val;
}
/**
* @brief 启动
* @param 无
* @retval 无
*/
void SHT10_Start(void)
{
//SDA输出
SHT10_SDAOut();
SCK_L();
SHT10_Delay();
SCK_H();
SHT10_Delay();
SDA_L();
SHT10_Delay();
SCK_L();
SHT10_Delay();
SCK_H();
SHT10_Delay();
SDA_H();
SHT10_Delay();
SCK_L();
}
/**
* @brief 重新连接
* @param 无
* @retval 无
*/
void SHT10_ConReset(void)
{
uint8_t i;
//输出
SHT10_SDAOut();
SDA_H(); //输出高电平
SCK_L();
for(i = 0 ; i < 9 ; i++)
{
SCK_H();
SHT10_Delay();
SCK_L();
SHT10_Delay();
}
SHT10_Start();
}
/**
* @brief 软件重启
* @param 无
* @retval 无
*/
uint8_t SHT10_SoftReset(void)
{
uint8_t error=0;
SHT10_ConReset();
error += SHT10_WriteByte(RESET);
return error;
}
/**
* @brief 温度或湿度测量
* @param 温度或者湿度指针数据,校验值指针,模式
* @retval 错误
*/
uint8_t SHT10_Measure(uint16_t* pValue, uint8_t* pCheckSum, uint8_t mode)
{
uint8_t error=0;
uint8_t Value_H = 0;
uint8_t Value_L = 0;
//启动
SHT10_Start();
switch(mode)
{
case TEMP:
error += SHT10_WriteByte(MEASURE_TEMP);
break;
case HUMI:
error += SHT10_WriteByte(MEASURE_HUMI);
break;
default:
break;
}
//SDA读状态
SHT10_SDAIn();
//等待转换完成,代码有待优化
while(SDA_R())
{
;
}
Value_H = SHT10_ReadByte(ACK); //读高位
Value_L = SHT10_ReadByte(ACK); //读低位
*pCheckSum = SHT10_ReadByte(noACK); //读校验结果
//返回结果
*pValue = (Value_H << 8) | Value_L;
return error;
}
/**
* @brief 计算温度和湿度数据
* @param 温度数据 湿度数据 温度结果 湿度结果
* @retval 无
*/
void SHT10_Cal(uint16_t Temp,uint16_t Hum, float* pTempValue,float* pHumValue)
{
const float d1 = -40.1;
const float d2 = 0.01;
float Temp_C;
//温度结果,换算
Temp_C = d1 + d2 * Temp;
const float C1 = -2.0468;
const float C2 = +0.0367;
const float C3 = -0.0000015955;
const float T1 = +0.01;
const float T2 = +0.00008;
//湿度线性值
float RH_Lin;
//湿度真实值
float RH_True;
//RH线性结果
RH_Lin = C1 + C2 * Hum + C3 * Hum *Hum;
RH_True = (Temp_C - 25) * (T1 + T2 * Hum) + RH_Lin;
//限定范围
if( RH_True > 100 ) RH_True = 100;
if( RH_True < 0.01) RH_True = 0.01;
*pTempValue = Temp_C;
*pHumValue = RH_True;
}
/**
* @brief 延时函数
* @param 无
* @retval 无
*/
void SHT10_Delay(void)
{
//延时函数,i有待修改
for(uint16_t i = 500 ; i > 0 ; i--)
{
;
}
}
|