|
/************************************************************
程序說明:
首先要確定模塊已經(jīng)注冊到網(wǎng)絡(luò)
然后正確的硬件連接 P3.0-----STXD或者5VT P3.1-----SRXD或者5VR GND---GND(只要保證公地即可,沒必要單獨接一次)
然后確認(rèn)你單片機上的晶振,根據(jù)晶振修改自己的程序。
推薦先將單片機與電腦相連,確定單片機發(fā)送的數(shù)據(jù)是正確的。如果發(fā)送的是亂碼,請檢查晶振與單片機的串口波特率。
如果通過以上幾條還解決不了問題,請看群共享文件 AN0004 。
*************************************************************/
#include <REG51.H>
#include <string.H>
#include <stdio.h>
#include "DHT11.H"
#define uchar unsigned char
#define uint unsigned int
//以下是板子上LED的配置,把Px_x改成自己對應(yīng)的腳。LED 只是用來提示,非必須。
//以下是你的51單片機的晶振大小
sbit P13=P2^3;
sbit P14=P2^4;
sbit P15=P2^5;
sbit P11=P2^2;
#define FOSC_110592M
//#define FOSC_12M
//以下是GSM模塊返回數(shù)據(jù)
uchar rec_data[50];
uchar rec_num;
uchar S[20];
//注意,無論接收到信號還是發(fā)送完信號,都會進中斷服務(wù)程序的
/*初始化程序(必須使用,否則無法收發(fā)),次程序?qū)褂枚〞r器1*/
void SerialInti()//初始化程序(必須使用,否則無法收發(fā))
{
TMOD=0x20;//定時器1操作模式2:8位自動重載定時器
#ifdef FOSC_12M //在這里根據(jù)晶振大小設(shè)置不同的數(shù)值初始化串口
TH1=0xf3;//裝入初值,波特率2400
TL1=0xf3;
#else
TH1=0xfd;//裝入初值,波特率9600
TL1=0xfd;
#endif //end of SOC_12M
TR1=1;//打開定時器
SM0=0;//設(shè)置串行通訊工作模式,(10為一部發(fā)送,波特率可變,由定時器1的溢出率控制)
SM1=1;//(同上)在此模式下,定時器溢出一次就發(fā)送一個位的數(shù)據(jù)
REN=1;//串行接收允許位(要先設(shè)置sm0sm1再開串行允許)
EA=1;//開總中斷
ES=1;//開串行口中斷
}
/*串行通訊中斷,收發(fā)完成將進入該中斷*///如:+CMTI:"SM",2
void Serial_interrupt() interrupt 4
{
uchar temp;
temp=SBUF;
rec_data[rec_num++]=temp;
if(rec_num>=50)
rec_num=0;
else
;
RI=0;//接收中斷信號清零,表示將繼續(xù)接收
}
//串行口連續(xù)發(fā)送char型數(shù)組,遇到終止號/0將停止
void Uart1Sends(uchar *str)
{
while(*str!='\0')
{
SBUF=*str;
while(!TI);//等待發(fā)送完成信號(TI=1)出現(xiàn)
TI=0;
str++;
}
}
void Uart1BYTE(uchar temp)
{
SBUF=temp;
while(!TI);//等待發(fā)送完成信號(TI=1)出現(xiàn)
TI=0;
}
void clear_rec_data()
{
uchar i;
for(i=0;i<strlen(rec_data);i++)
{
rec_data[i]='0';
}
rec_num=0;
}
//延時函數(shù)大概是1s鐘,不過延時大的話不準(zhǔn)...
void DelaySec(int sec)
{
uint i , j= 0;
for(i=0; i<sec; i++)
{
for(j=0; j<65535; j++)
{
}
}
}
void main()
{
uchar i = 0;
SerialInti();
receive();
P13=1;
P14=1;
P15 = 1;
if(P11==0)
{
receive();
P13=0;
clear_rec_data();
DelaySec(1);//延時
//以下是發(fā)送英文短信短信
Uart1Sends("AT+CSCS=\"GSM\"\r\n"); //
DelaySec(1);//延時
Uart1Sends("AT+CSCA?\r\n"); //短信中心號碼
DelaySec(1);//延時
Uart1Sends("AT+CMGF=1\r\n"); //方式1
DelaySec(1);//延時
Uart1Sends("AT+CMGS=\"18295376558\"\r\n"); //此處修改短信接收方電話號
DelaySec(1);//延時
P14 = 0;
sprintf(S,"Water level overrun!T:%d-R:%d",RH,TH);//
Uart1Sends(S); //此處修改短信內(nèi)容
DelaySec(1);//延時
Uart1BYTE(0X1A);
P15=0;
DelaySec(1);//延時
DelaySec(1);//延時
DelaySec(1);//延時
DelaySec(1);//延時
}
}
#include "DHT11.H"
uint RH, RL, TH, TL; //濕度(整數(shù)),濕度(小數(shù)),溫度(整數(shù)),溫度(小數(shù))//
uchar data_byte;
void delay(uchar ms) //延時模塊//
{
uchar i;
while(ms--)
for(i=0;i<100;i++);
}
void delay1()//一個for循環(huán)大概需要8個多機器周期一個機器周期為1us晶振為12MHz也就是說本函數(shù)延時8us多此延時函數(shù)必須德稍微精確一點
{
uchar i;
for(i=0;i<1;i++);
}
void start()//開始信號
{
io=1;
delay1();
io=0;
delay(25);// 主機把總線拉低必須大于18ms保證DHT11能檢測到起始信號
io=1; //發(fā)送開始信號結(jié)束后拉高電平延時20-40us
delay1();//以下三個延時函數(shù)差不多為24us符合要求
delay1();
delay1();
}
uchar receive_byte()//接收一個字節(jié)//
{
uchar i,temp;
for(i=0;i<8;i++)//接收8bit的數(shù)據(jù)
{
while(!io);//等待50us的低電平開始信號結(jié)束
delay1();//開始信號結(jié)束之后延時26us-28us以下三個延時函數(shù)
delay1();
delay1();
temp=0;//時間為26us-28us表示接收的為數(shù)據(jù)'0'
if(io==1)
temp=1; //如果26us-28us之后還為高電平則表示接收的數(shù)據(jù)為'1'
while(io);//等待數(shù)據(jù)信號高電平'0'為26us-28us'1'為70us
data_byte<<=1;//接收的數(shù)據(jù)為高位在前右移
data_byte|=temp;
}
return data_byte;
}
void receive()//接收數(shù)據(jù)//
{
uchar T_H,T_L,R_H,R_L,check,num_check,i;
start();//開始信號//
io=1; //主機設(shè)為輸入判斷從機DHT11響應(yīng)信號
if(!io)//判斷從機是否有低電平響應(yīng)信號//
{
while(!io);//判斷從機發(fā)出 80us 的低電平響應(yīng)信號是否結(jié)束//
while(io);//判斷從機發(fā)出 80us 的高電平是否結(jié)束如結(jié)束則主機進入數(shù)據(jù)接收狀態(tài)
R_H=receive_byte();//濕度高位
R_L=receive_byte();//濕度低位
T_H=receive_byte();//溫度高位
T_L=receive_byte();//溫度低位
check=receive_byte();//校驗位
io=0; //當(dāng)最后一bit數(shù)據(jù)接完畢后從機拉低電平50us//
for(i=0;i<7;i++)//差不多50us的延時
delay1();
io=1;//總線由上拉電阻拉高進入空閑狀態(tài)
num_check=R_H+R_L+T_H+T_L;
if(num_check==check)//判斷讀到的四個數(shù)據(jù)之和是否與校驗位相同
{
RH=R_H;
RL=R_L;
TH=T_H;
TL=T_L;
check=num_check;
}
}
} |
|