原创 stm32实现SHT温湿度传感器

2011-7-21 20:20 6713 9 12 分类: MCU/ 嵌入式

20110721201133001.gif

 

原理图如上图所示:其中PE9->GND,PE11->SCL,E13->SDA,E15->VDD

对温度传感器的理解:
1.不是标准的I2C总线结构。
2.先读取的是高位数据,比方说温度,采用14位,则先发过来的是高字节中的两位00,第14位,第13位,第12位,第11位,第10位,第9位,第8位,一直到第1位。
3.要注意结果的计算。

附件是完整的程序和对sht1x的说明。

程序:
#include<stm32f10x_lib.h>
#include "sys.h"
#include "delay.h"
#include "1602.h"

#define noACK 0 //用于判断是否结束SHT10通讯
#define ACK 1 //结束数据传输
        // r/w
#define STATUS_REG_W 0x06 // 0
#define STATUS_REG_R 0x07 // 1
#define MEASURE_TEMP 0x03 // 1
#define MEASURE_HUMI 0x05 // 1
#define RESET 0x1E        // 0

#define SCLL GPIOE->ODR&=~(1<<11)//时钟线输出低电平
#define SCLH GPIOE->ODR|=1<<11//时钟线输出低电平
#define SDAL GPIOE->ODR&=~(1<<13)//数据线输出低电平
#define SDAH GPIOE->ODR|=1<<13//数据线输出高电平

#define ReadState() {GPIOE->CRH&=0xFF0FFFFF; GPIOE->CRH|=0x00800000; GPIOE->ODR&=~(1<<13);}//数据线改为读
#define WriteState() {GPIOE->CRH&=0xFF0FFFFF; GPIOE->CRH|=0x00300000;}//数据线改为写

#define DATA() (GPIOE->IDR>>13)&1//读出数据线数据

enum{TEMP,HUMI};//温度和湿度

unsigned int Temperature,Humidity;
u8 t[2];//读取的两个字节,用于保存温度或湿度

void SHT_GPIO_Config(){//与传感器连接的引脚配置为推挽输出,用写1来作为电源,写0作为地
 RCC->APB2ENR|=1<<(2+4);
 GPIOE->CRH&=0x0F0F0F0F;
 GPIOE->CRH|=0x30303030;
 GPIOE->ODR&=0x00000001;
 GPIOE->ODR|=1<<15;
}

//启动传输
//       _____         ________
// DATA:      |_______|
//           ___     ___
// SCK : ___|   |___|   |______
void TransStart(){
 SDAH;
 SCLL;
 delay_us(1);
 SCLH;
 delay_us(1);
 SDAL;
 delay_us(1);
 SCLL;
 delay_us(1);
 SCLH;
 delay_us(1);
 SDAH;
 delay_us(1);
 SCLL;
 delay_us(1);
}

// 通讯复位: DATA-line=1 and at least 9 SCK cycles followed by transstart
//       _____________________________________________________         ________
// DATA:                                                      |_______|
//          _    _    _    _    _    _    _    _    _        ___     ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
void ConnectionReset(){
 unsigned char i;
 SDAH;
 SCLL;
 delay_us(1);
 for(i=0;i<9;i++){
  SCLH;
  delay_us(1);
  SCLL;
  delay_us(1);
 }
 TransStart();
}

char ReadByte(unsigned char ack){//读取温度或湿度
 unsigned char i,val=0;
 SDAH;
 ReadState();
 for(i=0x80;0<i;i/=2){//先读取的是高位
  SCLH;
  delay_us(1);
  if(DATA())
   val=(val|i);
  delay_us(1);
  SCLL;
  delay_us(1);
 }
 WriteState();
 if(ack==1)//发送确认
  SDAL;
 else//不确认
  SDAH;
 delay_us(1);
 SCLH;
 delay_us(1);
 SCLL; 
 delay_us(1);
 SDAH;
 return val;
}

char WriteByte(unsigned char value){//从高位开始发送
 unsigned char i,error=0;
 for(i=0x80;0<i;i/=2){
  if(i&value)
   SDAH;
  else
   SDAL;
  SCLH;
  delay_us(1);
  SCLL;
 }
 SDAH;//release DATA-line
 SCLH;//clk #9 for ack
 delay_us(1);
 ReadState();
 error=DATA();//DATA在第9个上升沿将被SHT10自动下拉为低电平
 WriteState();
 delay_us(1);
 SCLL;
 SDAH;//release DATA-line
 return error;
}

char Measure(unsigned char *pCheckSum,unsigned char mode){
 unsigned char error=0;
 TransStart();
 switch(mode){
  case TEMP:
   error+=WriteByte(MEASURE_TEMP);
   break;
  case HUMI:
   error+=WriteByte(MEASURE_HUMI);
   break;
  default:
   break;
 }
 ReadState();
 delay_us(320000);//320ms等待数据准备好
 if(DATA())// 或超时 (约2 sec.)
  error+=1; 
 WriteState();
 t[0]=ReadByte(ACK);
 t[1]=ReadByte(ACK);
 *pCheckSum=ReadByte(noACK);
 return error;
}

//温度暂时设定值为0-99,可以根据需要更改
void Display(u32 x){
// x=x%1000;
// WriteData(x/100+'0');
 WriteData((x%100)/10+'0');
 WriteData(x%10+'0');
}

int main(){
 unsigned char error,CheckSum;
 Stm32_Clock_Init(9);
 delay_init(72);
 L1602_GPIO_Init();//1602液晶显示器初始化
 L1602_Init();

 SHT_GPIO_Config();//温湿度传感器的引脚初始化
 delay_us(11000);
 ConnectionReset();
 while(1){
  WriteCmd(0x01);
  error=0;
  error+=Measure(&CheckSum,TEMP);
  if(error!=0){//如果出错,显示错误代码
   ConnectionReset();
   WriteData(error+'0');
   delay_us(500000);
   continue;
  }
  Temperature=(u32)(((t[0]<<8)+t[1])*0.01-40);//计算温度,这里只是实现了温度
  Display(Temperature);//显示温度
  delay_us(500000);//为了不显示太快引起闪烁,延时0.5s
 }
}

附件:zip.gifSHT.zip

文章评论3条评论)

登录后参与讨论

用户377235 2013-4-27 06:09

调试准确不,我用杜邦线把SHT10的片子引出来的,发现有问题。

用户1630203 2012-12-17 16:16

非常感谢楼主!!!

用户412046 2012-3-22 14:31

你好,我在网上看了一篇你写的关于湿温传感器sht用stm32实现的文章,我也正在做这方面的项目,有些问题想请教一下。 首先我想知道sht71输出的结果是什么格式的,有没有小数啊,有的话是几位小数? 其次我想知道sht的数据端口输出测量的数据是每8位就接收一次吗,还是输出一位就接收一位 这句程序Temperature=(u32)(((t[0]<<8)+t[1])*0.01-40);有点不太明白,这样的话好像就是每八位就接收一次啊
相关推荐阅读
Crystal_oscillator 2012-06-06 11:39
我的一些与研究生生涯的相关资料
如题。...
Crystal_oscillator 2012-06-02 19:42
EDA--IPCore的使用
很清晰地讲解了如何在EDA中使用IPCore,推荐在这里,如附件: ...
Crystal_oscillator 2012-05-21 14:12
c#与MySql连接
如附件:...
Crystal_oscillator 2012-04-01 20:41
关于搜索的一点思考
  现在的搜索引擎,仍然面对的一个现实就是:它依然找不到客户所需要的东西。   这里面有两个原因:   (1)现有的东西没有被归类,而是分散在浩如烟海的网络中,各种博客,微博等等。  ...
Crystal_oscillator 2012-04-01 12:00
有趣的加1电路
  在上一篇博客,我介绍了并行加法。在这里,我将带大家学习并行加一电路,并且,我们会发现结 论相当简单有趣。     我们知道对于一位加法电路,假设A,B是参与运算的两个位变量,C_1...
Crystal_oscillator 2012-03-21 17:53
【博客大赛】VHDL实现并行8位加法
  要实现8位加法,先要从1位开始。假设A,B,C_1分别为两个输入值和进位输入,S是和值,C为进位输出值,于是便有以下表达式:   S=A xor B xor C_1;   C=AB+BC_...
我要评论
3
9
关闭 站长推荐上一条 /2 下一条