SHT11温湿度传感器AVR单片机程序

发布者:脑力激荡最新更新时间:2017-12-15 来源: eefocus关键字:SHT11  温湿度传感器  AVR单片机 手机看文章 扫描二维码
随时随地手机看文章

#include "shtxx.h" 

void shtxx_init(void) 

    shtxx_temp = shtxx_humi = 0; 
    SHTXX_SCK_LOW(); 
    SHTXX_DAT_1();

    shtxx_reconnect(); 


void shtxx_reconnect(void) 

    SHTXX_DAT_1(); 
    SHTXX_SCK_LOW(); 
    for(uint8 i=0; i<9; i++) 
    { 
        SHTXX_SCK_HIGH(); SHTXX_SCK_LOW(); 
    } 
    SHTXX_START(); 


uint8 shtxx_SOFtrst(void) 

    uint8 error = 0; 
    shtxx_reconnect(); 
    error += shtxx_write_byte(SHTXX_SOFT_RST); 
    return error; 


//写命令函数 
//参数:命令类型 
//返回:0成功,1失败 
uint8 shtxx_write_byte(uint8 cmd) 

    uint8 ack; 
    for (uint8 i=8; i>0; i--) 
    { 
        if (BITCHK(cmd, (i-1)))        //trans ’1’  
        { 
            SHTXX_DAT_1();     
            SHTXX_SCK_HIGH(); SHTXX_SCK_LOW(); 
        }     
        else                         //trans ’0’ 
        { 
            SHTXX_DAT_0();                          
            SHTXX_SCK_HIGH(); SHTXX_SCK_LOW(); 
        } 
    } 
    //SHTxx 会以下述方式表示已正确地接收到指令: 
    //在第8 个SCK 时钟的下降沿之后,将DATA 下拉为低电平(ACK 位)。 
    //在第9 个SCK 时钟的下降沿之后,释放DATA(恢复高电平)。 
    BITCLR(SHTXX_DAT_DDR, SHTXX_DAT_BIT); 
    SHTXX_SCK_HIGH(); 
    ack = BITCHK(SHTXX_DAT_PIN, SHTXX_DAT_BIT); 
    SHTXX_SCK_LOW(); 
    return ack; 


uint8 shtxx_read_byte(uint8 dat_crc) 

    uint8 dat8 = 0; 
    for (uint8 i=8; i>0; i--) 
    { 
        BITCLR(SHTXX_DAT_DDR, SHTXX_DAT_BIT); 
        c4680504cSHTXX_SCK_HIGH(); 
        if (BITCHK(SHTXX_DAT_PIN, SHTXX_DAT_BIT))  
            BITSET(dat8, (i-1)); 
        SHTXX_SCK_LOW(); 
    } 
     
    if (dat_crc) 
    { 
        SHTXX_DAT_0(); 
        SHTXX_SCK_HIGH(); SHTXX_SCK_LOW(); 
    } 
    else 
    { 
        SHTXX_DAT_1(); 
        SHTXX_SCK_HIGH(); SHTXX_SCK_LOW(); 
    } 
    SHTXX_DAT_1();     
     
    return dat8; 


int8 shtxx_measure(uint8 mode) 

    uint8 error = 0; 
     
    SHTXX_START();     
    switch (mode) 
    { 
        case SHTXX_MODE_TEMP: 
            error = shtxx_write_byte(SHTXX_CMD_TEMPTURE); 
            for(uint16 i=0; i<65535; i++) 
            {     
                _delay_us(5); 
                BITCLR(SHTXX_DAT_DDR, SHTXX_DAT_BIT);  
                if (!(BITCHK(SHTXX_DAT_PIN, SHTXX_DAT_BIT))) break; 
            } 
            BITCLR(SHTXX_DAT_DDR, SHTXX_DAT_BIT);  
            if (BITCHK(SHTXX_DAT_PIN, SHTXX_DAT_BIT)) error += 1; 
                         
            shtxx_temp = shtxx_read_byte(1); 
            shtxx_temp = (shtxx_temp << 8) + shtxx_read_byte(1); 
            shtxx_crc = shtxx_read_byte(0);     
            break; 
        case SHTXX_MODE_HUMI: 
            error = shtxx_write_byte(SHTXX_CMD_HUMIDITY); 
            for(uint16 i=0; i<65535; i++) 
            {     
                _delay_us(5); 
                BITCLR(SHTXX_DAT_DDR, SHTXX_DAT_BIT);  
                if (!(BITCHK(SHTXX_DAT_PIN, SHTXX_DAT_BIT))) break; 
            } 
            BITCLR(SHTXX_DAT_DDR, SHTXX_DAT_BIT);  
            if (BITCHK(SHTXX_DAT_PIN, SHTXX_DAT_BIT)) error += 1; 
            shtxx_humi = shtxx_read_byte(1); 
            shtxx_humi = (shtxx_humi<<8) + shtxx_read_byte(1);             
            shtxx_crc = shtxx_read_byte(0);         
            break; 
        default: 
            break; 
    } 

    return error; 


void shtxx_calc(void) 

    uint32 rh_line = 0; 
    //所有湿度常量放大10000000 
    const uint32 C1 = 40000000; 
    const uint32 C2 = 405000; 
    const uint32 C3 = 28; 
    const uint32 T1 = 100000; 
    const uint32 T2 = 8000;     
     
    //温度常量放大100 
    t_c = shtxx_temp - 4000;    //结果除以100 
     
    rh_line = C2*shtxx_humi - C3*shtxx_humi*shtxx_humi - C1; 
    rh_true = (t_c/100-25)*(T1+T2*shtxx_humi) + rh_line; 
     
    if (rh_true>1000000000) rh_true = 1000000000; //cut if the value is outside of 
    if (rh_true<1000000) rh_true = 1000000; //the physICal possible range 


void hex_bcd(uint32 hex32) 

    MEMSet(bcd32, ’\0’, 10); 
    while (hex32 >= 1000000000)        // 
    { 
        bcd32[9]++; 
        hex32 = hex32 - 1000000000; 
    }       
            
    while (hex32 >= 100000000)        // 
    { 
        bcd32[8]++; 
        hex32 = hex32 - 100000000; 
    } 
     
    while (hex32 >= 10000000)        // 
    { 
        bcd32[7]++; 
        hex32 = hex32 - 10000000; 
    } 
     
    while (hex32 >= 1000000)        // 
    { 
        bcd32[6]++; 
        hex32 = hex32 - 1000000; 
    } 
     
    while (hex32 >= 100000)            // 
    { 
        bcd32[5]++; 
        hex32 = hex32 - 100000; 
    } 
     
    while (hex32 >= 10000)            // 
    { 
        bcd32[4]++; 
        hex32 = hex32 - 10000; 
    }     
     
    while (hex32 >= 1000)            // 
    { 
        bcd32[3]++; 
        hex32 = hex32 - 1000; 
    }     
     
    while (hex32 >= 100)            // 
    { 
        bcd32[2]++; 
        hex32 = hex32 - 100; 
    }     
     
    while (hex32 >= 10)                // 
    { 
        bcd32[1]++; 
        hex32 = hex32 - 10; 
    } 
     
    bcd32[0] = hex32; 


void shtxx_disp(void) 

    if (!shtxx_measure(SHTXX_MODE_TEMP)) 
    { 
        shtxx_calc(); 
        hex_bcd(t_c); 
        LCD_print_str(2, 1, "温度: "); 
         
        if(bcd32[4] != 0) 
            lcd_write_dat(bcd32[4]+0x30); 
        lcd_write_dat(bcd32[3]+0x30); 
        lcd_write_dat(bcd32[2]+0x30); 
        lcd_write_dat(’.’); 
        lcd_write_dat(bcd32[1]+0x30); 
        lcd_write_dat(bcd32[0]+0x30); 
    } 
    if (!shtxx_measure(SHTXX_MODE_HUMI)) 
    { 
        shtxx_calc(); 
        hex_bcd(rh_true); 
        lcd_print_str(3, 1, "湿度: "); 
         
        if(bcd32[9] != 0) 
            lcd_write_dat(bcd32[9]+0x30); 
        lcd_write_dat(bcd32[8]+0x30); 
        lcd_write_dat(bcd32[7]+0x30); 
        lcd_write_dat(’.’); 
        lcd_write_dat(bcd32[6]+0x30); 
        lcd_write_dat(bcd32[5]+0x30); 
    } 
}


 

shtxx.H

#ifndef _SHTXX_H
#define _SHTXX_H
#include "config.h"

#define SHTXX_SCK_DDR  DDRC
#define SHTXX_SCK_PORT  PORTC
#define SHTXX_SCK_BIT  (0)

#define SHTXX_DAT_DDR  DDRC
#define SHTXX_DAT_PORT  PORTC
#define SHTXX_DAT_PIN  PINC
#define SHTXX_DAT_BIT  (1)

#define SHTXX_SCK_HIGH() {BITSET(SHTXX_SCK_DDR, SHTXX_SCK_BIT); BITSET(SHTXX_SCK_PORT, SHTXX_SCK_BIT); _delay_us(10);}
#define SHTXX_SCK_LOW()  {BITSET(SHTXX_SCK_DDR, SHTXX_SCK_BIT); BITCLR(SHTXX_SCK_PORT, SHTXX_SCK_BIT); _delay_us(10);}

#define SHTXX_DAT_1()  {BITSET(SHTXX_DAT_DDR, SHTXX_DAT_BIT); _delay_us(1); BITSET(SHTXX_DAT_PORT, SHTXX_DAT_BIT); _delay_us(5);}
#define SHTXX_DAT_0()  {BITSET(SHTXX_DAT_DDR, SHTXX_DAT_BIT); _delay_us(1); BITCLR(SHTXX_DAT_PORT, SHTXX_DAT_BIT); _delay_us(5);}

#define SHTXX_START()  {SHTXX_DAT_1(); SHTXX_SCK_LOW(); SHTXX_SCK_HIGH(); SHTXX_DAT_0(); SHTXX_SCK_LOW(); _delay_us(2); SHTXX_SCK_HIGH(); SHTXX_DAT_1();  SHTXX_SCK_LOW();}
#define SHTXX_ACK()   {BITCLR(SHTXX_DAT_DDR, SHTXX_DAT_BIT); if(!(BITCHK(SHTXX_DAT_PIN, SHTXX_DAT_BIT)));}
#define SHTXX_WAIT()  {BITCLR(SHTXX_DAT_DDR, SHTXX_DAT_BIT); while(BITCHK(SHTXX_DAT_PIN, SHTXX_DAT_BIT));}

#define SHTXX_CMD_TEMPTURE 0b00000011
#define SHTXX_CMD_HUMIDITY 0b00000101
#define SHTXX_RD_STATE_REG 0b00000111
#define SHTXX_WR_STATE_REG 0b00000110
#define SHTXX_SOFT_RST  0b00011110

#define SHTXX_MODE_TEMP  0x01
#define SHTXX_MODE_HUMI  0x02

uint16 shtxx_temp, shtxx_humi;
uint8 shtxx_crc;
uint32 t_c, rh_true;
uint8 bcd32[10];

void shtxx_init(void);
void shtxx_reconnect(void);
uint8 shtxx_write_byte(uint8 cmd);
uint8 shtxx_softrst(void);
uint8 shtxx_read_byte(uint8 dat_crc);

#endif


关键字:SHT11  温湿度传感器  AVR单片机 引用地址:SHT11温湿度传感器AVR单片机程序

上一篇:AVR定时器T1中断示例程序
下一篇:DS1302的AVR单片机C程序

推荐阅读最新更新时间:2024-03-16 15:49

基于AVR单片机的煤矿传感器设计
1 引言 由于近年来煤矿瓦斯事故频发,并且动则死伤矿工十余人甚至上百人。鉴于此,国家安全生产监督管理总局在《煤矿安全规程》中明确规定,“所有矿井必须安装矿井安全监控系统。”为了满足市场需要,煤矿监控系统的研发和生产呈越来越旺的趋势。其中,煤矿用传感器是直接面对矿井具体工作环境的最直接设备。传感器的工作性能、可靠性、可调节性与可升级性直接影响煤矿监控系统的正常运行。 迄今为止,我国的矿井瓦斯监测监控系统仍处于开发阶段,虽然很多产品已投放市场并正式运行,但大部分产品并没有最后定型。因此,对煤矿传感器的研究与开发更有利于其发展,并推动煤矿用其他检测控制装置的研究,使矿用产品越来越成熟。 2 现有传感器的设计 综观现有传感器,基本上都以单片
[单片机]
基于<font color='red'>AVR单片机</font>的煤矿<font color='red'>传感器</font>设计
AVR单片机T1中断定时1秒程序
#include iom16v.h #include macros.h #define uchar unsigned char #define uint unsigned int uchar num=0; #pragma interrupt_handler miao:9 #pragma data:code // T/C1中断入口 void miao(void) { if(num==100) {num=0;} else {num++;} TCNT1H=0X85;//重新装载T/C1的初值 TCNT1L=0XED; } void Time1Init(void) { TCCR1B=0X04;//
[单片机]
基于AVR单片机的自行车行车记录仪,软硬件协同
自行车行车记录仪包括主控板,打印机驱动板,霍尔传感器,12864液晶显示器,EPSON微型打点打印机这五部分。该记录仪能记录实时的行车速度,行车总里程,单次行车里程,以及历史最高行车速度,具备外部环境温度显示,总里程设置,行车信息打印等功能,是面向自行车爱好者的一个高精度,功能强大的行车记录仪。 功能上,在设计行车记录仪时,以Atmega64单片机为核心,AT24LC64 EEPROM,DS1302,12864液晶显示器,霍尔传感器等构成外围电路,行车记录仪的核心部件是霍尔传感器,在下面讲述原理的时候会进行详细的描述。显示部分由12864液晶来完成,该液晶控制简单,显示区域大,低功耗,适合电池供电,可以通过设计菜单,从而来实现记
[单片机]
基于<font color='red'>AVR单片机</font>的自行车行车记录仪,软硬件协同
AVR单片机GCC编程:定时器的基本操作
以下为定时器的查询工作方式,不会发生中断请求: #include avr/io.h int main(void) { //8位定时器时间计算 T=(256-初值) * 脉冲周期 int i; TCNT0 = 55; //设置初值 TCCR0 |= (1 CS01); //8分频 for (i = 0; i 10000; i++) { while(!(TIFR & TOV0)); //对T/C0溢出标志进行判断,溢出后自动清零,不发生中断. } } 以下工作方式,会发生溢出中断请求: #include avr/io.h #include avr/interrupt.h volatile unsigned int
[单片机]
什么是avr单片机
什么是avr单片机 1997年,由ATMEL公司挪威设计中心的A先生与V先生利用ATMEL公司的Flash新技术, 共同研发出RISC精简指令集的高速8位单片机,简称AVR。 单片机又称单片微控制器,它是把一个计算机系统集成到一个芯片上,概括的讲:一块芯片就成了一台计算机。单片机技术是计算机技术的一个分支,是简易机器人的核心元件。 AVR单片机的优点和参数 单片机已广泛地应用于军事、工业、家用电器、智能玩具、便携式智能仪表和机器人制作等领域,使产品功能、精度和质量大幅度提升,且电路简单,故障率低,可靠性高,成本低廉。单片机种类很多,在简易机器人制作和创新中,为什么选用AVR单片机呢? 一、简便易学,费用低廉 首先,
[模拟电子]
什么是<font color='red'>avr单片机</font>
如何让你的AVR单片机功耗超低
四年多前整过一次低功耗的,当时调试也是OK的,程序基本上是移植过来了。 这次重新改动一下,做了,本以为捣腾一天差不多了,结果又捣腾了两天。 硬件平台是使用9V的电池,系统稳压到5V,普通的稳压IC肯定不行的,必须是LDO型的IC。LDO选的是国产的BL8061,INPUT VOLTAGE是2-16V,OUTPUT CURRENT:250mA,典型的消耗是2uA,BL8060输入电压是1.5-14V,最大电流时200mA,功耗是1uA。稳压前后的电解电容1uF。因为板子做的是贴片的,贴片的手头现成的只有10V/22uF,偶加在稳压后,因为9V电池空载电压就接近10V了,稳压前偶弄了个普通的杂牌铝电解,结果第一晚就被这颗害死了。
[单片机]
如何让你的<font color='red'>AVR单片机</font>功耗超低
基于AVR单片机的125 kHz简易RFID阅读器设计
0 引言 无线射频识别(Radio Frequency Identification,RFID)是利用感应、电磁场或电磁波为传输手段,完成非接触式双向通信、获取相关数据的一种自动识别技术。该技术完成识别工作时无须人工干预,易于实现自动化且不易损坏,可识别高速运动物体并可同时识别多个射频卡,操作快捷方便,已经得到了广泛的应用。 目前存在的一些读卡器,都需要读卡芯片作为基站,成本较高。本文介绍了一种采用分立元件构成的125 kHz RFID阅读器,电路结构简单,成本极低,用于读取EM4100型ID卡。 1 RFID系统的分类 RFID系统的分类方法有很多,在通常应用中都是根据频率来分,根据不同的工作频率,可将
[单片机]
AVR单片机设计LED彩灯控制器
8个LED灯直接连接到Vcc 上,不需要限流电阻。本制作利用到同步定时器,及使用睡眠的方式节省电力。 如果你想改变LED接的管脚,请修改hardware.h文件。如果想修改LED的亮度,请修改globals.h 中的Timings 段定义。本设计外接了两个按钮,一个是选择工作模式,另一个是电源的开关。当你按下模式按钮1.5秒以上时,进入自动模式,会自动演示所有的预设模式。 实物图: 电路图:(点击可以放大) PCB图:(点击可以放大)
[单片机]
用<font color='red'>AVR单片机</font>设计LED彩灯控制器
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved