|
采用51单片机主控的整个远程温度监控系统设计出来的实物图如下:
左上角是gprs模块,需要插入手机卡才能远程通讯。具有串口接口,显示部分采用的是lcd12864液晶.
原理图,pcb文件(是用ad画的附件中可下载工程文件):
详尽资料在附件中,因网站上传限制,需要其他相关资料可留言。这个设计花了大概三个星期时间,gprs实时通讯方面难度相对大。望多多指教!
部分源程序预览:
- /*******************************************************************************
- * 实验名 :温度显示实验
- * 使用的IO :
- * 实验效果 :1602显示温度
- * 注意 :
- *******************************************************************************/
- #include<reg51.h>
- #include"LCD12864_SPI.h"
- #include"temp.h"
- #include<math.h>
- #include<string.h>
- #include <all.h>
- sbit K1 = P1^3;
- sbit K2 = P1^4;
- sbit K3 = P1^5;
- sbit K4 = P1^6;
- sbit K5 = P1^7;
- sbit Buzzer1 = P0^2;
- sbit LED1 = P0^0;
- sbit Buzzer2 = P0^5;
- sbit LED2 = P0^6;
- int Temperature = 0; //用于存储温度值
- int Deviation = 0; //1存储偏差
- int Report = 5000; //1高温报警值
- int Temperature1 = 0; //用于存储温度值
- int Deviation1 = 0; //2存储偏差
- int Report1 = 5000; //2高温报警值
- char Set = 0;
- unsigned char xdata TCP[] = {"AT+CIPSTART=TCP,103.44.145.245,33601\x0D\x0A"}; //映射的域名对应IP及端口在这里修改
- unsigned char dat[8] = {0, 0, 0, 0, 0, 0, 0, 0}; //定义数组
- unsigned int count=0;
- unsigned char Flag=0;
- unsigned char Num=0;
- #define LenRxBuf 50
- char AT_SK[]="\x0D\x0A> "; // 0D 0A 3E 20 \x0D\x0A
- char AT_Code[]="\x0D\x0AOK"; // 0D 0A 4F 4B 0D 0A
- char CONNECT_OK[]="\x0D\x0ACONNECT OK"; //CONNECT OK // 0D 0A 43 4F 4E 4E 45 43 54 20 4F 4B 0D 0A 0D 0A 4F 4B 0D 0A
- char RsPoint=0; //发送 数组指针
- char xdata RsBuf[LenRxBuf]; //接收缓存
- void REPORT(int temperature, int report, uchar es);
- void UsartConfiguration();
- void TX_Char(unsigned char TXData);
- void Send_Str(unsigned char *str);
- void SendnStr(char *str, char n);//发送字符串
- void Int_Char(int temp);
- void ClrRsBuf(char *p, int len);
- char WaitOK(char *th, char time);
- char Connect_GPRS();
- void KeyScan();
- int TempDeal(int temp);
- void LcdDisplay(int temp);
- void LcdDisplay1(int temp); //lcd显示
- /*******************************************************************************
- * 函数名 : main
- * 函数功能 : 主函数
- * 输入 : 无
- * 输出 : 无
- *******************************************************************************/
- void main()
- {
- unsigned char i;
- P0=0XFF;
- Buzzer1 = 1; //熄灭LED及关闭蜂鸣器
- LED1 = 1;
- Buzzer2 = 1;
- LED2 = 1;
-
- Lcd_Init(); //初始化LCD12864
- UsartConfiguration(); //初始化串口,波特率9600
- while(1)
- {
-
- KeyScan();
-
- if(Set==0)
- {
- LcdWriteStr(0x80, "Temp1:", 6);
- LcdWriteStr(0x90, "Temp2:", 6);
-
- Temperature = TempDeal(Ds18b20ReadTemp()) + Deviation;
- Temperature1 = TempDeal(Ds18b20ReadTemp1()) + Deviation1;
-
- LcdDisplay(Temperature); //显示温度
- LcdDisplay1(Temperature1); //显示温度
-
- REPORT(Temperature, Report, 1); //报警
- REPORT(Temperature1, Report1, 2); //报警
-
- }
- // delay_1ms(1000);//1s钟刷一次
-
-
- if((count>=200) && (Flag==1)) //10s
- {
- count=0;
-
- // ClrRsBuf(RsBuf,50); //清空接收缓冲区
- // RsPoint=0;
- //
- // ES=0; //关闭接收中断
- // Send_Str("AT+CIPSTATUS\x0D\x0A"); //查询tcp连接状态 0D 0A 0D 0A 2B 43 49 50 53 54 41 54 55 53 3A 30 2C 43 4F 4E 4E 45 43 54 20 4F 4B 20 20 0D 0A
- // ES=1; //打开接收中断
- // if(WaitOK(AT_Code, 10)==1)
- // {
- // LcdWriteCom(0x98); //清空lcd后1行
- // for(i=0;i<16;i++)
- // LcdWriteData(' ');
- // Flag=1;
- // LcdWriteStr(0x98, "CONNECT OK", 10);
- //
-
- ClrRsBuf(RsBuf,50); //清空接收缓冲区
- RsPoint=0;
-
- ES=0; //关闭接收中断
- Send_Str("AT+CIPSEND\x0D\x0A"); //tcp发送
- ES=1; ////打开接收中断
- if(WaitOK(AT_SK, 2)==1) // '>' 0D 0A 3E 20
- {
- ES=0; //关闭接收中断
- Int_Char(Temperature);
- Send_Str("节点1温度值为:");
- SendnStr(dat,8);
- Send_Str(";\x0A");
-
- Int_Char(Temperature1);
- Send_Str("节点2温度值为:");
- SendnStr(dat,8);
- Send_Str(";\x0A\x1A");
- ES=1; ////打开接收中断
-
- switch(WaitOK(AT_Code, 3))
- {
- case 0:
- {
- LcdWriteCom(0x98); //清空lcd后1行
- for(i=0;i<16;i++)
- LcdWriteData(' ');
- LcdWriteStr(0x98, "SEND FAIL", 9);
- Num++;
- if(Num==10)
- {
- Num=0;
- Flag=0;
- LcdWriteCom(0x88); //清空lcd后2行
- for(i=0;i<16;i++)
- LcdWriteData(' ');
- LcdWriteCom(0x98);
- for(i=0;i<16;i++)
- LcdWriteData(' ');
- }
- }
- break;
-
- case 1:
- {
- LcdWriteCom(0x98); //清空lcd后1行
- for(i=0;i<16;i++)
- LcdWriteData(' ');
- LcdWriteStr(0x98, "SEND SUCCESS", 12);
- Flag=1;
- }
- break;
-
- default:
- break;
- }
- }
-
- }
-
- }
-
- }
- /*******************************************************************************
- * 函数名 : Int_Char
- * 函数功能 : 整形数据转换为字符型
- * 输入 : temp
- * 输出 : 无
- *******************************************************************************/
- void Int_Char(int temp)
- {
-
- dat[0] = (temp % 10000 / 1000)+0x30;
- dat[1] = (temp % 1000 / 100)+0x30;
- dat[2] = '.';
- dat[3] = (temp % 100 / 10)+0x30;
- dat[4] = (temp % 10)+0x30;
- dat[5] = '\xA1';
- dat[6] = '\xE3';
- dat[7] = 'C';
- }
- /*******************************************************************************
- * 函数名 : REPORT(int temperature, int report, uchar es)
- * 函数功能 : 报警处理,
- * 输入 : 采集的温度:temperature;报警温度:report; 节点选择:es
- * 输出 : 无
- *******************************************************************************/
- void REPORT(int temperature, int report, uchar es)
- {
- switch(es)
- {
- case 1:
- {
- if(temperature>=report) //报警temperature
- {
- Buzzer1 = 0;
- LED1 = 0;
-
- }
- else
- {
- Buzzer1 = 1;
- LED1 = 1;
- }
- }
- break;
-
- case 2:
- {
- if(temperature>=report) //报警
- {
- Buzzer2 = 0;
- LED2 = 0;
- }
- else
- {
- Buzzer2 = 1;
- LED2 = 1;
- }
- }
- break;
-
- default:
- break;
- }
- }
- /*******************************************************************************
- * 函数名 :UsartConfiguration()
- * 函数功能 :设置串口
- * 输入 : 无
- * 输出 : 无
- *******************************************************************************/
- void UsartConfiguration()
- {
- SCON=0X50; //设置为工作方式1
- TMOD=0X21; //设置计数器1工作方式2;定时器 0工作方式1
- PCON=0X80; //波特率加倍
- TH1=0XFA; //计数器初始值设置,注意波特率是9600;4800的f3
- TL1=0XFA;
-
- TH0=0X3C; //定时50ms
- TL0=0XB0;
-
- ES=0; //bu打开接收中断
- ET0=1; //打开定时器0中断
- EA=1; //打开总中断
-
- TR1=1; //打开计数器1
- TR0=0; //关闭定时器0
- }
- /*******************************************************************************
- * 函数名 : TX_Char(unsigned char TXData)
- * 函数功能 : 串口发送字符
- * 输入 : TXData
- * 输出 : 无
- *******************************************************************************/
- void TX_Char(unsigned char TXData)
- {
- SBUF=TXData; //发送数据
- while(!TI); //等待发送数据完成
- TI=0; //清除发送完成标志位
- }
- /*******************************************************************************
- * 函数名 : TX_Char(unsigned char TXData)
- * 函数功能 : 串口发送字符串
- * 输入 : TXData
- * 输出 : 无
- *******************************************************************************/
- void Send_Str(unsigned char *str)//发送字符串
- {
- while(*str!='\0')
- {
- TX_Char(*str);
- str++;
- }
- }
- /*******************************************************************************
- * 函数名 : SendnStr(char *str, char n)
- * 函数功能 : 串口发送n字节字符串
- * 输入 : TXData
- * 输出 : 无
- *******************************************************************************/
- void SendnStr(char *str, char n)//发送字符串
- {
- while((n--) && (*str!='\0'))
- {
- TX_Char(*str);
- str++;
- }
- }
- /*******************************************************************************
- * 函数名 : ClrRsBuf(char *p,int len)
- * 函数功能 : 清空p指针里len字节长度的内存
- * 输入 : 指针:p ; 清空长度:len
- * 输出 : 无
- *******************************************************************************/
- void ClrRsBuf(char *p,int len) //清空
- {
- while(len--)
- {
- *p='\0';
- p++;
- }
- }
- /*******************************************************************************
- * 函数名 : strncmp ( char * s1, char * s2, size_t n)
- * 函数功能 :比较str1与str2的前n个字符,相同返回0;不同返回( *s1 - *s2 )
- * 输入 : 指针:str1 ; 指针:str2 ;长度:n
- * 输出 : 比较结果相同返回0;不同返回( *s1 - *s2 )
- *******************************************************************************/
- char strncmp ( char * s1, char * s2, size_t n)
- {
- if ( !n ) //n为0,则返回0
- return(0);
- //在接下来的while循环中
- //第一个循环条件:--n,如果比较到前n个字符,则退出循环
- //第二个循环条件:*s1,如果s1指向字符串末尾,则退出循环
- //第三个循环条件:*s1 == *s2,如果两字符不等,则退出循环
- while (--n && *s1 && *s1 == *s2)
- {
- s1++;
- s2++;
- }
- return( *s1 - *s2 );
- }
- /*******************************************************************************
- * 函数名 : strlen(const char *str)
- * 函数功能 : 求指针的长度
- * 输入 : 指针:str
- * 输出 : 指针的长度
- *******************************************************************************/
- size_t strlen(const char *str)
- {
- size_t length = 0;
- while (*str++)
- ++length;
- return length;
- }
- /*******************************************************************************
- * 函数名 : *strstr( const char *s1, const char *s2 )
- * 函数功能 : 找出s2字符串在s1字符串中第一次出现的位置
- * 输入 : 指针:s1 ; 指针:s2
- * 输出 : 返回该位置的指针,如找不到则返回NULL
- *******************************************************************************/
- char *strstr( const char *s1, const char *s2 )
- {
- int len2;
- if ( !(len2 = strlen(s2)) )
- return (char *)s1;
- for ( ; *s1; ++s1 )
- {
- if ( *s1 == *s2 && strncmp( s1, s2, len2 )==0 )
- return (char *)s1;
- }
- return NULL;
- }
- /*******************************************************************************
- * 函数名 : WaitOK(uchar *th, uchar time)
- * 函数功能 : 等待time s的时间,判断6A模组返回信息是否OK
- * 输入 : 指针:th ; 等待时间:time
- * 输出 : OK返回1,否则返回0
- *******************************************************************************/
- char WaitOK(char *th, char time)
- {
- while(time--)
- {
- if(strstr(RsBuf,th) != NULL) //strncmp
- {
- return 1;
- }
-
- else
- {
- if(time!=0)
- delay_1ms(1000);
- }
- }
- return 0;
- }
- /*******************************************************************************
- * 函数名 : Connect_GPRS()
- * 函数功能 : 连接GPRS
- * 输入 : 无
- * 输出 : 无
- *******************************************************************************/
- char Connect_GPRS()
- {
- char i;
-
- ClrRsBuf(RsBuf,50); //清空接收缓冲区 AT_Code
- RsPoint=0;
- ES=0; //关闭接收中断
- Send_Str("ATE0\x0D\x0A"); //ATE0:关闭回显; ATE1:打开回显
- ES=1; //打开接收中断
- if(WaitOK(AT_Code, 10)!=1)
- return 0;
-
- ClrRsBuf(RsBuf,50); //清空接收缓冲区 AT_Code
- RsPoint=0;
- ES=0; //关闭接收中断
- Send_Str("AT+CGATT=1\x0D\x0A"); //GPRS 附着; AT+CGATT=0 GPRS分离
- ES=1; //打开接收中断
- if(WaitOK(AT_Code, 10)!=1)
- return 0;
-
- ClrRsBuf(RsBuf,50); //清空接收缓冲区 AT_Code
- RsPoint=0;
- ES=0; //关闭接收中断
- Send_Str("AT+CGACT=1,1\x0D\x0A"); //PDP上下文激活 去激活:AT+CGACT=0,1
- ES=1; //打开接收中断
- if(WaitOK(AT_Code, 10)!=1)
- return 0;
-
- ClrRsBuf(RsBuf,50); //清空接收缓冲区 AT_Code
- RsPoint=0;
- ES=0; //关闭接收中断
- Send_Str("AT+CIFSR\x0D\x0A"); //查询 IP 地址
- ES=1; //打开接收中断
- if(WaitOK(AT_Code,10)==1)
- {
- LcdWriteCom(0x88); //清空第3行
- for(i=0;i<16;i++)
- LcdWriteData(' ');
- LcdWriteCom(0x88);
-
- for(i=2;i<17;i++)
- {
- if((RsBuf[i]!='\x0D')&&(RsBuf[i]!='\x0A')&&(RsBuf[i]!=' '))
- LcdWriteData(RsBuf[i]);
- }
- }
-
- ClrRsBuf(RsBuf,50); //清空接收缓冲区 AT_Code
- RsPoint=0;
- ES=0; //关闭接收中断
- Send_Str(TCP); //GPRS TCP 连接
- ES=1; //打开接收中断
- if(WaitOK(AT_Code,10)==1) //strncmp(RsBuf+17,CONNECT_OK, 10)==0 WaitOK(CONNECT_OK, 10)==1
- {
- LcdWriteCom(0x98); //清空lcd后1行
- for(i=0;i<16;i++)
- LcdWriteData(' ');
- LcdWriteStr(0x98, "CONNECT OK", 10);
- Flag=1; //置GPRS连接标志
-
- return 1;
- }
-
- LcdWriteCom(0x88); //清空lcd后1行
- for(i=0;i<16;i++)
- LcdWriteData(' ');
- LcdWriteCom(0x98); //清空lcd后1行
- for(i=0;i<16;i++)
- LcdWriteData(' ');
- LcdWriteStr(0x98, "CONNECT ERROR", 13);
- Flag=0; //清GPRS连接标志
-
- return 0;
-
- }
- /*******************************************************************************
- * 函数名 : void Usart()
- * 函数功能 : 串口中断函数
- * 输入 : 无
- * 输出 : 无
- *******************************************************************************/
- void Usart() interrupt 4 using 3
- {
- if(RI==1)
- {
- RI=0;
- RsBuf[RsPoint++]=SBUF;
- if (RsPoint>=50)
- {
- ES=0; //关闭接收中断
- RsPoint=50;
- }
- }
- }
- /*******************************************************************************
- * 函数名 : Timer0
- * 函数功能 : 定时器0中断函数
- * 输入 : 无
- * 输出 : 无
- *******************************************************************************/
- void Timer0() interrupt 1 using 3
- {
- TH0=0X3C; //重装定时值50ms
- TL0=0XB0;
- count++;
-
- }
- /*******************************************************************************
- * 函数名 : KeyScan
- * 函数功能 : 按键检测函数
- * 输入 : 无
- * 输出 : 无
- *******************************************************************************/
- void KeyScan()
- {
- unsigned char i=0;
- int Dev;
-
- K1=1;
- if(K1==0) //检测按键K1是否按下
- {
- delay_1ms(10); //消除抖动
- if(K1==0) //按键1按下时执行该动作
- {
-
- Set += 1;
- if(Set==5)
- Set=0;
-
- LcdWriteCom(0x01); //写入空格清屏幕
-
- LcdWriteCom(0x80); //设定首行显示位置
-
- if(Set==1)
- {
- LcdWriteStr(0x80, "Correct Temp1:", 14);
-
- LcdWriteCom(0x91); //设定显示位置
-
- if(Deviation == 0)
- LcdWriteData(' '); //显示
- if(Deviation > 0)
- LcdWriteData('+'); //显示正
- if(Deviation < 0)
- LcdWriteData('-'); //显示负
-
- Dev = abs(Deviation);
-
- dat[0] = Dev % 1000 / 100;
- dat[1] = Dev % 100 / 10;
- dat[2] = Dev % 10;
-
- LcdWriteData('0'+dat[0]); //个位
- LcdWriteData('.'); //显示 ‘.’
- LcdWriteData('0'+dat[1]); //十分位
- LcdWriteData('0'+dat[2]); //百分位
- LcdWriteData(' ');
- LcdWriteData('C');
- }
-
- if(Set==2)
- {
- LcdWriteStr(0x80, "Correct Temp2:", 14);
-
- LcdWriteCom(0x91); //设定显示位置
-
- if(Deviation1 == 0)
- LcdWriteData(' '); //显示
- if(Deviation1 > 0)
- LcdWriteData('+'); //显示正
- if(Deviation1 < 0)
- LcdWriteData('-'); //显示负
-
- Dev = abs(Deviation1);
-
- dat[0] = Dev % 1000 / 100;
- dat[1] = Dev % 100 / 10;
- dat[2] = Dev % 10;
-
- LcdWriteData('0'+dat[0]); //个位
- LcdWriteData('.'); //显示 ‘.’
- LcdWriteData('0'+dat[1]); //十分位
- LcdWriteData('0'+dat[2]); //百分位
- LcdWriteData(' ');
- LcdWriteData('C');
- }
-
- if(Set==3)
- {
- LcdWriteStr(0x80, "High Ring1:", 10);
-
- LcdWriteCom(0x91); //设定显示位置
-
- if(Report == 0)
- LcdWriteData(' '); //显示
- if(Report > 0)
- LcdWriteData('+'); //显示正
- if(Report < 0)
- LcdWriteData('-'); //显示负
-
- Dev = abs(Report);
-
- dat[0] = Dev % 10000 / 1000;
- dat[1] = Dev % 1000 / 100;
- dat[2] = Dev % 100 / 10;
- dat[3] = Dev % 10;
-
- LcdWriteData('0'+dat[0]); //十位
- LcdWriteData('0'+dat[1]); //个位
- LcdWriteData('.'); //显示 ‘.’
- LcdWriteData('0'+dat[2]); //十分位
- LcdWriteData('0'+dat[3]); //百分位
- LcdWriteData(' ');
- LcdWriteData('C');
- }
-
- if(Set==4)
- {
- LcdWriteStr(0x80, "High Ring2:", 10);
-
- LcdWriteCom(0x91); //设定显示位置
-
- if(Report1 == 0)
- LcdWriteData(' '); //显示
- if(Report1 > 0)
- LcdWriteData('+'); //显示正
- if(Report1 < 0)
- LcdWriteData('-'); //显示负
-
- Dev = abs(Report1);
-
- dat[0] = Dev % 10000 / 1000;
- dat[1] = Dev % 1000 / 100;
- dat[2] = Dev % 100 / 10;
- dat[3] = Dev % 10;
-
- LcdWriteData('0'+dat[0]); //十位
- LcdWriteData('0'+dat[1]); //个位
- LcdWriteData('.'); //显示 ‘.’
- LcdWriteData('0'+dat[2]); //十分位
- LcdWriteData('0'+dat[3]); //百分位
- LcdWriteData(' ');
- LcdWriteData('C');
- }
-
- while((i<50)&&(K1==0)) //检测按键是否松开
- {
- delay_1ms(10);
- i++;
- }
- i=0;
- }
- }
-
- K2=1;
- if(K2==0) //检测按键K1是否按下
- {
- delay_1ms(10); //消除抖动
- if(K2==0)
- {
-
- if(Set==1)
- {
- Deviation += 10; //按键2按下时执行该动作,按一下温度值正向纠正 0.1°C,最多纠正5°C
- if(Deviation >= 500)
- {
- Deviation = 500;
- }
- LcdWriteCom(0x91); //设定显示位置
-
- if(Deviation == 0)
- LcdWriteData(' '); //显示
- if(Deviation > 0)
- LcdWriteData('+'); //显示正
- if(Deviation < 0)
- LcdWriteData('-'); //显示负
-
- Dev = abs(Deviation);
-
- dat[0] = Dev % 1000 / 100;
- dat[1] = Dev % 100 / 10;
- dat[2] = Dev % 10;
-
- LcdWriteData('0'+dat[0]); //个位
- LcdWriteData('.'); //显示 ‘.’
- LcdWriteData('0'+dat[1]); //十分位
- LcdWriteData('0'+dat[2]); //百分位
- LcdWriteData(' ');
- LcdWriteData('C');
- }
-
- if(Set==2)
- {
- Deviation1 += 10; //按键2按下时执行该动作,按一下温度值正向纠正 0.1°C,最多纠正5°C
- if(Deviation1 >= 500)
- {
- Deviation1 = 500;
- }
- LcdWriteCom(0x91); //设定显示位置
-
- if(Deviation1 == 0)
- LcdWriteData(' '); //显示
- if(Deviation1 > 0)
- LcdWriteData('+'); //显示正
- if(Deviation1 < 0)
- LcdWriteData('-'); //显示负
-
- Dev = abs(Deviation1);
-
- dat[0] = Dev % 1000 / 100;
- dat[1] = Dev % 100 / 10;
- dat[2] = Dev % 10;
-
- LcdWriteData('0'+dat[0]); //个位
- LcdWriteData('.'); //显示 ‘.’
- LcdWriteData('0'+dat[1]); //十分位
- LcdWriteData('0'+dat[2]); //百分位
- LcdWriteData(' ');
- LcdWriteData('C');
- }
-
- if(Set==3)
- {
- Report += 10; //按键2按下时执行该动作,按一下温度报警值正向增加0.1°C
- if(Report >= 9000)
- {
- Report = 9000;
- }
-
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
资料下载:
程序 原理图 用到的包括串口助手,服务器等资料.zip
(4 MB, 下载次数: 405)
|
评分
-
查看全部评分
|