赞
踩
设备(主机或从机)通过一个一个漏极开路或三态端口连接至该数据线,以允许设备在不发送数据时能够释放总线,而让其他设备使用总线。——GPBPUD=0——DSP使能上拉。
一次传送40位数据,高位先出。数据格式:
关于电平时间的定义
gpio40_init();
EALLOW;
DAT_DIR=0;//输入
EDIS;
for(i=0;i<2000;i++) //等待稳定
DELAY_US(1000);
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到输入状态 //找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; }
总的DHT11初始化程序
Uint16 DHT11_Init (void){ //DHT11初始化
DHT11_Rst();//DHT11端口复位,发出起始信号
return Dht11_Check(); //等待DHT11回应
}
法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;
}
法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——用的是全局变量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);
法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++);
当定义 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);
法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]; } } }
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; }
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]; } } }
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_ */
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);
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);%取决于发送的数组大小,真实的个数(1,9) if 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
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');
draw_total运行的figure
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。