找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1294|回复: 1
打印 上一主题 下一主题
收起左侧

单片机水环境监测系统程序设计 蓝牙控制电机

[复制链接]
跳转到指定楼层
楼主
ID:538659 发表于 2019-5-15 10:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
水环境系统的设计,完成了池塘中的循迹以及水环境的监测

单片机源程序如下:
  1. //定义头文件
  2. #include <STC12C5A60S2.H>
  3. #include <math.h>    //Keil library  
  4. #include <stdio.h>  
  5. #include <intrins.h>

  6. //定义引脚、常量和变量
  7. sbit LCD12864_RS  =  P1^2;         //RS控制引脚
  8. sbit LCD12864_RW  =  P1^1;         //RW控制引脚
  9. sbit LCD12864_EN  =  P1^0;         //EN控制引脚
  10. sbit LCD12864_PSB =  P1^6;          //CS1模式选择引脚,ST7920控制器,1为8位并行接口,0为串行接口
  11. sbit DQ=P1^5;        //18B20温度传感器引脚
  12. sbit dianji0=P0^0;
  13. sbit dianji1=P0^1;
  14. sbit dianji2=P0^2;
  15. //   PH接                                   =  P1^4;
  16. //         LM35接                          =  P1^3;
  17. #define LCDPORT P2                //数据引脚
  18. unsigned char            ucStr1[]  =  "温度内: 00.00 度";                //显示信息1
  19. unsigned char            ucStr2[]  =  "温度外: 00.00 度";                //显示信息2
  20. unsigned char            ucStr3[]  =  " PH 值: 00.00   ";                //显示信息3
  21. unsigned char code ucStr4[]  =  "鱼塘环境监控系统";                //显示信息4
  22. unsigned char code ucStr5[]  =  "硬件初始化中....";                //显示信息4
  23. unsigned char code ucStr6[]  =  " 10 %           ";                //显示信息4
  24. unsigned char code ucStr7[]  =  " 20 %           ";                //显示信息4
  25. unsigned char code ucStr8[]  =  " 30 %           ";                //显示信息4
  26. unsigned char code ucStr9[]  =  " 40 %           ";                //显示信息4
  27. unsigned char code ucStr10[] =  " 50 %           ";                //显示信息4
  28. unsigned char code ucStr11[] =  " 60 %           ";                //显示信息4
  29. unsigned char code ucStr12[] =  " 70 %           ";                //显示信息4
  30. unsigned char code ucStr13[] =  " 80 %           ";                //显示信息4
  31. unsigned char code ucStr14[] =  " 90 %           ";                //显示信息4
  32. unsigned char code ucStr15[] =  "100 %           ";                //显示信息4
  33. unsigned char code b1[]=" go\n ",b2[]=" left\n ",b3[]=" right\n ";
  34. unsigned int x,y;
  35. unsigned char flag,a;
  36. //需要串口发送到GSM模块的字符串

  37. unsigned char code UartAT8[] = "AT\r\n";
  38. unsigned char code UartAT1[] = "AT+CSTT\r\n";
  39. unsigned char code UartAT2[] = "AT+CIICR\r\n";
  40. unsigned char code UartAT3[] = "AT+CIFSR\r\n";
  41. unsigned char code UartAT4[] = "AT+CIPSTART=\"TCP\",\"123.206.21.219\",8080\r\n";
  42. unsigned char code UartAT5[] = "AT+CIPSEND\r\n";
  43. unsigned char      UartAT6[] = "t1=00.00  t2=00.00  PH=00.00<br />";
  44.                              // 0123456789012345678901234567890
  45.                                  char code UartAT7[] = {0x1A};
  46. unsigned char code UartAT9[] = "\r\n";                 


  47. /*  
  48.         任务
  49.         需处理计算
  50.         1.温度LM35
  51.         2.温度18B20
  52.         3.PH
  53.         需输出显示
  54.         1.串口输出
  55.         2.12864显示
  56. */
  57. //AD检测PH和温度1
  58.                         void delayAD(unsigned int a) //延时约1ms
  59.                         {
  60.                                                 unsigned int i;
  61.                                                 while (--a!=0)
  62.                                                 for(i=600;i>0;i--);   //1T单片机i=600,若是12T单片机i=125
  63.                         }
  64.                         void AD_init()                        //AD初始化
  65.                         {
  66.                                                 P1ASF=0x18; //P1口全部作为模拟功能AD使用
  67.                                                 ADC_RES=0;   //清零转换结果寄存器高8位
  68.                                                 ADC_RESL=0; //清零转换结果寄存器低2位
  69.                                                 ADC_CONTR=0x80;//开启AD电源
  70.                                                 delayAD(2);   //等待1ms,让AD电源稳定
  71.                         }
  72.                         unsigned int AD_get(unsigned char channel)
  73.                         {
  74.                                                 ADC_CONTR=0x88|channel;    //开启AD转换1000 1000 即POWER SPEED1 SPEED0 ADC_FLAG   ADC_START CHS2 CHS1 CHS0
  75.                                                 _nop_(); _nop_(); _nop_(); _nop_();//要经过4个CPU时钟的延时,其值才能够保证被设置进ADC_CONTR 寄存器
  76.                                                 while(!(ADC_CONTR&0x10));    //等待转换完成
  77.                                                 ADC_CONTR&=0xe7;      //关闭AD转换,ADC_FLAG位由软件清0
  78.                                                 return(ADC_RES*4+ADC_RESL);   //返回AD转换完成的10位数据(16进制)
  79.                         }

  80.                         float AD_work(unsigned char channel)
  81.                         {
  82.                                                 float AD_val;     //定义处理后的数值AD_val为浮点数
  83.                                                 unsigned char i;
  84.                                                 for(i=0;i<250;i++)
  85.                                                 AD_val+=AD_get(channel); //转换100次求平均值(提高精度)
  86.                                                 AD_val/=250;
  87.                                                 AD_val=(AD_val*5)/1024; //AD的参考电压是单片机上的5v,所以乘5即为实际电压值
  88.                                                 return AD_val;
  89.                         }
  90.                         void chuliLM35wendu(void)
  91.                         {
  92.                                         float ADLM35 = AD_work(3);
  93.                                         int  wenduLM35 = (int)(ADLM35*10000/3);
  94.                                         ucStr1[8] = wenduLM35/1000+0x30;
  95.                                                 UartAT6[3] = ucStr1[8];
  96.                                         ucStr1[9] = wenduLM35%1000/100+0x30;
  97.                                                 UartAT6[4] = ucStr1[9];
  98.                                         ucStr1[11] = wenduLM35%100/10+0x30;
  99.                                                 UartAT6[6] = ucStr1[11];
  100.                                         ucStr1[12] = wenduLM35%10+0x30;
  101.                                                 UartAT6[7] = ucStr1[12];
  102.                         }
  103.                         void PH(void)
  104.                         {
  105.                                         float PHAD = AD_work(4);
  106.                                         int   PH   = (23.34-5.51*PHAD)*100;
  107.                                   ucStr3[8] = PH/1000+0x30;
  108.                                         ucStr3[9] = PH%1000/100+0x30;
  109.                                         ucStr3[11] = PH%100/10+0x30;
  110.                                         ucStr3[12] = PH%10+0x30;
  111.                                 UartAT6[23] = ucStr3[8];
  112.                                 UartAT6[24] = ucStr3[9];
  113.                                 UartAT6[26] = ucStr3[11];
  114.                                 UartAT6[27] = ucStr3[12];
  115.                         }
  116.                
  117. //单总线检测18B20
  118.        
  119.                 void Delay18B20_us(unsigned int uiUs)        //us延时函数
  120.                 {
  121.                                         for(;uiUs > 0;uiUs--)
  122.                                                 {
  123.                                                         _nop_();
  124.                                                 }       
  125.                 }



  126.                 void Delay18B20_ms(unsigned int uiMs)        //ms延时函数
  127.                 {
  128.                                 unsigned int i;
  129.                                                 for(;uiMs > 0;uiMs--)
  130.                                                 {
  131.                                                                 for(i = 1498;i > 0;i--);
  132.                                                 }
  133.                 }               
  134.                 void DS18B20_Init(void)
  135.                 {
  136.                         unsigned char x=0;
  137.                        
  138.                         DQ = 1;    //DQ复位
  139.                         Delay18B20_us(10);
  140.                         //Delay(8);  //稍做延时,10us
  141.                         DQ = 0;    //单片机将DQ拉低
  142.                         Delay18B20_us(700);
  143.                         //Delay(80); //精确延时 大于 480us ,498us
  144.                         DQ = 1;    //拉高总线
  145.                         Delay18B20_us(60);
  146.                         //Delay(14);        //154us
  147.                         x=DQ;      //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
  148.                         Delay18B20_us(60);
  149.                         //Delay(20); //212us
  150.                        
  151.                 }

  152.                 void DS18B20_WriteOneChar(unsigned char dat)
  153.                 {
  154.                         unsigned char i=0;
  155.                         for (i=8; i>0; i--)
  156.                         {
  157.                                 DQ = 0;
  158.                                 Delay18B20_us(4);
  159.                                 DQ = dat&0x01;
  160.                                 Delay18B20_us(59);
  161.                                 //Delay(5); //66us
  162.                                 DQ = 1;
  163.                                 Delay18B20_us(4);
  164.                                 dat>>=1;
  165.                         }
  166.                 }

  167.                 unsigned char DS18B20_ReadOneChar(void)
  168.                 {
  169.                         unsigned char i=0;
  170.                         unsigned char dat = 0;
  171.                         for (i=8;i>0;i--)
  172.                         {
  173.                                 DQ = 0; // 给脉冲信号
  174.                                 Delay18B20_us(4);
  175.                                 dat>>=1;
  176.                                 DQ = 1; // 给脉冲信号
  177.                                 Delay18B20_us(9);
  178.                                 if(DQ)
  179.                                 dat|=0x80;
  180.                                 Delay18B20_us(66);
  181.                                 //Delay(4); //56us
  182.                                 DQ = 1; // 给脉冲信号
  183.                                 Delay18B20_us(4);
  184.                         }
  185.                         return(dat);
  186.                 }
  187.                
  188.                 unsigned int DS18B20_ReadTemperature(void)                                        //返回温度值
  189.                 {
  190.                         unsigned char tempL=0;
  191.                         unsigned char tempH=0;
  192.                         unsigned int sdate;//测量到的温度的整数部分
  193.                         unsigned char xiaoshu1;//小数第一位
  194.                         unsigned char xiaoshu2;//小数第二位
  195.                         unsigned char xiaoshu;//两位小数
  196.                         bit  fg=1;        //温度正负标志
  197.                         unsigned int t=0;
  198.                         DS18B20_Init();
  199.                         DS18B20_WriteOneChar(0xCC); // 跳过读序号列号的操作
  200.                         DS18B20_WriteOneChar(0x44); // 启动温度转换
  201.                         DS18B20_Init();
  202.                         DS18B20_WriteOneChar(0xCC); //跳过读序号列号的操作
  203.                         DS18B20_WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
  204.                         tempL=DS18B20_ReadOneChar();
  205.                         tempH=DS18B20_ReadOneChar();
  206. //                        t=b;
  207. //                        t<<=8;
  208. //                        t=t|a;
  209. //                        //t= t/2; //放大10倍输出并四舍五入---此行没用
  210. //                        return(t);
  211.                         if(tempH>0x7f)      //最高位为1时温度是负
  212.                                         {
  213.                                          tempL=~tempL;         //补码转换,取反加一
  214.                                          tempH=~tempH+1;      
  215.                                          fg=0;      //读取温度为负时fg=0
  216.                                     }
  217.                                 sdate = tempL/16+tempH*16;      //整数部分
  218.                                 xiaoshu1 = (tempL&0x0f)*10/16; //小数第一位
  219.                                 xiaoshu2 = (tempL&0x0f)*100/16%10;//小数第二位
  220.                                 xiaoshu=xiaoshu1*10+xiaoshu2; //小数两位
  221.                                         //if(sdate>9)
  222.                                        
  223.                                         ucStr2[8] = sdate/10+0x30;
  224.                                                 UartAT6[13] = ucStr2[8];
  225.                                         ucStr2[9] = sdate%10+0x30;
  226.                                                 UartAT6[14] = ucStr2[9];
  227.                                        
  228. //                                        else
  229. //                                        {
  230. //                                                        ucStr2[8] = 0x00;
  231. //                                                        ucStr2[9] = sdate+0x30;
  232. //                                        }
  233.                                         ucStr2[11] = xiaoshu1+0x30;
  234.                                                 UartAT6[16] = ucStr2[11];
  235.                                         ucStr2[12] = xiaoshu2+0x30;
  236.                                                 UartAT6[17] = ucStr2[12];
  237.                         return 0;
  238.                 }


  239. //12864显示数据


  240.                 /******************************************************************************
  241.                 函数名称:Delay
  242.                 函数功能:延时函数
  243.                 入口参数:uiCount-延时参数
  244.                 返回值:无
  245.                 备注:无
  246.                 *******************************************************************************/
  247.                 void DelayL(unsigned int uiCount)
  248.                 {
  249.                         while(uiCount--);
  250.                 }
  251.                 /******************************************************************************
  252.                 函数名称:LCD12864_CheckBusy
  253.                 函数功能:忙检测
  254.                 入口参数:无
  255.                 返回值:无
  256.                 备注:使用变量i做计时,避免液晶在死循环处停滞。
  257.                 *******************************************************************************/
  258.                 void LCD12864_CheckBusy(void)
  259.                 {
  260.                         unsigned char i = 250;        //局部变量
  261.                         LCD12864_RS = 0;          //拉低
  262.                         LCD12864_RW = 1;          //拉高
  263.                         LCD12864_EN = 1;          //使能
  264.                         while((i > 0) && (P0 & 0x80))i--;  //判断忙标志位
  265.                         LCD12864_EN = 0;          //释放
  266.                 }
  267.                 /******************************************************************************
  268.                 函数名称:LCD12864_WriteInfomation
  269.                 函数功能:向LCD12864写入命令或者数据
  270.                 入口参数:ucData-要写入液晶的数据或者命令的内容
  271.                                   bComOrData-命令或者数据的标志位选择,0或者1,其中
  272.                                         1:写入的是数据
  273.                                         0:写入的是命令
  274.                 返回值:无
  275.                 备注:无
  276.                 *******************************************************************************/
  277.                 void LCD12864_WriteInfomation(unsigned char ucData,bit bComOrData)
  278.                 {
  279.                         LCD12864_CheckBusy();        //忙检测
  280.                         LCD12864_RW = 0;        //拉低RW
  281.                         LCD12864_RS = bComOrData;        //根据标志位判断写入的是命令还是数据
  282.                         DelayL(150);                                  //延时,等待操作
  283.                         LCDPORT = ucData;                  //将数据送至数据端口
  284.                         LCD12864_EN = 1;                  //使能信号
  285.                         DelayL(150);                                  //延时
  286.                         LCD12864_EN = 0;                //按照时序来操作
  287.                         DelayL(150);
  288.                 }
  289.                 /******************************************************************************
  290.                 函数名称:LCD12864_Init
  291.                 函数功能:LCD12864液晶初始化
  292.                 入口参数:无
  293.                 返回值:无
  294.                 备注:无
  295.                 *******************************************************************************/
  296.                 void LCD12864_Init(void)
  297.                 {
  298.                         DelayL(400);//延时
  299.                         LCD12864_PSB = 1;        //8位并口工作模式
  300.                         DelayL(150);//延时

  301.                         LCD12864_WriteInfomation(0x30,0); //基本指令集
  302.                         DelayL(150);
  303.                         LCD12864_WriteInfomation(0x08,0);  //显示设置
  304.                         DelayL(150);
  305.                         LCD12864_WriteInfomation(0x10,0);        //光标设置
  306.                         DelayL(150);
  307.                         LCD12864_WriteInfomation(0x0c,0);        //游标设置
  308.                         DelayL(150);
  309.                         LCD12864_WriteInfomation(0x01,0);  //清屏
  310.                         DelayL(150);
  311.                         LCD12864_WriteInfomation(0x06,0);        //进入点设定
  312.                         DelayL(150);
  313.                                
  314.                 }

  315.                 /******************************************************************************
  316.                 函数名称:LCD12864_DisplayOneLine
  317.                 函数功能:显示一行汉字(8个汉字或者16个英文字符)
  318.                 入口参数:position-要显示的行的首地址,可选值0x80,0x88,0x90,0x98,其中:
  319.                                         0x80:液晶的第一行;
  320.                                         0x88:液晶的第三行;
  321.                                         0x90:液晶的第二行;
  322.                                         0x98:液晶的第四行。
  323.                                   p-要显示的内容的首地址。
  324.                 返回值:无
  325.                 备注:无
  326.                 *******************************************************************************/
  327.                 void LCD12864_DisplayOneLine(unsigned char position,unsigned char *p)
  328.                 {
  329.                          unsigned char i;
  330.                          LCD12864_WriteInfomation(position,0);//写入要显示文字的行的首地址
  331.                          DelayL(150);

  332.                          for(i = 0;i<16;i++)                //依次执行写入操作
  333.                          {
  334.                                  LCD12864_WriteInfomation(*p,1);
  335.                                  p++;
  336.                          }
  337.                 }


  338. void Delay10000ms()                //@11.0592MHz开机用延时10秒
  339. {
  340.         unsigned char i, j, k;

  341.         i = 165;
  342.         j = 59;
  343.         k = 28;
  344.         do
  345.         {
  346.                 do
  347.                 {
  348.                         while (--k);
  349.                 } while (--j);
  350.         } while (--i);
  351. }

  352. void fangxiang()
  353. {
  354.   switch(a)//判断a从串口读取到的数据                                     
  355.                 {
  356.                         case 49://如果是0x1f就前进
  357.                         if(flag==1)
  358.                                 {
  359.                                         ES=0;
  360.                                         flag=0;
  361.                                         for(x=0;b1[x]!='\0';x++)
  362.                                         {
  363.                                         SBUF=b1[x];//28;       
  364.                                         while(!TI);       
  365.                                         TI=0;         }

  366.                                         ES=1;
  367.                                 }
  368.                                 dianji0=0;
  369.                                 a=0;
  370.                         break;

  371.                         case 50://如果是0x2f就后退
  372.                         if(flag==1)
  373.                                 {
  374.                                         ES=0;
  375.                                         flag=0;
  376.                                         for(x=0;b2[x]!='\0';x++)
  377.                                         {
  378.                                         SBUF=b2[x];//28;       
  379.                                         while(!TI);       
  380.                                         TI=0;         }

  381.                                         ES=1;
  382.                                 }
  383.                                 dianji1=0;
  384.                                 a=0;
  385.                         break;

  386.                         case 51://如果是0x3f就左转
  387.                         if(flag==1)
  388.                                 {
  389.                                         ES=0;
  390.                                         flag=0;
  391.                                         for(x=0;b3[x]!='\0';x++)
  392.                                         {
  393.                                         SBUF=b3[x];//28;       
  394.                                         while(!TI);       
  395.                                         TI=0;         }

  396.                                         ES=1;
  397.                                 }
  398.                                 a=0;
  399.                                 dianji2=0;
  400.                         break;

  401.                         case 52://如果是0x1f就前进
  402.                         if(flag==1)
  403.                                 {
  404.                                         ES=0;
  405.                                         flag=0;
  406.                                         for(x=0;b1[x]!='\0';x++)
  407.                                         {
  408.                                         SBUF=b1[x];//28;       
  409.                                         while(!TI);       
  410.                                         TI=0;         }

  411.                                         ES=1;
  412.                                 }
  413.                                 dianji0=1;
  414.                                 dianji1=1;
  415.                                 dianji2=1;
  416.                                 a=0;
  417.                         break;
  418.                 }
  419. }
  420. void init()//初始化子程序
  421. {
  422.         TMOD=0x20;                          //设置定时器T1为工作方式2
  423.         TH1=0xfd;
  424.         TL1=0xfd;                           //T1定时器装初值
  425.         TR1=1;                              //启动定时器T1
  426.         REN=1;                              //允许串口接收
  427.         SM0=0;
  428.         SM1=1;                              //设置串口工作方式1
  429.         EA=1;                               //开总中断
  430.         ES=1;                               //开串口中断
  431. }

  432. //主函数
  433.                
  434.                 void main(void)
  435.                 {                init();
  436.                                 AD_init();                                                                //ADinit
  437.                                 LCD12864_Init();                                                                                   //初始化液晶
  438.                         /*        LCD12864_DisplayOneLine(0x98,ucStr4);        //显示信息4
  439.                                 LCD12864_DisplayOneLine(0x90,ucStr5);        //显示信息2
  440.                                 Delay10000ms();
  441.                                 LCD12864_DisplayOneLine(0x88,ucStr6);        //显示信息3
  442.                                 Delay10000ms();
  443.                         LCD12864_DisplayOneLine(0x88,ucStr7);        //显示信息3
  444.                                 Delay10000ms();
  445.                         LCD12864_DisplayOneLine(0x88,ucStr8);        //显示信息3
  446.                                 Delay10000ms();
  447.                                 LCD12864_DisplayOneLine(0x88,ucStr9);        //显示信息3
  448.                                 Delay10000ms();
  449.                                 LCD12864_DisplayOneLine(0x88,ucStr10);        //显示信息3
  450.                                 Delay10000ms();
  451.                                 LCD12864_DisplayOneLine(0x88,ucStr11);        //显示信息3
  452.                                 Delay10000ms();
  453.                                 LCD12864_DisplayOneLine(0x88,ucStr12);        //显示信息3
  454.                                 Delay10000ms();
  455.                                 LCD12864_DisplayOneLine(0x88,ucStr13);        //显示信息3
  456.                                 Delay10000ms();
  457.                                         LCD12864_DisplayOneLine(0x88,ucStr14);        //显示信息3
  458.                                         Delay10000ms();
  459.                                         LCD12864_DisplayOneLine(0x88,ucStr15);        //显示信息3
  460.                                         Delay18B20_ms(500);*/               
  461.                        


  462.                                 while(1)
  463.                                 {         fangxiang();
  464.                                         chuliLM35wendu();                                                                                //LM35xianshi
  465.                                         PH();                                                                                                                                //PHADxianshi
  466.                                         DS18B20_ReadTemperature();                                                //18B20xianshi
  467.                                         LCD12864_DisplayOneLine(0x80,ucStr1);        //显示信息1
  468.                                         LCD12864_DisplayOneLine(0x90,ucStr2);        //显示信息2
  469.                                         LCD12864_DisplayOneLine(0x88,ucStr3);        //显示信息3
  470.                                         Delay18B20_ms(50);       
  471.                                
  472.                                 }
  473.                 }
  474. void chuan() interrupt 4//串口中断服务程序
  475. {
  476.         RI=0;//软件清除串口响应
  477.         a=SBUF;//读取单片机串口接受的蓝牙模块发送的数据
  478.         flag=1;
  479. }
复制代码

所有资料51hei提供下载:
池塘巡检1.2(完成蓝牙控制电机).rar (59.68 KB, 下载次数: 18)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1 发表于 2019-5-15 21:15 | 只看该作者
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表