找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3188|回复: 5
收起左侧

17年电赛简易水情检测系统单片机代码

[复制链接]
ID:129825 发表于 2019-3-30 13:58 | 显示全部楼层 |阅读模式
17年电赛P题

单片机源程序如下:
  1. #include <STC15F2K60S2.H>// 包含STC115F2K60S2单片机寄存器定义文件   
  2. #define VCC 5.0   // 存放用万用表实测的单片机供电电压
  3. #include <intrins.h>                                           
  4. #define uchar unsigned char
  5. #define uint  unsigned int
  6. unsigned int ADvalue;            // 存放AD转换返回的结果

  7. sbit ADC_SCK=P2^6 ;//ADC时钟
  8. sbit ADC_DIN= P2^7;//ADC数据入
  9. sbit ADC_DOUT=P2^4;  //ADC数据出
  10. sbit ADC_DBY=P2^5;//ADC准备
  11. unsigned int channal1;

  12. sbit RS=P0^0;            //片选信号        rs        CS
  13. sbit RW=P0^1;                //数据信号        rw          SID
  14. sbit E=P0^2;                //时钟信号   e                 SCLK

  15. sbit RST=P0^6;                //复位信号
  16. sbit PSB = P0^7;                //并行、串行选择信号         psb   CH

  17. sbit c_send   = P3^3;                //超声波发射          t
  18. sbit c_recive = P3^2;                //超声波接收         e
  19. uchar flag_hc_value;        //超声波中间变量

  20. long distance;                //距离
  21. uint set_d;                    //距离
  22. bit flag_csb_juli;      //超声波超出量程
  23. uint  flag_time0;      //用来保存定时器0的时候的
  24. uint time;

  25. /********************************************************************
  26. * 名称 : delay()
  27. * 功能 : 延时,延时时间为 100us * t。这是通过软件延时,有一定误差。
  28. * 输入 : t
  29. * 输出 : 无
  30. ***********************************************************************/
  31. void delay(unsigned int t)
  32. {
  33.         unsigned int i,j;
  34.         for(i=0; i<t;  i++)
  35.     for(j=0; j<10; j++);
  36. }
  37. void Delay_ms(unsigned int n)
  38. {
  39.         unsigned int  i,j;
  40.         for(i=0;i<n;i++)
  41.                 for(j=0;j<123;j++);
  42. }

  43. void UART_init(void)
  44. {                  
  45.         //下面代码设置定时器1
  46.         TMOD = 0x20;        // 0010 0000 定时器1工作于方式2(8位自动重装方式)
  47.         TH1  = 0xFD;        // 波特率:9600 /11.0592MHZ
  48.         TL1  = 0xFD;        // 波特率:9600 /11.0592MHZ
  49.         TR1  = 1;
  50.         //下面代码设置定串口
  51.         AUXR = 0x00;             // 很关键,使用定时器1作为波特率发生器,S1ST2=0
  52.         SCON = 0x50;         // 0101 0000 SM0.SM1=01(最普遍的8位通信),REN=1(允许接受)
  53.         TI=1;                        // 很关键,使用printf函数时必须有此命令
  54. }

  55. /********************************************************************
  56. * 名称 : sendbyte()
  57. * 功能 : 按照液晶的串口通信协议,发送数据
  58. * 输入 : zdata
  59. * 输出 : 无
  60. ***********************************************************************/
  61. void sendbyte(unsigned char zdata)
  62. {
  63.         unsigned int i;
  64.         for(i=0; i<8; i++)
  65.         {
  66.                 if((zdata << i) & 0x80)
  67.                 {
  68.                         RW = 1;
  69.                 }
  70.                 else
  71.                 {
  72.                         RW = 0;
  73.                 }
  74.                 E = 0;
  75.                 E = 1;
  76.         }
  77. }

  78. /********************************************************************
  79. * 名称 : write_com()
  80. * 功能 : 写串口指令
  81. * 输入 : cmdcode
  82. * 输出 : 无
  83. ***********************************************************************/
  84. void write_com(unsigned char cmdcode)
  85. {
  86.         RS = 1;
  87.         sendbyte(0xf8);
  88.         sendbyte(cmdcode & 0xf0);
  89.         sendbyte((cmdcode << 4) & 0xf0);
  90.         delay(2);
  91. }

  92. /********************************************************************
  93. * 名称 : write_data()
  94. * 功能 : 写串口指令
  95. * 输入 : cmdcode
  96. * 输出 : 无
  97. ***********************************************************************/
  98. void write_data(unsigned char Dispdata)
  99. {
  100.         RS = 1;
  101.         sendbyte(0xfa);
  102.         sendbyte(Dispdata & 0xf0);
  103.         sendbyte((Dispdata << 4) & 0xf0);
  104.         delay(2);
  105. }

  106. /********************************************************************
  107. * 名称 : lcdinit()
  108. * 功能 : 初始化函数
  109. * 输入 : cmdcode
  110. * 输出 : 无
  111. ***********************************************************************/
  112. void lcdinit()
  113. {  
  114.     PSB = 0;
  115.         delay(1);
  116.         RST = 0;
  117.         delay(100);
  118.         RST = 1;
  119.         delay(20000);
  120.         write_com(0x30);
  121.         delay(50);
  122.         write_com(0x0c);
  123.         delay(50);
  124. }

  125. /********************************************************************
  126. * 名称 : hzkdis()
  127. * 功能 : 显示字符串
  128. * 输入 : *s
  129. * 输出 : 无
  130. ***********************************************************************/
  131. void hzkdis(unsigned char code *s)
  132. {  
  133.         while(*s > 0)
  134.     {
  135.                 write_data(*s);
  136.                 s++;
  137.                 delay(50);
  138.     }
  139. }
  140.         void time_init()          
  141. {
  142.         EA  = 1;                   //开总中断
  143.         TMOD = 0X01;          //定时器0、定时器1工作方式1
  144.         ET0 = 1;                  //开定时器0中断
  145.         TR0 = 1;                  //允许定时器0定时
  146. }
  147. void send_wave()
  148. {
  149.          c_send=1;     //启动一次检测模块
  150.          delay(20);
  151.          c_send=0; //停止向检测模块Trig端发送高电平
  152.          while(!c_recive);      //无回波时等待
  153.          TR0=1;             //计时开始
  154.          while(c_recive);       //有回波是计数并继续等待
  155.          TR0=0;
  156.          time=TH0*256+TL0;   
  157.          TH0=0;
  158.          TL0=0;
  159.          distance=269.05-time*0.191;//  计算距离,算出来的单位是mm
  160.          if(distance<=0)
  161.           distance=0;
  162.          if(distance>=269.05)
  163.          distance=269.05;
  164.        
  165. }
  166. void  ADC_P11_init()
  167. {
  168.         unsigned int i;                    // 用于软件延时程序
  169.         ADC_CONTR|=0x80;              // 开AD转换电源,第一次使用时要打开内部模拟电源
  170.     for (i=0;i<10000;i++);  // 适当延时等待AD转换供电稳定,一般延时1ms以内即可,为了缩短AD
  171. // 调用时间,可把这2行剪切到主程序中去。
  172.         P1ASF|=0x02;                        // 选择P1.1作为AD转换通道,0x02= 0000 0010       
  173.         ADC_CONTR=0xE1;         // 选择P1.1作为AD转换通道,最高转换速度,清转换完成标志。
  174.         for (i=0;i<200;i++);   // 如果是多通道模拟量进行AD转换,则更换AD转换通道后要适当延时,
  175. // 使输入电压稳定,延时量取20μs~200μs即可,与输入电压源的内阻有关,如果输入电压信号源的内
  176. // 阻在10K以下,可不加延时,如果是单通道模拟量转换,则不需要更换AD转换通道,也不需要加延时。
  177.         ADC_CONTR|=0x08;        // 启动 A/D 转换,ADC_START=1。
  178.         EADC=1;
  179.         EA=1;         
  180. }  
  181. void ADC(void) interrupt 5
  182. {
  183.         unsigned int AD_Dat=0,AD_Dat1=0;    // 10位AD转换值
  184.         unsigned char Tmp=0,Tmp1=0;          // 临时变量用于将AD转换出来的2个字节合成一个字节
  185.         ADC_CONTR&=0xE7;               // 将ADC_FLAG清0, 0xE7=1110 0111B,ADC_FLAG=0,ADC_START=0。       
  186.         AD_Dat = ADC_RES;                  // 默认高字节高8位。
  187.         AD_Dat <<= 2;
  188.         Tmp = ADC_RESL;           // 默认低字节低2位。
  189.         Tmp &= 0x03;              // 屏蔽无关位
  190.         AD_Dat|= Tmp;                  // 高低字节拼接成一个10位数。
  191.         ADvalue=AD_Dat;
  192.         ADC_CONTR|=0x08;          // 重新启动 A/D 转换,ADC_START=1。
  193. }

  194. /******向AD7705写入一个字节******/
  195. void WriteByte7705(unsigned char dat)
  196. {
  197.         unsigned char i;
  198.         for (i=0; i<8; i++)
  199.         {
  200.                  ADC_SCK=0;
  201.                 _nop_();
  202.                 _nop_();
  203.                 _nop_();
  204.                  if(dat & 0x80){ADC_DIN=1;}
  205.                  else
  206.                  ADC_DIN=0;
  207.                 _nop_();
  208.                 _nop_();
  209.                 _nop_();
  210.                  ADC_SCK=1;                        
  211.                 _nop_();
  212.                 _nop_();
  213.                 _nop_();
  214.                  dat=dat<<1;
  215.         }
  216. }

  217. /****** 从AD7705读一个字节 ******/
  218. unsigned long ReadWord7705()
  219. {
  220.         unsigned long read_dat=0;
  221.         unsigned char i;
  222.         for(i=0;i<16;i++)
  223.         {
  224.                  read_dat=read_dat<<1;
  225.                  ADC_SCK=0;
  226.                 _nop_();
  227.                 _nop_();
  228.                 _nop_();
  229.                  if(ADC_DOUT == 1)
  230.                  {read_dat++; }
  231.                 _nop_();
  232.                 _nop_();
  233.                 _nop_();
  234.                   ADC_SCK=1;
  235.                 _nop_();
  236.                 _nop_();
  237.                 _nop_();                         
  238.          }
  239.          return read_dat;
  240. }

  241. /******ad7705通信端口复位******/
  242. void reset7705()
  243. {
  244.          unsigned char i;
  245.           ADC_DIN=1;
  246.          for(i=0;i<36;i++)
  247.          {
  248.          ADC_SCK=0;
  249.         _nop_();
  250.         _nop_();
  251.         _nop_();
  252.          ADC_SCK=1;
  253.         _nop_();
  254.         _nop_();
  255.         _nop_();
  256.    }
  257. }

  258. /******AD7705通道1初始化******/
  259. void ad7705_init1()
  260. {
  261. reset7705();
  262. WriteByte7705(0x20);//写通信寄存器,选择通道1,将下一次操作设为写时钟寄存器
  263. WriteByte7705(0x01);//写时钟寄存器,不分频,更新频率25Hz
  264. WriteByte7705(0x10);//写通信寄存器,选择通道1
  265. WriteByte7705(0x44);//写设置寄存器4,单极性,非缓冲模式,清除滤波器同步,启动对1通道的自校准
  266. }

  267. /******读取AD7705通道1转换数据函数******/
  268. unsigned int ReadData1_7705()
  269. {
  270.           unsigned int value;
  271.           ad7705_init1();
  272.           reset7705();
  273.           while(ADC_DBY);          //等待转换结束
  274.           WriteByte7705(0x38);    //写通信寄存器,下一次操作为读数据寄存器
  275.           value=5000*ReadWord7705()/65535;
  276.           return value;                                   
  277. }

  278. void main(void)
  279. {
  280.         float Vin,N,U;                                   // 存放计算出来的外部输入电压
  281.         uint PH;
  282.         ADC_P11_init();
  283.         UART_init();                                   // 串口初始化9600/11.0592MHz
  284.         time_init();
  285.         send_wave();
  286.         lcdinit();
  287.         delay(10);
  288.         write_com(0x03);
  289.           while(1)
  290.         {
  291.          
  292.                 channal1=ReadData1_7705();         //测电池电压
  293.                 channal1=channal1*1.618;
  294.                 delay(50);     
  295.                 send_wave();                           //测距
  296.                 delay(50);
  297.                 Vin=VCC*ADvalue/1023;      // 注意是1023才正确
  298.                     U=Vin*1010.33;
  299.                 N=(4418.5-U)/177.28;       
  300.                 PH=N*100;                                          //测PH值
  301.                 write_com(0x81);
  302.                 hzkdis("水情检测系统");
  303.         write_com(0x90);
  304.         hzkdis("液位高度: ");
  305.                 write_data(distance%1000/100 + 0x30);
  306.                 write_data(distance%100/10 + 0x30);
  307.                 write_data(distance%10 + 0x30);
  308.                 hzkdis("mm");
  309.         write_com(0x88);
  310.         hzkdis("当前PH值: ");
  311.                 write_data(PH%10000/1000 + 0x30);
  312.                 write_data(PH%1000/100 + 0x30);
  313.                 hzkdis(".")        ;
  314.                 write_data(PH%100/10 + 0x30);
  315.         write_com(0x98);
  316.         hzkdis("电池电压: ");
  317.                 write_data(channal1%10000/1000 + 0x30);
  318.                 hzkdis(".");
  319.                 write_data(channal1%1000/100 + 0x30);
  320.                 write_data(channal1%100/10 + 0x30);
  321.                 hzkdis("V");
  322.                 Delay_ms(10);

  323.         }
  324.    }
复制代码

所有资料51hei提供下载:
17年电赛简易水情检测系统代码.zip (45.21 KB, 下载次数: 40)
回复

使用道具 举报

ID:1 发表于 2019-3-31 02:10 | 显示全部楼层
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
回复

使用道具 举报

ID:472844 发表于 2019-7-18 10:30 | 显示全部楼层
感谢分享学习了
回复

使用道具 举报

ID:375799 发表于 2019-7-20 11:01 | 显示全部楼层
ph传感器用的是什么型号的
回复

使用道具 举报

ID:593657 发表于 2019-8-1 15:52 | 显示全部楼层
xxxxxxxxxxxxxxxxxx

datasheet.pdf

1.06 MB, 下载次数: 10, 下载积分: 黑币 -5

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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