当前位置:   article > 正文

dsp28335+dht11+matlab实时绘制温湿度(3种取数据方式)_dsp28335 dht11

dsp28335 dht11

1.dht11基础

1.1单线通信

设备(主机或从机)通过一个一个漏极开路或三态端口连接至该数据线,以允许设备在不发送数据时能够释放总线,而让其他设备使用总线。——GPBPUD=0——DSP使能上拉。

1.2数据位定义

一次传送40位数据,高位先出。数据格式:
在这里插入图片描述

1.3 数据时序图

在这里插入图片描述
关于电平时间的定义
在这里插入图片描述

2.外设的读取步骤

在这里插入图片描述

步骤1:等待

商店

		gpio40_init();
		EALLOW;
		DAT_DIR=0;//输入
		EDIS;
		for(i=0;i<2000;i++)	//等待稳定
				DELAY_US(1000);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

步骤2:起始信号

在这里插入图片描述

void DHT11_Rst(void)
{
	uchar i;
	EALLOW;
	DAT_DIR=1;//输出
	EDIS;
	DAT = 0;  //拉低DQ
	for(i=0;i<25;i++)	//18-30ms
			DELAY_US(1000);
	DAT = 1;
	DELAY_US(30);//主机拉高20~40us释放总线
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

步骤3:CHECK

在这里插入图片描述

Uint16 Dht11_Check(void){ //等待DHT11回应,返回1:未检测到DHT11,返回0:成功(IO接收)
	Uint16 retry=0;
	EALLOW;
	DAT_DIR=0;
	EDIS;//IO到输入状态
	//找DHT11发出的低电平
    while (DAT&&retry<100){//DHT11会拉低78~88us
        retry++;
        DELAY_US(1);
    }
    if(retry>=100)return 1; else retry=0;
    //找DHT11发出的高电平
    while (!DAT&&retry<100){//DHT11拉低后会再次拉高80~92us
        retry++;
        DELAY_US(1);
    }
    if(retry>=100)return 1;
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

总的DHT11初始化程序

Uint16 DHT11_Init (void){	//DHT11初始化
	DHT11_Rst();//DHT11端口复位,发出起始信号
	return Dht11_Check(); //等待DHT11回应
}

  • 1
  • 2
  • 3
  • 4
  • 5

步骤4:读数据

在这里插入图片描述
在这里插入图片描述

读Bit

法1:——延时检测高电平

uchar Dht11_ReadBit(void){ //从DHT11读取一个位 返回值:1/0
    uchar retry=0;
    while(DAT&&retry<100){//等待变为低电平(54us前边那段)
        retry++;
        DELAY_US(1);
    }
    retry=0;
    while(!DAT&&retry<100){//等待变高电平
        retry++;
        DELAY_US(1);
    }
    DELAY_US(40);//等待40us	//用于判断高低电平,即数据1或0
    if(DAT)return 1; else return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

法2:——判断高电平时间

uchar Dht11_ReadBit(void){ //从DHT11读取一个位 返回值:1/0
    uchar retry=0;
    while(DAT&&retry<100){//等待变为低电平(54us前边那段)
            retry++;
            DELAY_US(1);
        }
        retry=0;
    while(!DAT&&retry<60){//等待54us的低电平
        retry++;
        DELAY_US(1);
    }
    retry=0;
    while(DAT)
    {
        retry++;
        DELAY_US(1);
    }
    if(40<retry)return 1; else return 0;//高电平维持的时间跟手册有出入。
}

//***************************甚至你可以这样写*********************************//
uchar Dht11_ReadBit(void){ //从DHT11读取一个位 返回值:1/0
    uchar retry=0;
    while(DAT){//等待变为低电平
        }
    while(!DAT){//等待变高电平
    }
    while(DAT)
    {
        retry++;
        DELAY_US(1);
    }
    if(40<retry)return 1; else return 0;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
读湿度+温度字节

法1——用的是全局变量temp[4]

							dht11.h
extern char temp[4];
//***********************全局变量*******************//
                            dht11.c
#include "dht11.h"
char temp[4];
void DHT11_ReadData(void){ //读取一次数据//湿度值(十进制,范围:20%~90%) ,温度值(十进制,范围:0~50°),返回值:0,正常;1,失败
	uchar buf[5];
	uchar i;
	DHT11_Rst();//DHT11端口复位,发出起始信号
    if(Dht11_Check()==0){ //等待DHT11回应
        for(i=0;i<5;i++){//读取5位数据
            buf[i]=Dht11_ReadByte(); //读出数据
        }
        if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){	//数据校验
            temp[0]=buf[0]; //将湿度值放入指针1
            temp[1]=buf[1];
	        temp[2]=buf[2]; //将温度值放入指针2
	        temp[3]=buf[3];
        }
    }
}
 						main.c
				DHT11_ReadData();
				hum=temp[0]*1;
				tep=10*(temp[2]*1+0.1*temp[3]);
				int_char(hum,tep);
				UARTa_SendString(table);						
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

法2——用的是数组指针
char *s;
char a[ ] ;
前面说到 a代表字符串的首地址,而s 这个指针也保存字符串的地址(其实首地址),即第一个字符的地址,这个地址单元中的数据是一个字符,
可以 s = a
当然也可以这样:

    char  a [ ] = "hello";

    char *s =a;

    for(int i= 0; i < strlen(a) ; i++)

         printf("%c", s[i]);

     或  printf("%c",*s++);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

当定义 char a[10 ] 时,编译器会给数组分配十个单元,每个单元的数据类型为字符。
而定义 **char *s 时, 这是个指针变量,占四个字节,32位,**用来保存一个地址。
也就是说如果char msg;那么msg是一个指针变量,占有4个字节。取值赋值msg;msg++;或者msg[1],msg[2]

void DHT11_ReadData1(uchar *msg1){ //读取一次数据//湿度值(十进制,范围:20%~90%) ,温度值(十进制,范围:0~50°),返回值:0,正常;1,失败
	uchar buf[5];
	uchar i;
	DHT11_Rst();//DHT11端口复位,发出起始信号
    if(Dht11_Check()==0){ //等待DHT11回应
        for(i=0;i<5;i++){//读取5位数据
            buf[i]=Dht11_ReadByte(); //读出数据
        }
        if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){	//数据校验
            *msg1 = buf[0]; //将湿度值放入指针1
            msg1++;
            *msg1 = buf[1];
            msg1++;
	       *msg1=buf[2]; //将温度值放入指针2
	        msg1++;
	       *msg1=buf[3];
        }
    }
}
				***********************main.c**********************
				DHT11_ReadData2(msg);
				temp[0]=msg[0];
				temp[2]=msg[2];
				temp[3]=msg[3];
				hum=temp[0]*1;
			    tep=10*(temp[2]*1+0.1*temp[3]);
				int_char(hum,tep);
				UARTa_SendString(table);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

法3——用的是msg[1]

void DHT11_ReadData2(uchar *msg1){ //读取一次数据//湿度值(十进制,范围:20%~90%) ,温度值(十进制,范围:0~50°),返回值:0,正常;1,失败
	uchar buf[5];
	uchar i;
	DHT11_Rst();//DHT11端口复位,发出起始信号
    if(Dht11_Check()==0){ //等待DHT11回应
        for(i=0;i<5;i++){//读取5位数据
            buf[i]=Dht11_ReadByte(); //读出数据
        }
        if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){	//数据校验
            msg1[0] = buf[0]; //将湿度值放入指针1
            msg1[1] = buf[1];
	        msg1[2]=buf[2]; //将温度值放入指针2
	        msg1[3]=buf[3];
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

3.总的DSP程序

main.c

#include "DSP2833x_Device.h"     // DSP2833x 头文件
#include "DSP2833x_Examples.h"   // DSP2833x 例子相关头文件
#include "dht11.h"
#include "time.h"
#include "uart.h"
#include "leds.h"
char table[14];

uchar Z_F_judge(char a);
void int_char(int a,int b);
void main(void)
{
			uchar i;
			uchar * msg;
			Uint16 hum;
			Uint16 tep;
			InitSysCtrl();
			InitPieCtrl();
			IER = 0x0000;
			IFR = 0x0000;
			InitPieVectTable();
			gpio40_init();
			EALLOW;
			DAT_DIR=0;//输入
			EDIS;
			LED_Init();
			TIM0_Init(150,200000);//200ms
			UARTa_Init(9600);
			for(i=0;i<2000;i++)	//等待稳定
				DELAY_US(1000);

			while(1)
			{
//使用DHT11_ReadData();
#if 1
				DHT11_ReadData();
				hum=temp[0]*1;
				tep=10*(temp[2]*1+0.1*temp[3]);
				int_char(hum,tep);
				UARTa_SendString(table);
#endif
//使用DHT11_ReadData2(uchar *msg)或者DHT11_ReadData1(uchar *msg)
#if 0
				DHT11_ReadData2(msg);
				temp[0]=msg[0];
				temp[2]=msg[2];
				temp[3]=msg[3];
				hum=temp[0]*1;
			    tep=10*(temp[2]*1+0.1*temp[3]);
				int_char(hum,tep);
				UARTa_SendString(table);
#endif
			}

}

//生成要发送的字符串
void int_char(int a,int b)
{
	int tt1,tt2;
	uchar m;
	tt1=a;
	tt2=b;
	m=Z_F_judge(temp[3]);
	if(!m)
		table[5]=('-');
	else
		table[5]=(' ');
	table[0]=tt1/10+0x30;  //湿度十位
	table[1]=tt1%10+0x30;//个位
	table[2]=0x25;//%
	table[3]='r';
	table[4]='h';

	table[6]=tt2/100+0x30;  //温度十位
	table[7]=tt2%100/10+0x30;//个位
	table[8]='.';
	table[9]=tt2%100%10+0x30;//小数
	table[10]='C';
	table[11]='\r';//r回车n换行0结束
	table[12]='\n';//换行
	table[13]='\0';//表明字符串的结束
}

//温度正负判断函数
uchar Z_F_judge(char a)
{
	char b;
	b=a&0xf0;
	if(b == 0x01)
		return 0;
	else
		return 1;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95

dht11.c

#include "dht11.h"

char temp[4];
void gpio40_init(void)
{
	EALLOW;
	GpioCtrlRegs.GPBPUD.bit.GPIO40 = 0;    // 使能GPIO10 引脚内部上拉
	GpioCtrlRegs.GPBMUX1.bit.GPIO40 =0;   // 配置GPIO10为通用I/O口
	GpioCtrlRegs.GPBQSEL1.bit.GPIO40 = 0;    // GPIO40与系统时钟SYSCLKOUT 同步
	EDIS;
}



void DHT11_Rst(void)
{
	uchar i;
	EALLOW;
	DAT_DIR=1;//输出
	EDIS;
	DAT = 0;  //拉低DQ
	for(i=0;i<25;i++)	//18-30ms
			DELAY_US(1000);
	DAT = 1;
	DELAY_US(30);//主机拉高20~40us
}

Uint16 Dht11_Check(void){ //等待DHT11回应,返回1:未检测到DHT11,返回0:成功(IO接收)
	Uint16 retry=0;
	EALLOW;
	DAT_DIR=0;
	EDIS;//IO到输入状态
    while (DAT&&retry<100){//DHT11会拉低40~80us
        retry++;
        DELAY_US(1);
    }
    if(retry>=100)return 1; else retry=0;
    while (!DAT&&retry<100){//DHT11拉低后会再次拉高40~80us
        retry++;
        DELAY_US(1);
    }
    if(retry>=100)return 1;
    return 0;
}

Uint16 DHT11_Init (void){	//DHT11初始化
	DHT11_Rst();//DHT11端口复位,发出起始信号
	return Dht11_Check(); //等待DHT11回应
}

uchar Dht11_ReadBit(void){ //从DHT11读取一个位 返回值:1/0
    uchar retry=0;
    while(DAT){//等待变为低电平
           // retry++;
            //DELAY_US(1);
        }
       // retry=0;
    while(!DAT){//等待变高电平
      //  retry++;
     //   DELAY_US(1);
    }
   // retry=0;
    while(DAT)
    {
        retry++;
        DELAY_US(1);
    }
    if(40<retry)return 1; else return 0;
}

uchar Dht11_ReadByte(void){  //从DHT11读取一个字节  返回值:读到的数据
    uchar i,dat;
    dat=0;
    for (i=0;i<8;i++){
        dat<<=1;
        dat|=Dht11_ReadBit();
    }
    return dat;
}

void DHT11_ReadData(void){ //读取一次数据//湿度值(十进制,范围:20%~90%) ,温度值(十进制,范围:0~50°),返回值:0,正常;1,失败
	uchar buf[5];
	uchar i;
	DHT11_Rst();//DHT11端口复位,发出起始信号
    if(Dht11_Check()==0){ //等待DHT11回应
        for(i=0;i<5;i++){//读取5位数据
            buf[i]=Dht11_ReadByte(); //读出数据
        }
        if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){	//数据校验
            temp[0]=buf[0]; //将湿度值放入指针1
            temp[1]=buf[1];
	        temp[2]=buf[2]; //将温度值放入指针2
	        temp[3]=buf[3];
        }
    }
}

void DHT11_ReadData1(uchar *msg1){ //读取一次数据//湿度值(十进制,范围:20%~90%) ,温度值(十进制,范围:0~50°),返回值:0,正常;1,失败
	uchar buf[5];
	uchar i;
	DHT11_Rst();//DHT11端口复位,发出起始信号
    if(Dht11_Check()==0){ //等待DHT11回应
        for(i=0;i<5;i++){//读取5位数据
            buf[i]=Dht11_ReadByte(); //读出数据
        }
        if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){	//数据校验
            *msg1 = buf[0]; //将湿度值放入指针1
            msg1++;
            *msg1 = buf[1];
            msg1++;
	       *msg1=buf[2]; //将温度值放入指针2
	        msg1++;
	       *msg1=buf[3];
        }
    }
}

void DHT11_ReadData2(uchar *msg1){ //读取一次数据//湿度值(十进制,范围:20%~90%) ,温度值(十进制,范围:0~50°),返回值:0,正常;1,失败
	uchar buf[5];
	uchar i;
	DHT11_Rst();//DHT11端口复位,发出起始信号
    if(Dht11_Check()==0){ //等待DHT11回应
        for(i=0;i<5;i++){//读取5位数据
            buf[i]=Dht11_ReadByte(); //读出数据
        }
        if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){	//数据校验
            msg1[0] = buf[0]; //将湿度值放入指针1
            msg1[1] = buf[1];
	        msg1[2]=buf[2]; //将温度值放入指针2
	        msg1[3]=buf[3];
        }
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134

dht11.h

#ifndef APP_DHT11_DHT11_H_
#define APP_DHT11_DHT11_H_
#include "DSP2833x_Device.h"     // DSP2833x 头文件
#include "DSP2833x_Examples.h"   // DSP2833x 例子相关头文件

#define uchar unsigned char
#define DAT_DIR		GpioCtrlRegs.GPBDIR.bit.GPIO40  //方向1为输出,0为输入
#define DAT			GpioDataRegs.GPBDAT.bit.GPIO40//数值

extern char temp[4];


void gpio40_init(void);
void DHT11_Rst(void);
Uint16 Dht11_Check(void);
Uint16 DHT11_Init (void);
uchar Dht11_ReadBit(void);
void DHT11_ReadData(void);//三种方法取数据
void DHT11_ReadData1(uchar * msg1);
void DHT11_ReadData2(uchar *msg1);

#endif /* APP_DHT11_DHT11_H_ */

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

4.MATLAB脚本

main.m

clear all;
delete(instrfindall)
clear obj1
global obj1;
global data;
global sendbuff;
global data1;
global data2;
global data3;
global data4;
global data5;
global dian_ya;
global wen_du;
global shi_du;
global x;%用于画图
global y;
x=0;
y=0;
dian_ya=0;
wen_du=0;
shi_du=0;
data1=0;
data2=0;
data3=0;
data4=0;
data5=0;
global n;
n=0;
data = zeros(5,1);
sendbuff = zeros(1,8);

obj1 = serial('com8');%需要修改
fclose(obj1);
set(obj1, 'InputBufferSize', 100);
set(obj1, 'OutputBufferSize', 100);
set(obj1, 'BaudRate', 9600);
set(obj1, 'Timeout', 15.0);
set(obj1,'BytesAvailableFcnMode','terminator');
set(obj1,'terminator',10);
set(obj1,'BytesAvailableFcn',@my_callback1);
fopen(obj1);


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

my_callback1

function my_callback1(obj1,event)
global data;
global data1;
global data2;
global data3;
global data4;
global data5;
global dian_ya;
global wen_du;
global shi_du;
global x;
global y;
data = fread(obj1 , 14);%取决于发送的数组大小,真实的个数(19if length(data)==14
            if data(3)=='%'
                data1=data(1)-48;%48就是去掉0x30;
                data2=data(2)-48;
                data3=data(7)-48;
                data4=data(8)-48;
                data5=data(9)-48;
                shi_du=10*data1+data2;
                wen_du=10*data3+1*data4+0.1*data5;
            end
        end
        disp(shi_du);
        disp(wen_du);
        x = [x shi_du];
        y = [y wen_du];
        plot(x,'r');
        hold on;
        plot(y,'g');
        axis([0 inf 27 100]);
        title('From Dsp');
        xlabel('Sample');
        ylabel('Result');
        drawnow;
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

draw_total.main

clc;
t=1:length(x);

plot(t,x)
hold on;
plot(t,y);
legend('湿度','温度');
axis([0 inf 27 100]);
title('From Dsp');
xlabel('Sample');
ylabel('Result');
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

draw_total运行的figure
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/630108
推荐阅读
相关标签
  

闽ICP备14008679号