水環境系統的設計,完成了池塘中的循跡以及水環境的監測
單片機源程序如下:
- //定義頭文件
- #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)
2019-5-15 10:47 上傳
點擊文件名下載附件
水環境循跡+監測 下載積分: 黑幣 -5
|