• 永兴集团

    产品
    永兴集团云 — 物联网云平台 零编程,组态拖拽即可实现远程监控。同时支持私有部署,拥有属于自己的软硬件一体化方案
    200
    +
    私有云项目
    数据本地化
    业务个性化
    10
    +
    万 公有云注册用户
    80%公有云功能免费
    付费VIP享自定义品牌服务
    永兴集团云官网
    永兴集团智造 — ODM/EMS 依托自动化、智能化、柔性化、透明化的智能工厂,
    提供代研、代料、代工一站式OEM/ODM服务
    永兴集团智造官网
    永兴集团智能 — 解决方案 打包提供云、管、边、端整体解决方案
    从问题诊断、方案设计,到实施落地、系统运维
    永兴集团智能官网
    新闻资讯
    DHT21/am2301使用范例 AT89S52或 STC89C52RC
    2010-11-10


    分别有51的C和汇编两种例程,编译软件 Keil   注意:本例程仅供参考,请根据实际情况自行编写

    温湿度传感器接口图片

    am2301电路图参考

    [code="PLAIN"]
    ;*********************************************;
    ; DHT21使用范例
    ;单片机 : AT89S52或 STC89C52RC
    ;功能 ; 串口发送温湿度数据 波特率 9600
    ;公司 ; 广州奥松电子
    ;*********************************************;

    ;--------------------
    ;----变量定义区------
    ;--------------------
    FLAG EQU 30H
    U8comdata EQU 31H
    U8T_data_H EQU 32H
    U8T_data_L EQU 33H
    U8RH_data_H EQU 34H
    U8RH_data_L EQU 35H
    U8checkdata EQU 36H
    U8temp EQU 37H
    temp EQU 38H
    ;--------------------
    ;--------------------
    ;--------------------
    org 0000h
    AJMP START
    org 0023h
    AJMP SET_INT
    START:
    MOV P0,#0FFH
    MOV TMOD,#20H ;T1工作方式2
    MOV TH1,#0FDH ;串口波特率为9600
    MOV SCON,#50H ;串口工作于方式1并允许接受
    SETB TR1 ;启动T1
    SETB ES ;允许串口中断
    SETB EA ;允许全部外设中断
    MAIN:

    ;---------------------------
    ;-----调用湿度读取子程序----
    ;---------------------------
    LCALL RH
    ;---------------------------
    ;------串口发送程序 --------
    ;---------------------------
    TT:
    MOV A,U8RH_data_H
    LCALL TX_DATA
    MOV A,U8RH_data_L
    LCALL TX_DATA
    MOV A,U8T_data_H
    LCALL TX_DATA
    MOV A,U8T_data_L
    LCALL TX_DATA
    MOV A,U8checkdata
    LCALL TX_DATA

    //延时两秒
    LCALL Delay_2S

    LJMP MAIN


    ;--------------------------------
    ;-----湿度读取子程序 ------------
    ;--------------------------------
    ;----以下变量均为全局变量--------
    ;----温度高8位== U8T_data_H------
    ;----温度低8位== U8T_data_L------
    ;----湿度高8位== U8RH_data_H-----
    ;----湿度低8位== U8RH_data_L-----
    ;----校验 8位 == U8checkdata-----
    ;----调用相关子程序如下----------
    ;---- Read,Delay_10us , Delay
    ;--------------------------------
    RH:
    ;主机拉低总线,延时500us
    CLR P2.0
    MOV A,#1
    LCALL Delay
    SETB P2.0
    ;延时40us
    LCALL Delay_10us
    LCALL Delay_10us
    LCALL Delay_10us
    LCALL Delay_10us
    ;检测从机是否响应,无响应则跳出
    JB P2.0,RH_END
    MOV FLAG,#0
    LOOP1:
    INC FLAG
    MOV A,FLAG
    JB P2.0,LOOP1_END ;为高电平则跳出
    CJNE A,#0,LOOP1
    LJMP RH_END
    LOOP1_END:
    MOV FLAG,#0
    LOOP2:
    INC FLAG
    MOV A,FLAG
    JNB P2.0,LOOP2_END ;为低电平则跳出
    CJNE A,#0,LOOP2
    LJMP RH_END
    LOOP2_END:
    ;进入数据接收阶段
    LCALL Read
    MOV U8RH_data_H,U8comdata;
    LCALL Read
    MOV U8RH_data_L,U8comdata;
    LCALL Read
    MOV U8T_data_H,U8comdata;
    LCALL Read
    MOV U8T_data_L,U8comdata;
    LCALL Read
    MOV U8checkdata,U8comdata;
    SETB P2.0
    ;----------------------------------------------------------------------------
    ;----注意:本程序没有加校验程序 如果用户需要校验请安以下说明编写校验程序-----
    ;----------------------------------------------------------------------------
    ; 数据传送正确时校验和U8checkdata的值等于
    ; "8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据"所得结果的末8位
    ;-----------------------------------------------------------------------------
    ;-----------------------------------------------------------------------------
    ;-----------------------------------------------------------------------------

    RH_END:
    RET
    ;--------------------------------
    ;---------读数子程序-------------
    ;--------------------------------
    Read:
    MOV temp,#8
    MOV U8comdata,#0
    LOOP_COM:
    ;判断低电平是否结束
    MOV FLAG,#0
    LOOP3:
    INC FLAG
    MOV A,FLAG
    JB P2.0,LOOP3_END ;为高电平则跳出
    CJNE A,#0,LOOP3
    LJMP COM_END
    LOOP3_END:
    ;----------------------
    ;CLR P2.1
    ;SETB P2.1
    ;----------------------
    LCALL Delay_10us
    LCALL Delay_10us
    LCALL Delay_10us
    ;----------------------
    ;CLR P2.1
    ;SETB P2.1
    ;----------------------
    MOV U8temp,#0
    JNB P2.0,HIGH_END
    MOV U8temp,#1
    HIGH_END:

    MOV FLAG,#0
    LOOP4:
    INC FLAG
    MOV A,FLAG
    JNB P2.0,LOOP4_END ;为低电平则跳出
    CJNE A,#0,LOOP4
    LJMP COM_END
    LOOP4_END:
    MOV A,FLAG
    CJNE A,#0,NO_FLAG
    LJMP COM_END
    NO_FLAG:
    MOV A,U8comdata
    RL A
    ORL A,U8temp
    MOV U8comdata,A
    ;判断高电平是否结束
    DJNZ temp,LOOP_COM
    COM_END:
    RET
    ;--------------------------------
    ;------延时函数 -----------------
    ;--------------------------------
    Delay: MOV R4,A ;2.5ms
    D1: MOV R5,#0FFH
    DJNZ R5,$
    DJNZ R4,D1
    RET
    ;--------------------------------
    ;------延时10us函数 -----------------
    ;--------------------------------
    Delay_10us: ;10us
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    RET
    ;--------------------------------
    ;------延时2S函数 -----------------
    ;--------------------------------
    Delay_2S:
    MOV A,#250
    LCALL Delay
    MOV A,#250
    LCALL Delay
    MOV A,#250
    LCALL Delay
    MOV A,#250
    LCALL Delay
    MOV A,#250
    LCALL Delay
    MOV A,#250
    LCALL Delay
    MOV A,#250
    LCALL Delay
    MOV A,#250
    LCALL Delay
    RET
    ;--------------------------------
    ;------串口数据发送函数 ---------
    ;--------------------------------
    TX_DATA:
    CLR ES ;禁止串口中断
    MOV SBUF,A
    JNB TI,$
    CLR TI ;将同一数据发送到串口
    SETB ES ;允许串口中断
    RET
    ;--------------------------------
    ;------串口中断函数 -------------
    ;--------------------------------
    SET_INT:
    CLR ES ;禁止串口中断
    JNB RI,$
    CLR RI
    MOV A,SBUF ;接受串口数据
    MOV P0,A ;将串口数据送往P0
    MOV SBUF,A
    JNB TI,$
    CLR TI ;将同一数据发送到串口
    SETB ES ;允许串口中断
    RETI
    END
    ;--------------------------------
    ;----------结束------------------
    ;--------------------------------
    [/code]

    [code="CSHARP"]
    //****************************************************************//
    // DHT21使用范例
    //单片机 : AT89S52 或 STC89C52RC
    // 功能 :串口发送温湿度数据 波特率 9600
    // 公司 :奥松电子
    //****************************************************************//

    #include <reg51.h>
    #include <intrins.h>
    //
    typedef unsigned char U8; /* defined for unsigned 8-bits integer variable 无符号8位整型变量 */
    typedef signed char S8; /* defined for signed 8-bits integer variable 有符号8位整型变量 */
    typedef unsigned int U16; /* defined for unsigned 16-bits integer variable 无符号16位整型变量 */
    typedef signed int S16; /* defined for signed 16-bits integer variable 有符号16位整型变量 */
    typedef unsigned long U32; /* defined for unsigned 32-bits integer variable 无符号32位整型变量 */
    typedef signed long S32; /* defined for signed 32-bits integer variable 有符号32位整型变量 */
    typedef float F32; /* single precision floating point variable (32bits) 单精度浮点数(32位长度) */
    typedef double F64; /* double precision floating point variable (64bits) 双精度浮点数(64位长度) */
    //
    #define uchar unsigned char
    #define uint unsigned int
    #define Data_0_time 4

    //----------------------------------------------//
    //----------------IO口定义区--------------------//
    //----------------------------------------------//
    sbit P2_0 = P2^0 ;
    sbit P2_1 = P2^1 ;
    sbit P2_2 = P2^2 ;
    sbit P2_3 = P2^3 ;
    //----------------------------------------------//
    //----------------定义区--------------------//
    //----------------------------------------------//
    U8 U8FLAG,k;
    U8 U8count,U8temp;
    U8 U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;
    U8 U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;
    U8 U8comdata;
    U8 outdata[5]; //定义发送的字节数
    U8 indata[5];
    U8 count, count_r=0;
    U8 str[5]={"RS232"};
    U16 U16temp1,U16temp2;
    SendData(U8 *a)
    {
    outdata[0] = a[0];
    outdata[1] = a[1];
    outdata[2] = a[2];
    outdata[3] = a[3];
    outdata[4] = a[4];
    count = 1;
    SBUF=outdata[0];
    }

    void Delay(U16 j)
    { U8 i;
    for(;j>0;j--)
    {
    for(i=0;i<27;i++);

    }
    }
    void Delay_10us(void)
    {
    U8 i;
    i--;
    i--;
    i--;
    i--;
    i--;
    i--;
    }
    void COM(void)
    {

    U8 i;
    for(i=0;i<8;i++)
    {

    U8FLAG=2;
    while((!P2_0)&&U8FLAG++);
    Delay_10us();
    Delay_10us();
    Delay_10us();
    U8temp=0;
    if(P2_0)U8temp=1;
    U8FLAG=2;
    while((P2_0)&&U8FLAG++);
    //超时则跳出for循环
    if(U8FLAG==1)break;
    //判断数据位是0还是1

    // 如果高电平高过预定0高电平值则数据位为 1

    U8comdata<<=1;
    U8comdata|=U8temp; //0
    }//rof

    }

    //--------------------------------
    //-----湿度读取子程序 ------------
    //--------------------------------
    //----以下变量均为全局变量--------
    //----温度高8位== U8T_data_H------
    //----温度低8位== U8T_data_L------
    //----湿度高8位== U8RH_data_H-----
    //----湿度低8位== U8RH_data_L-----
    //----校验 8位 == U8checkdata-----
    //----调用相关子程序如下----------
    //---- Delay();, Delay_10us();,COM();
    //--------------------------------

    void RH(void)
    {
    //主机拉低 1-5ms
    P2_0=0;
    Delay(5);
    P2_0=1;
    //总线由上拉电阻拉高 主机延时40us
    Delay_10us();
    Delay_10us();
    Delay_10us();
    Delay_10us();
    //主机设为输入 判断从机响应信号
    P2_0=1;
    //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行
    if(!P2_0) //T !
    {
    U8FLAG=2;
    //判断从机是否发出 80us 的低电平响应信号是否结束
    while((!P2_0)&&U8FLAG++);
    U8FLAG=2;
    //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
    while((P2_0)&&U8FLAG++);
    //数据接收状态
    COM();
    U8RH_data_H_temp=U8comdata;
    COM();
    U8RH_data_L_temp=U8comdata;
    COM();
    U8T_data_H_temp=U8comdata;
    COM();
    U8T_data_L_temp=U8comdata;
    COM();
    U8checkdata_temp=U8comdata;
    P2_0=1;
    //数据校验
    U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
    if(U8temp==U8checkdata_temp)
    if(1)
    {
    U8RH_data_H=U8RH_data_H_temp;
    U8RH_data_L=U8RH_data_L_temp;
    U8T_data_H=U8T_data_H_temp;
    U8T_data_L=U8T_data_L_temp;
    U8checkdata=U8checkdata_temp;
    }//fi
    }//fi

    }
    //----------------------
    //P2_1=0 ; //T
    //P2_1=1 ; //T
    //----------------------

    //----------------------
    //P2_1=0 ; //T
    //P2_1=1 ; //T
    //----------------------
    //----------------------------------------------
    //main()功能描述: AT89C51 11.0592MHz 串口发
    //送温湿度数据,波特率 9600
    //----------------------------------------------
    void main()
    {
    U8 i,j;

    //uchar str[6]={"RS232"};
    /* 系统初始化 */
    TMOD = 0x20; //定时器T1使用工作方式2
    TH1 = 253; // 设置初值
    TL1 = 253;
    TR1 = 1; // 开始计时
    SCON = 0x50; //工作方式1,波特率9600bps,允许接收
    ES = 1;
    EA = 1; // 打开所以中断
    TI = 0;
    RI = 0;
    SendData(str) ; //发送到串口
    Delay(1); //延时100US(12M晶振)
    while(1)
    {

    //------------------------
    //调用温湿度读取子程序
    RH();
    //串口显示程序
    //--------------------------

    str[0]=U8RH_data_H;
    str[1]=U8RH_data_L;
    str[2]=U8T_data_H;
    str[3]=U8T_data_L;
    str[4]=U8checkdata;
    SendData(str) ; //发送到串口
    //读取模块数据周期不易小于 2S
    Delay(20000);
    }//elihw

    }// main

    void RSINTR() interrupt 4 using 2
    {
    U8 InPut3;
    if(TI==1) //发送中断
    {
    TI=0;
    if(count!=5) //发送完5位数据
    {
    SBUF= outdata[count];
    count++;
    }
    }

    if(RI==1) //接收中断
    {
    InPut3=SBUF;
    indata[count_r]=InPut3;
    count_r++;
    RI=0;
    if (count_r==5)//接收完4位数据
    {
    //数据接收完毕处理。
    count_r=0;
    str[0]=indata[0];
    str[1]=indata[1];
    str[2]=indata[2];
    str[3]=indata[3];
    str[4]=indata[4];
    P0=0;
    }
    }
    }
    [/code]

    工作日每天: 14:00~17:00
    抖音、天猫 "永兴集团旗舰店"

    关注永兴集团微信公众号
    了解更多信息

    永兴集团