OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3002|回复: 7

sht10的驱动程序,寄存器版本的

[复制链接]

84

主题

347

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2008
金钱
2008
注册时间
2014-7-1
在线时间
189 小时
发表于 2016-7-3 13:58:34 | 显示全部楼层 |阅读模式
网上找了下,大多库函数版本的,一直用寄存器版本的,就选篇改了下。分享出来大家可以参考下。头文件:

[mw_shl_code=c,true]#ifndef _sht10_h_
#define _sht10_h_
//PC4时钟引脚
//PC5信号引脚

//初始化传感器连接端口
void sht10_init(void);
//得到温湿度的值
void GetTemperatureHumidity(void);

#define UpdataTimeSht10                        2        //温湿度传感器跟新时间   

#endif[/mw_shl_code]

.c文件[mw_shl_code=c,true]#include "sht10.h"
#include "delay.h"
#include "uart.h"

#define noACK 0                                                 //用于判断是否结束SHT10通信
#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
#define SCLL GPIOC->ODR&=~(1<<4)                //时钟线输出低电平
#define SCLH GPIOC->ODR|=1<<4                                //时钟线输出高电平
#define SDAL GPIOC->ODR&=~(1<<5)                //数据线输出低电平
#define SDAH GPIOC->ODR|=1<<5                                //数据线输出高电平
#define ReadState() {GPIOC->CRL&=0xFF0FFFFF; GPIOC->CRL|=0x00800000; GPIOC->ODR&=~(1<<5);}//数据线改为读
#define WriteState(){GPIOC->CRL&=0xFF0FFFFF; GPIOC->CRL|=0x00300000;}                                                                                         //数据线改为写
#define DATA() (GPIOC->IDR>>5)&1                //读出数据线数据
enum{TEMP,HUMI};                                                                                //温度和湿度
u16 Temperature=0,Humidity=0;
u8 t[2];                                                                                                                //读取2个字节,用于保存温度或者湿度



//启动输出
void TransStart(void);
//通信复位
void ConnectionReset(void);
//读取温度或者湿度
char ReadByte(unsigned char ack);
//从高位开始发送
char WriteByte(unsigned char value);
char Measure(unsigned char *pCheckSum,unsigned char mode);

//初始化传感器连接端口
void sht10_init(void)
{
        RCC->APB2ENR |=1<<4;//使能端口PORTC口时钟
        
        GPIOC->CRL &=0xFF00FFFF;
        GPIOC->CRL |=0x00330000;//PORTC4、5推挽输出
        GPIOC->ODR &=~(1<<4);                //GPIOC4输出0
        GPIOC->ODR &=~(1<<5);                //GPIOC5输出0
        
        delay_ms(20);
        ConnectionReset();
        Temperature=0;
        Humidity=0;
}
//启动输出
//       _____         ________
// DATA:      |_______|
//           ___     ___
// SCK : ___|   |___|   |______
void TransStart(void)
{
         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(void)
{
         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;
}
  
//得到温湿度的值并显示
void GetTemperatureHumidity(void)
{
        unsigned char error,CheckSum;
        
        error=0;
        error+=Measure(&CheckSum,TEMP);
        if(error!=0)
        {
                ConnectionReset();
                return;
        }
        else
        {
                float tem;
                tem=((t[0]<<8)+t[1])*0.1-400.0;//计算温度值
                Temperature=tem;
                send_uart1(0x5A);                                                        //显示温度值
                send_uart1(0xA5);//起始
                send_uart1(0x05);//数据长度
                send_uart1(0x82);//指令
                send_uart1(0x02);
                send_uart1(0x70);//地址
                send_uart1((Temperature/256));
                send_uart1((Temperature%256));
        }
        error=0;
        error+=Measure(&CheckSum,HUMI);
        if(error!=0)
        {
                ConnectionReset();
                return;
        }
        else
        {
                double hum=(t[0]<<8)+t[1];
                hum=hum*(hum*(-0.000028))+hum*0.405-40;
                Humidity=hum;                                                        //计算温度值
                send_uart1(0x5A);                                        //显示湿度值
                send_uart1(0xA5);                                        //起始
                send_uart1(0x05);                                        //数据长度
                send_uart1(0x82);                                        //指令
                send_uart1(0x02);
                send_uart1(0x72);                                        //地址
                send_uart1((Humidity/256));
                send_uart1((Humidity%256));
        }               
}
[/mw_shl_code]

做一个相信自己的人
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

23

主题

73

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
284
金钱
284
注册时间
2013-8-27
在线时间
37 小时
发表于 2016-11-5 17:17:29 | 显示全部楼层

楼主的 代码 灌进去 试过没有。。结果准不准,我这边测试的结果都不是很准,差的有点离谱
回复 支持 反对

使用道具 举报

84

主题

347

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2008
金钱
2008
注册时间
2014-7-1
在线时间
189 小时
 楼主| 发表于 2016-11-7 09:10:24 | 显示全部楼层
kevin9101 发表于 2016-11-5 17:17
楼主的 代码 灌进去 试过没有。。结果准不准,我这边测试的结果都不是很准,差的有点离谱

是值偏高吗?我的也是,温度高个1度左右,自己修正下就好
做一个相信自己的人
回复 支持 反对

使用道具 举报

23

主题

73

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
284
金钱
284
注册时间
2013-8-27
在线时间
37 小时
发表于 2016-11-7 09:23:24 | 显示全部楼层
shenqihao 发表于 2016-11-7 09:10
是值偏高吗?我的也是,温度高个1度左右,自己修正下就好

湿度 你那边测试怎么样,温度是有点高,。。
回复 支持 反对

使用道具 举报

23

主题

73

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
284
金钱
284
注册时间
2013-8-27
在线时间
37 小时
发表于 2016-11-7 09:30:03 | 显示全部楼层
这个测试结果  是带小数的么???
QQ图片20161107092905.png
回复 支持 反对

使用道具 举报

84

主题

347

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2008
金钱
2008
注册时间
2014-7-1
在线时间
189 小时
 楼主| 发表于 2016-11-7 15:12:17 | 显示全部楼层
kevin9101 发表于 2016-11-7 09:30
这个测试结果  是带小数的么???

是带小数的,0x0122是290,就是29.0度,0x024A是586,586*(586*-0.000028)+586*0.405-40=-9.615+237.33-40=18.7%,参考的这个:
http://www.doc88.com/p-915990136676.html
做一个相信自己的人
回复 支持 反对

使用道具 举报

23

主题

73

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
284
金钱
284
注册时间
2013-8-27
在线时间
37 小时
发表于 2016-11-7 16:13:28 | 显示全部楼层
en ,谢谢回复,另外 你测试的湿度准不,我的差了近9个点,
回复 支持 反对

使用道具 举报

84

主题

347

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2008
金钱
2008
注册时间
2014-7-1
在线时间
189 小时
 楼主| 发表于 2016-11-9 09:33:01 | 显示全部楼层
kevin9101 发表于 2016-11-7 16:13
en ,谢谢回复,另外 你测试的湿度准不,我的差了近9个点,

差9个倒是有可能,我这边几个测试度的仪器,相差都好几个
做一个相信自己的人
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-25 00:10

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表