#include "drive_1602.h" #include "string.h" #include "stdio.h" #include "dht11.h" #define uint unsigned int #define uchar unsigned char /* 按键实现人机交互的主要方式,温湿度传感器可以感测环境温度湿度, 并且采集电信号至单片机,供电模块给单片机提供电能保证系统能够正常运行, 水位传感器能够检测水田水位保证一定的水位。 显示屏可以显示温湿度信息和水位信息, 蓝牙传输模块能够将采集的信号都传输至手机APP,并实现图形化显示。 实现的功能: 1、通过蓝牙能够检测到水田的水位、温度、湿度。 2、通过USB +5V 供电 3、能够具有阈值报警的功能 4、阈值可以进行调节。 5、实现APP的温湿度信息监测,可在APP端图形化实时监测温度湿度变化。 */ sbit SW1=P3^7; sbit SW2=P3^6; sbit SW3=P3^5; sbit SW4=P3^4; sbit JR_LED=P2^2; sbit JW_LED=P2^4; sbit buzz=P3^3; uchar temp,humi; int sw_val=0; void delay_xms(int xms) { char ix=0; for(;xms>0;xms--) for(ix=110;ix>0;ix--); } uchar SET=0; char WdL=10; char WdH=30; char SdL=30; char SdH=80; char SWL=2; char SWH=6; char keyflag=0; uchar bj_flag=0; uchar Bj_CNt=0; uchar JCount=0; uchar clear_flag=0; uchar bj_clear=0; uint clear_cnt=0; void KeyRead(void) { if(!SW1) { if(!SW1&&keyflag==0) { keyflag=1; if(++SET>6)SET=0; while(!SW1); } } else if(!SW2) { if(!SW2&&keyflag==0) { keyflag=1; switch(SET) { case 1: if(++WdH>50)WdH=0; break; case 2: if(++WdL>50)WdL=0; break; case 3: if(++SdH>90)SdH=0; break; case 4: if(++SdL>90)SdH=0; break; case 5: if(++SWH>8)SWH=0; break; case 6: if(++SWL>8)SWL=0; break; } while(!SW2); } } else if(!SW3) { if(!SW3&&keyflag==0) { keyflag=1; switch(SET) { case 1: if(--WdH<0)WdH=50; break; case 2: if(--WdL<0)WdL=50; break; case 3: if(--SdH<0)SdH=90; break; case 4: if(--SdL<0)SdL=90; break; case 5: if(--SWH<0)SWH=8; break; case 6: if(--SWL<0)SWL=8; break; } while(!SW3); } } else if(!SW4) { if(!SW4&&keyflag==0) { bj_clear^=1; while(!SW4); } } else { keyflag=0; clear_cnt=0; } } void Timer0Init(void) //10毫秒@11.0592MHz { TMOD &= 0xF0; //设置定时器模式 TMOD |= 0x01; //设置定时器模式 TL0 = 0x00; //设置定时初值 TH0 = 0xDC; //设置定时初值 TF0 = 0; //清除TF0标志 ET0=1; TR0 = 1; //定时器0开始计时 EA=1; } void TimeISR()interrupt 1 { TL0 = 0x00; //设置定时初值 TH0 = 0xDC; //设置定时初值 KeyRead(); if((bj_flag==1)&&(bj_clear==0)) { if(++Bj_CNt>30) { Bj_CNt=0; buzz=~buzz; } }else { buzz=1; Bj_CNt=0; } JCount++; } void UartInit(void) //9600bps@11.0592MHz { PCON &= 0x7F; //波特率不倍速 SCON = 0x50; //8位数据,可变波特率 TMOD &= 0x0F; //清除定时器1模式位 TMOD |= 0x20; //设定定时器1为8位自动重装方式 TL1 = 0xFD; //设定定时初值 TH1 = 0xFD; //设定定时器重装值 ET1 = 0; //禁止定时器1中断 TR1 = 1; //启动定时器1 EA=1; ES=0; } void sendData(char *p,unsigned char n) { if( p == 0) return ; ES = 0; if(n > 0) { while(n --) { SBUF = *p++ ; while(!TI) ; TI = 0 ; } } // ES = 1; } // 往串口发送字符串 void sendString(char *p) { if(p == 0) return ; sendData(p,strlen(p)); } // 接收中断函数 void usart() interrupt 4 { if(RI == 1) { // setUsartRxData(SBUF); } RI = 0; TI = 0; } //char xdata showbuff[16]={0}; char data send_buff[17]={0}; sbit IN_PL = P2^0; //SHIFT/!LOA引脚 sbit IN_Data = P2^2; // QH数据输出引脚 sbit SCK = P2^1; //CLOCK引脚 unsigned char Read74HC165(void) { unsigned char indata; unsigned char i; IN_PL = 0;//装载8位并行数据 _nop_(); IN_PL = 1;//转换8位并行数据为串行数据 _nop_(); indata = 0; for(i = 0; i < 8; i ++) //将8个串行数据存入数组indata中 { indata = indata << 1;//开始时,indata数组先左移一位,以后每个循环左移一次 SCK = 0;//时钟低电平到来后,并行数据开始转换串行数据 _nop_(); indata |= IN_Data; //将转换完成的串行数据一位位存入数组 SCK = 1; //时钟变为高电平,再次变为低电平时,开始传出下一位串行数据 } return indata; } char find_bit(unsigned char dat) { char i=0; char cnt=0; for(i=0;i<8;i++) { if(!(dat&0x01)) { cnt++; } dat>>=1; } return cnt; } void main() { lcd1602_init(); UartInit(); dht11_value(&temp,&humi,DHT11_UINT8); buzz=1; delay_xms(200); dht11_value(&temp,&humi,DHT11_UINT8); Timer0Init(); while(1) { if(JCount>50)//500ms采集一次 { JCount=0; if(SET==0) { if(clear_flag==1) { clear_flag=0; Write_1602_com(0x01);//清显示 delay_1ms(100); } sw_val = find_bit(Read74HC165()); dht11_value(&temp,&humi,DHT11_UINT8); L1602_printf(0,0,"temp:%2d",(int)temp); L1602_printf(0,1,"humi:%2d",(int)humi); L1602_printf(12,0,"%s","SW"); L1602_printf(12,1,"%2dcm",(int)sw_val); if((tempWdH)||(humiSdH)||(sw_valSWH)) { bj_flag=1; }else { bj_flag=0; } sprintf(send_buff,"X%dH%dD%dZ\r\n",(int)temp,(int)humi,(int)sw_val); sendString(send_buff); } else { if(clear_flag==0) { clear_flag=1; Write_1602_com(0x01);//清显示 delay_1ms(100); } switch(SET) { case 1: case 2: WriteLcd1602_String(0,0,"Set temp"); L1602_printf(0,1,"H:%2d L:%2d",(int)WdH,(int)WdL); break; case 3: case 4: WriteLcd1602_String(0,0,"Set humi"); L1602_printf(0,1,"H:%2d L:%2d",(int)SdH,(int)SdL); break; case 5: case 6: WriteLcd1602_String(0,0,"Set SW "); L1602_printf(0,1,"H:%2d L:%2d",(int)SWH,(int)SWL); break; } } } } }