水环境系统的设计,完成了池塘中的循迹以及水环境的监测
单片机源程序如下:
- //定义头文件
- #include <STC12C5A60S2.H>
- #include <math.h> //Keil library
- #include <stdio.h>
- #include <intrins.h>
- //定义引脚、常量和变量
- sbit LCD12864_RS = P1^2; //RS控制引脚
- sbit LCD12864_RW = P1^1; //RW控制引脚
- sbit LCD12864_EN = P1^0; //EN控制引脚
- sbit LCD12864_PSB = P1^6; //CS1模式选择引脚,ST7920控制器,1为8位并行接口,0为串行接口
- sbit DQ=P1^5; //18B20温度传感器引脚
- sbit dianji0=P0^0;
- sbit dianji1=P0^1;
- sbit dianji2=P0^2;
- // PH接 = P1^4;
- // LM35接 = P1^3;
- #define LCDPORT P2 //数据引脚
- unsigned char ucStr1[] = "温度内: 00.00 度"; //显示信息1
- unsigned char ucStr2[] = "温度外: 00.00 度"; //显示信息2
- unsigned char ucStr3[] = " PH 值: 00.00 "; //显示信息3
- unsigned char code ucStr4[] = "鱼塘环境监控系统"; //显示信息4
- unsigned char code ucStr5[] = "硬件初始化中...."; //显示信息4
- unsigned char code ucStr6[] = " 10 % "; //显示信息4
- unsigned char code ucStr7[] = " 20 % "; //显示信息4
- unsigned char code ucStr8[] = " 30 % "; //显示信息4
- unsigned char code ucStr9[] = " 40 % "; //显示信息4
- unsigned char code ucStr10[] = " 50 % "; //显示信息4
- unsigned char code ucStr11[] = " 60 % "; //显示信息4
- unsigned char code ucStr12[] = " 70 % "; //显示信息4
- unsigned char code ucStr13[] = " 80 % "; //显示信息4
- unsigned char code ucStr14[] = " 90 % "; //显示信息4
- unsigned char code ucStr15[] = "100 % "; //显示信息4
- unsigned char code b1[]=" go\n ",b2[]=" left\n ",b3[]=" right\n ";
- unsigned int x,y;
- unsigned char flag,a;
- //需要串口发送到GSM模块的字符串
- unsigned char code UartAT8[] = "AT\r\n";
- unsigned char code UartAT1[] = "AT+CSTT\r\n";
- unsigned char code UartAT2[] = "AT+CIICR\r\n";
- unsigned char code UartAT3[] = "AT+CIFSR\r\n";
- unsigned char code UartAT4[] = "AT+CIPSTART=\"TCP\",\"123.206.21.219\",8080\r\n";
- unsigned char code UartAT5[] = "AT+CIPSEND\r\n";
- unsigned char UartAT6[] = "t1=00.00 t2=00.00 PH=00.00<br />";
- // 0123456789012345678901234567890
- char code UartAT7[] = {0x1A};
- unsigned char code UartAT9[] = "\r\n";
- /*
- 任务
- 需处理计算
- 1.温度LM35
- 2.温度18B20
- 3.PH
- 需输出显示
- 1.串口输出
- 2.12864显示
- */
- //AD检测PH和温度1
- void delayAD(unsigned int a) //延时约1ms
- {
- unsigned int i;
- while (--a!=0)
- for(i=600;i>0;i--); //1T单片机i=600,若是12T单片机i=125
- }
- void AD_init() //AD初始化
- {
- P1ASF=0x18; //P1口全部作为模拟功能AD使用
- ADC_RES=0; //清零转换结果寄存器高8位
- ADC_RESL=0; //清零转换结果寄存器低2位
- ADC_CONTR=0x80;//开启AD电源
- delayAD(2); //等待1ms,让AD电源稳定
- }
- unsigned int AD_get(unsigned char channel)
- {
- ADC_CONTR=0x88|channel; //开启AD转换1000 1000 即POWER SPEED1 SPEED0 ADC_FLAG ADC_START CHS2 CHS1 CHS0
- _nop_(); _nop_(); _nop_(); _nop_();//要经过4个CPU时钟的延时,其值才能够保证被设置进ADC_CONTR 寄存器
- while(!(ADC_CONTR&0x10)); //等待转换完成
- ADC_CONTR&=0xe7; //关闭AD转换,ADC_FLAG位由软件清0
- return(ADC_RES*4+ADC_RESL); //返回AD转换完成的10位数据(16进制)
- }
- float AD_work(unsigned char channel)
- {
- float AD_val; //定义处理后的数值AD_val为浮点数
- unsigned char i;
- for(i=0;i<250;i++)
- AD_val+=AD_get(channel); //转换100次求平均值(提高精度)
- AD_val/=250;
- AD_val=(AD_val*5)/1024; //AD的参考电压是单片机上的5v,所以乘5即为实际电压值
- return AD_val;
- }
- void chuliLM35wendu(void)
- {
- float ADLM35 = AD_work(3);
- int wenduLM35 = (int)(ADLM35*10000/3);
- ucStr1[8] = wenduLM35/1000+0x30;
- UartAT6[3] = ucStr1[8];
- ucStr1[9] = wenduLM35%1000/100+0x30;
- UartAT6[4] = ucStr1[9];
- ucStr1[11] = wenduLM35%100/10+0x30;
- UartAT6[6] = ucStr1[11];
- ucStr1[12] = wenduLM35%10+0x30;
- UartAT6[7] = ucStr1[12];
- }
- void PH(void)
- {
- float PHAD = AD_work(4);
- int PH = (23.34-5.51*PHAD)*100;
- ucStr3[8] = PH/1000+0x30;
- ucStr3[9] = PH%1000/100+0x30;
- ucStr3[11] = PH%100/10+0x30;
- ucStr3[12] = PH%10+0x30;
- UartAT6[23] = ucStr3[8];
- UartAT6[24] = ucStr3[9];
- UartAT6[26] = ucStr3[11];
- UartAT6[27] = ucStr3[12];
- }
-
- //单总线检测18B20
-
- void Delay18B20_us(unsigned int uiUs) //us延时函数
- {
- for(;uiUs > 0;uiUs--)
- {
- _nop_();
- }
- }
- void Delay18B20_ms(unsigned int uiMs) //ms延时函数
- {
- unsigned int i;
- for(;uiMs > 0;uiMs--)
- {
- for(i = 1498;i > 0;i--);
- }
- }
- void DS18B20_Init(void)
- {
- unsigned char x=0;
-
- DQ = 1; //DQ复位
- Delay18B20_us(10);
- //Delay(8); //稍做延时,10us
- DQ = 0; //单片机将DQ拉低
- Delay18B20_us(700);
- //Delay(80); //精确延时 大于 480us ,498us
- DQ = 1; //拉高总线
- Delay18B20_us(60);
- //Delay(14); //154us
- x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
- Delay18B20_us(60);
- //Delay(20); //212us
-
- }
- void DS18B20_WriteOneChar(unsigned char dat)
- {
- unsigned char i=0;
- for (i=8; i>0; i--)
- {
- DQ = 0;
- Delay18B20_us(4);
- DQ = dat&0x01;
- Delay18B20_us(59);
- //Delay(5); //66us
- DQ = 1;
- Delay18B20_us(4);
- dat>>=1;
- }
- }
- unsigned char DS18B20_ReadOneChar(void)
- {
- unsigned char i=0;
- unsigned char dat = 0;
- for (i=8;i>0;i--)
- {
- DQ = 0; // 给脉冲信号
- Delay18B20_us(4);
- dat>>=1;
- DQ = 1; // 给脉冲信号
- Delay18B20_us(9);
- if(DQ)
- dat|=0x80;
- Delay18B20_us(66);
- //Delay(4); //56us
- DQ = 1; // 给脉冲信号
- Delay18B20_us(4);
- }
- return(dat);
- }
-
- unsigned int DS18B20_ReadTemperature(void) //返回温度值
- {
- unsigned char tempL=0;
- unsigned char tempH=0;
- unsigned int sdate;//测量到的温度的整数部分
- unsigned char xiaoshu1;//小数第一位
- unsigned char xiaoshu2;//小数第二位
- unsigned char xiaoshu;//两位小数
- bit fg=1; //温度正负标志
- unsigned int t=0;
- DS18B20_Init();
- DS18B20_WriteOneChar(0xCC); // 跳过读序号列号的操作
- DS18B20_WriteOneChar(0x44); // 启动温度转换
- DS18B20_Init();
- DS18B20_WriteOneChar(0xCC); //跳过读序号列号的操作
- DS18B20_WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
- tempL=DS18B20_ReadOneChar();
- tempH=DS18B20_ReadOneChar();
- // t=b;
- // t<<=8;
- // t=t|a;
- // //t= t/2; //放大10倍输出并四舍五入---此行没用
- // return(t);
- if(tempH>0x7f) //最高位为1时温度是负
- {
- tempL=~tempL; //补码转换,取反加一
- tempH=~tempH+1;
- fg=0; //读取温度为负时fg=0
- }
- sdate = tempL/16+tempH*16; //整数部分
- xiaoshu1 = (tempL&0x0f)*10/16; //小数第一位
- xiaoshu2 = (tempL&0x0f)*100/16%10;//小数第二位
- xiaoshu=xiaoshu1*10+xiaoshu2; //小数两位
- //if(sdate>9)
-
- ucStr2[8] = sdate/10+0x30;
- UartAT6[13] = ucStr2[8];
- ucStr2[9] = sdate%10+0x30;
- UartAT6[14] = ucStr2[9];
-
- // else
- // {
- // ucStr2[8] = 0x00;
- // ucStr2[9] = sdate+0x30;
- // }
- ucStr2[11] = xiaoshu1+0x30;
- UartAT6[16] = ucStr2[11];
- ucStr2[12] = xiaoshu2+0x30;
- UartAT6[17] = ucStr2[12];
- return 0;
- }
- //12864显示数据
- /******************************************************************************
- 函数名称:Delay
- 函数功能:延时函数
- 入口参数:uiCount-延时参数
- 返回值:无
- 备注:无
- *******************************************************************************/
- void DelayL(unsigned int uiCount)
- {
- while(uiCount--);
- }
- /******************************************************************************
- 函数名称:LCD12864_CheckBusy
- 函数功能:忙检测
- 入口参数:无
- 返回值:无
- 备注:使用变量i做计时,避免液晶在死循环处停滞。
- *******************************************************************************/
- void LCD12864_CheckBusy(void)
- {
- unsigned char i = 250; //局部变量
- LCD12864_RS = 0; //拉低
- LCD12864_RW = 1; //拉高
- LCD12864_EN = 1; //使能
- while((i > 0) && (P0 & 0x80))i--; //判断忙标志位
- LCD12864_EN = 0; //释放
- }
- /******************************************************************************
- 函数名称:LCD12864_WriteInfomation
- 函数功能:向LCD12864写入命令或者数据
- 入口参数:ucData-要写入液晶的数据或者命令的内容
- bComOrData-命令或者数据的标志位选择,0或者1,其中
- 1:写入的是数据
- 0:写入的是命令
- 返回值:无
- 备注:无
- *******************************************************************************/
- void LCD12864_WriteInfomation(unsigned char ucData,bit bComOrData)
- {
- LCD12864_CheckBusy(); //忙检测
- LCD12864_RW = 0; //拉低RW
- LCD12864_RS = bComOrData; //根据标志位判断写入的是命令还是数据
- DelayL(150); //延时,等待操作
- LCDPORT = ucData; //将数据送至数据端口
- LCD12864_EN = 1; //使能信号
- DelayL(150); //延时
- LCD12864_EN = 0; //按照时序来操作
- DelayL(150);
- }
- /******************************************************************************
- 函数名称:LCD12864_Init
- 函数功能:LCD12864液晶初始化
- 入口参数:无
- 返回值:无
- 备注:无
- *******************************************************************************/
- void LCD12864_Init(void)
- {
- DelayL(400);//延时
- LCD12864_PSB = 1; //8位并口工作模式
- DelayL(150);//延时
- LCD12864_WriteInfomation(0x30,0); //基本指令集
- DelayL(150);
- LCD12864_WriteInfomation(0x08,0); //显示设置
- DelayL(150);
- LCD12864_WriteInfomation(0x10,0); //光标设置
- DelayL(150);
- LCD12864_WriteInfomation(0x0c,0); //游标设置
- DelayL(150);
- LCD12864_WriteInfomation(0x01,0); //清屏
- DelayL(150);
- LCD12864_WriteInfomation(0x06,0); //进入点设定
- DelayL(150);
-
- }
- /******************************************************************************
- 函数名称:LCD12864_DisplayOneLine
- 函数功能:显示一行汉字(8个汉字或者16个英文字符)
- 入口参数:position-要显示的行的首地址,可选值0x80,0x88,0x90,0x98,其中:
- 0x80:液晶的第一行;
- 0x88:液晶的第三行;
- 0x90:液晶的第二行;
- 0x98:液晶的第四行。
- p-要显示的内容的首地址。
- 返回值:无
- 备注:无
- *******************************************************************************/
- void LCD12864_DisplayOneLine(unsigned char position,unsigned char *p)
- {
- unsigned char i;
- LCD12864_WriteInfomation(position,0);//写入要显示文字的行的首地址
- DelayL(150);
- for(i = 0;i<16;i++) //依次执行写入操作
- {
- LCD12864_WriteInfomation(*p,1);
- p++;
- }
- }
- void Delay10000ms() //@11.0592MHz开机用延时10秒
- {
- unsigned char i, j, k;
- i = 165;
- j = 59;
- k = 28;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
- void fangxiang()
- {
- switch(a)//判断a从串口读取到的数据
- {
- case 49://如果是0x1f就前进
- if(flag==1)
- {
- ES=0;
- flag=0;
- for(x=0;b1[x]!='\0';x++)
- {
- SBUF=b1[x];//28;
- while(!TI);
- TI=0; }
- ES=1;
- }
- dianji0=0;
- a=0;
- break;
- case 50://如果是0x2f就后退
- if(flag==1)
- {
- ES=0;
- flag=0;
- for(x=0;b2[x]!='\0';x++)
- {
- SBUF=b2[x];//28;
- while(!TI);
- TI=0; }
- ES=1;
- }
- dianji1=0;
- a=0;
- break;
- case 51://如果是0x3f就左转
- if(flag==1)
- {
- ES=0;
- flag=0;
- for(x=0;b3[x]!='\0';x++)
- {
- SBUF=b3[x];//28;
- while(!TI);
- TI=0; }
- ES=1;
- }
- a=0;
- dianji2=0;
- break;
- case 52://如果是0x1f就前进
- if(flag==1)
- {
- ES=0;
- flag=0;
- for(x=0;b1[x]!='\0';x++)
- {
- SBUF=b1[x];//28;
- while(!TI);
- TI=0; }
- ES=1;
- }
- dianji0=1;
- dianji1=1;
- dianji2=1;
- a=0;
- break;
- }
- }
- void init()//初始化子程序
- {
- TMOD=0x20; //设置定时器T1为工作方式2
- TH1=0xfd;
- TL1=0xfd; //T1定时器装初值
- TR1=1; //启动定时器T1
- REN=1; //允许串口接收
- SM0=0;
- SM1=1; //设置串口工作方式1
- EA=1; //开总中断
- ES=1; //开串口中断
- }
- //主函数
-
- void main(void)
- { init();
- AD_init(); //ADinit
- LCD12864_Init(); //初始化液晶
- /* LCD12864_DisplayOneLine(0x98,ucStr4); //显示信息4
- LCD12864_DisplayOneLine(0x90,ucStr5); //显示信息2
- Delay10000ms();
- LCD12864_DisplayOneLine(0x88,ucStr6); //显示信息3
- Delay10000ms();
- LCD12864_DisplayOneLine(0x88,ucStr7); //显示信息3
- Delay10000ms();
- LCD12864_DisplayOneLine(0x88,ucStr8); //显示信息3
- Delay10000ms();
- LCD12864_DisplayOneLine(0x88,ucStr9); //显示信息3
- Delay10000ms();
- LCD12864_DisplayOneLine(0x88,ucStr10); //显示信息3
- Delay10000ms();
- LCD12864_DisplayOneLine(0x88,ucStr11); //显示信息3
- Delay10000ms();
- LCD12864_DisplayOneLine(0x88,ucStr12); //显示信息3
- Delay10000ms();
- LCD12864_DisplayOneLine(0x88,ucStr13); //显示信息3
- Delay10000ms();
- LCD12864_DisplayOneLine(0x88,ucStr14); //显示信息3
- Delay10000ms();
- LCD12864_DisplayOneLine(0x88,ucStr15); //显示信息3
- Delay18B20_ms(500);*/
-
- while(1)
- { fangxiang();
- chuliLM35wendu(); //LM35xianshi
- PH(); //PHADxianshi
- DS18B20_ReadTemperature(); //18B20xianshi
- LCD12864_DisplayOneLine(0x80,ucStr1); //显示信息1
- LCD12864_DisplayOneLine(0x90,ucStr2); //显示信息2
- LCD12864_DisplayOneLine(0x88,ucStr3); //显示信息3
- Delay18B20_ms(50);
-
- }
- }
- void chuan() interrupt 4//串口中断服务程序
- {
- RI=0;//软件清除串口响应
- a=SBUF;//读取单片机串口接受的蓝牙模块发送的数据
- flag=1;
- }
复制代码
所有资料51hei提供下载:
池塘巡检1.2(完成蓝牙控制电机).rar
(59.68 KB, 下载次数: 18)
|