找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6253|回复: 9
收起左侧

水塔水位控制系统设计 单片机程序+hex文件+Proteus仿真 求指导

  [复制链接]
ID:489394 发表于 2019-3-22 10:32 | 显示全部楼层 |阅读模式
如题,基于单片机的水塔水位控制系统-proteus图+程序+hex文件
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)

电路图

电路图


单片机源程序如下:
  1. //程序头函数
  2. #include <reg52.h>
  3. //显示函数
  4. #include <display.h>
  5. #include <intrins.h>
  6. #include "eeprom52.h"
  7. //宏定义
  8. #define uint unsigned int
  9. #define uchar unsigned char
  10. #define Data_ADC0809 P1                //定义P1口为Data_ADC0809

  11. //管脚声明
  12. sbit LED_R= P2^2;                          //红色指示灯
  13. sbit LED_G= P2^0;                          //绿色指示灯
  14. sbit FENG = P2^5;                          //蜂鸣器
  15. sbit san=P3^4;                                  //继电器
  16. //ADC0809
  17. sbit ST=P3^3;
  18. sbit EOC=P3^6;
  19. sbit OE=P3^2;
  20. //按键
  21. sbit Key1=P2^6;
  22. sbit Key2=P2^7;
  23. sbit Key3=P3^7;

  24. bit bdata flag;                                  //定义位变量
  25. uchar set;                                          //设置变量


  26. //函数声明
  27. extern uchar ADC0809();
  28. extern void Key();
  29. /*
  30. void delay(uint z)
  31. {
  32.         uint i,j;
  33.         for(i=0;i<z;i++)
  34.         for(j=0;j<121;j++);
  35. }
  36. */

  37. //酒精含量变量
  38. uchar temp=0;

  39. //指示灯变量

  40. uchar WARNING=25;                //报警值变量

  41. /******************把数据保存到单片机内部eeprom中******************/
  42. void write_eeprom()
  43. {
  44.         SectorErase(0x2000);
  45.         byte_write(0x2000, WARNING);
  46.         byte_write(0x2060, a_a);        
  47. }

  48. /******************把数据从单片机内部eeprom中读出来*****************/
  49. void read_eeprom()
  50. {
  51.         WARNING   = byte_read(0x2000);
  52.         a_a      = byte_read(0x2060);
  53. }

  54. /**************开机自检eeprom初始化*****************/
  55. void init_eeprom()
  56. {
  57.         read_eeprom();                //先读
  58.         if(a_a != 1)                //新的单片机初始单片机内问eeprom
  59.         {
  60.                 WARNING   = 25;
  61.                 a_a = 1;
  62.                 write_eeprom();           //保存数据
  63.         }        
  64. }
  65. void init()                                //定时器初始化函数
  66. {
  67.         TMOD=0x01;                        //定时器工作方式
  68.          TL0=0xb0;
  69.          TH0=0x3c;                        //赋初值50ms
  70.          EA=1;                                //打开中断总开关
  71.         ET0=1;                                //打开定时器0中断允许开关
  72.          TR0=1;                                //打开定时器0定时开关
  73. }

  74. void main()                                //主函数
  75. {
  76.         Init1602();                                                 //初始化液晶函数
  77.         init_eeprom();  //开始初始化保存的数据
  78.         init();                                                         //初始化定时器
  79.         while(1)                                                 //进入循环
  80.         {
  81.                 temp=ADC0809();                                 //读取AD数值
  82.                 if(set==0)                                         //set为0,说明现在不是设置状态
  83.                 Display_1602(temp,WARNING);         //显示AD数值和报警值
  84.                 if(temp<WARNING&&set==0)         //AD数值小于报警值
  85.                 {
  86.                         flag=0;                                         //关闭报警
  87.                 }
  88.                 else if(temp>WARNING&&set==0)//AD值大于报警值
  89.                 {
  90.                         flag=1;                                         //打开报警
  91.                 }
  92.                 Key();                                                 //调用按键函数
  93.         }
  94. }
  95. //ADC0809读取信息
  96. uchar ADC0809()
  97. {
  98.         uchar temp_=0x00;
  99.         //初始化高阻太

  100.         OE=0;
  101.         //转化初始化
  102.         ST=0;
  103.         //开始转换
  104.         ST=1;
  105.         ST=0;
  106.         //外部中断等待AD转换结束
  107.         while(EOC==0)
  108.         //读取转换的AD值
  109.         OE=1;
  110.         temp_=Data_ADC0809;
  111.         OE=0;
  112.         return temp_;
  113. }

  114. void Key()                                          //按键函数
  115. {
  116.         if(Key1==0)                                  //设置键按下
  117.         {
  118.                 while(Key1==0);                  //按键松开
  119.                 FENG=0;                                  //蜂鸣器响
  120.                 set++;                                  //设置变量加
  121.                 flag=0;                                  //关闭报警
  122.                 san=1;                                  //关闭继电器
  123.                 TR0=0;                                  //关闭定时器
  124.         }
  125.         if(set==1)                                  //设置报警值时
  126.         {
  127.                 write_com(0x38);//屏幕初始化
  128.                 write_com(0x80+0x40+13);//位置
  129.                    write_com(0x0f);//打开显示 无光标 光标闪烁
  130.                    write_com(0x06);//当读或写一个字符是指针后一一位
  131.                 FENG=1;                                //关闭蜂鸣器

  132.         }
  133.         else if(set>=2)                //设置完成时
  134.         {
  135.                 set=0;                        //变量清零
  136.                 write_com(0x38);//屏幕初始化
  137.                 write_com(0x0c);//打开显示 无光标 无光标闪烁
  138.                 FENG=1;                        //关闭蜂鸣器
  139.                 flag=1;                        //打开报警
  140.                 TR0=1;                        //打开定时器
  141.         }
  142.         if(Key2==0&&set!=0)                        //设置报警值时加键按下
  143.         {
  144.                 while(Key2==0);                        //按键松开
  145.                 FENG=0;                                        //打开蜂鸣器
  146.                 WARNING++;                                //报警值加
  147.                 if(WARNING>=255)                //最大加到255
  148.                 WARNING=0;                                //清零
  149.                 write_com(0x80+0x40+11);           //选中液晶屏上的第二行第十一列
  150.                 write_data('0'+WARNING/100);   //开始显示报警值。例如报警值是123,123除以100的商是1,加上‘0’是为了得到液晶中对应1的显示码
  151.                 write_data('0'+WARNING%100/10);//123除以100的余数是23,23再除以10得到的商是2
  152.                 write_data('0'+WARNING%100%10);//23除以10的余数是3
  153.                 write_com(0x80+0x40+13);//位置
  154.                 FENG=1;                                                //关闭蜂鸣器
  155.                 write_eeprom();                           //保存数据
  156.         }
  157.         if(Key3==0&&set!=0)                                //注释同加按键
  158.         {
  159.                 while(Key3==0);
  160.                 FENG=0;
  161.                 WARNING--;
  162.                 if(WARNING<=0)
  163.                 WARNING=255;
  164.                 write_com(0x80+0x40+11);
  165.                 write_data('0'+WARNING/100);
  166.                 write_data('0'+WARNING/10%10);
  167.                 write_data('0'+WARNING%10);
  168.                 write_com(0x80+0x40+13);//位置
  169.                 FENG=1;
  170.                 write_eeprom();                           //保存数据
  171.         }
  172. }

  173. void  time1_int(void) interrupt 1                  //定时器工作函数
  174. {
  175.         uchar count;                                                  //定义计时变量
  176.         TL0=0xb0;
  177.          TH0=0x3c;                                                          //重新赋初值50ms
  178.           count++;                                                          //变量加一次就是50ms
  179.         if(count==10)                                                  //加到10次就是500ms
  180.         {
  181.                 if(flag==0)                                                  //flag=0时,也就是不开启报警
  182.                 {
  183.                         LED_G=0;                                          //绿灯点亮
  184.                         LED_R=1;                                          //红灯熄灭
  185.                         FENG=1;                                                  //关闭蜂鸣器
  186.                         san=1;                                                  //关闭继电器
  187.                 }
  188.                 if(flag==1)                                                  //flag为1时,也就是打开报警
  189.                 {
  190.                         LED_G=1;                                          //绿灯熄灭
  191.                         LED_R=0;                                          //红灯点亮
  192.                         FENG=0;                                                  //打开蜂鸣器
  193.                         san=0;                                                  //打开继电器
  194.                 }
  195.         }

  196.            if(count==20)                                                  //计数20次,就是1s
  197.            {                                                                          //在1s时,红绿灯都是熄灭状态,蜂鸣器也是关闭状态,装可以达到闪烁的目的
  198.                 count=0;                                                  //变量清零
  199.                 if(flag==0)                                                  //不是报警状态时
  200.                 {
  201.                         LED_G=1;
  202.                         LED_R=1;
  203.                         FENG=1;
  204.                         san=1;                                                  //都关闭
  205.                 }
  206.                 if(flag==1)                                                  //报警状态时
  207.                 {
  208.                         LED_G=1;
  209.                         LED_R=1;
  210.                         FENG=1;
  211.                         san=0;                                                  //继电器一直吸和
  212.                 }
  213.         }
  214. }
复制代码

包含文件

包含文件

由于缺少2个头文件,现在无法编译,求各位大神指导,如何编写.
无法编译的代码下载: 基于单片机的水塔控制系统.rar (29.65 KB, 下载次数: 181)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:577507 发表于 2019-7-3 23:42 | 显示全部楼层
楼主的程序缺少头文件,无法编译,大家学习下这个吧http://www.51hei.com/bbs/dpj-184123-1.html
ORG 0000H
D5 EQU 33H
D6 EQU 34H
WEI1 EQU P1.3
WEI2 EQU P1.4
AJMP MAIN
ORG 0030H
SJMP LOOP
ORG 0050H
MAIN: SETB P1.0
CLR P3.0
CLR P3.6
ACALL DELAY
SETB P3.0
SETB P3.6
WAIT:
JB P1.1,DONE
SJMP WAIT
DONEL: CLR P3.0
CLR P3.7
MOV A, P0
CLR C
SUBB A, #0F4H
JNC D1
MOV A,P0
SETB C
SUBB A,#0003H
JC D2
SJMP LOOP
D1: CLR P1.2
SJMP BACK
D2:SETB P1.2
SJMP BACK
BACK:ACALL D10S
SJMP LOOP
D10s:
MOV R3,#19H
LOOP3: MOV R1,#85H
LOOP1: MOV R2,#0FH
LOOP2:
DJNZ R2, LOOP2
DJNZ R1, LOOP1
DJNZ R3, LOOP3
RETI
LOOP: MOV A,P0
MOV P2, A
ACALL TRAN
ACALL DISP
CLR P1.0
CLR P3.0
CLR P3.6
ACALL DELAY
SETB P3.0
SETB P3.6
WAITI: JB P1. 1, DONE
SJMP WAIT
DONE: CLR P3.0
CLR P3.7
MOV A, P0
CLR C
SUBB A,#0AAH
JNC A1
MOV A, P0
SUBB A,#55H
JNC A2
SETB P1.5
CLR P1.6
CLR P1.7
SJMP MAIN
A1:SETB P1.7
CLR P1.6
CLR P1.5
SJMP MAIN
A2:SETB P1.6
CLR P1.5
CLR P1.7
SJMP MAIN
DELAY: MOV R5,#5
DL1: MOV R6,#10
DL2: MOV  R7,#10
DJNZ R6,DL2
DJNZ R5,DL1
RETI
TRAN: MOV A, P2
MOV B, #10H
DIV AB
MOV D5, A
MOV D6, B
RET
DISP: MOV DPTR,#TAB
SETB P1.3
MOV A,D5
MOVC A,@A+DPTR
MOV P2,A
ACALL DELAY1
CLR P1.3
SETB P1.4
MOV A,D6
MOVC A,@A+DPTR
MOV P2,A
ACALL DELAY1
CLR P1.4
MOV P2, #0FFH
RET
DELAY1: MOV R6,#5
DO:MOV R7,#200
DJNZ R7,$
DJNZ R6, DO
RET
TAB: DB 28H
DB 0EBH
DB 32H
DB 0A2H
DB 0E1H
DB 0A4H
DB 24H
DB 0EAH
DB 20H
DB 0A0H
DB 60H
DB 25H
DB 3CH
DB        23H
DB 34H
DB 74H
DB 0D7H
DB        0F7H
DB 61H
DB 70H
DB 0DFH
DB 27H
DB 0FFH
END
我用汇编写的 我想看看C的
回复

使用道具 举报

ID:243394 发表于 2019-7-12 17:35 | 显示全部楼层
谢谢分享
回复

使用道具 举报

ID:552535 发表于 2019-8-4 08:43 | 显示全部楼层
你的程序需要头文件啊,能不能发一下,谢谢
回复

使用道具 举报

ID:410466 发表于 2019-12-8 14:51 | 显示全部楼层
感谢分享
回复

使用道具 举报

ID:489394 发表于 2019-12-10 11:13 | 显示全部楼层
sjwjwj 发表于 2019-8-4 08:43
你的程序需要头文件啊,能不能发一下,谢谢

头文件用keil51的时候会生成阿
回复

使用道具 举报

ID:651990 发表于 2019-12-19 00:04 来自手机 | 显示全部楼层
你的那个display.h和eeprom52.h的头文件可以发一下吗?不能自动生成  感谢
回复

使用道具 举报

ID:651990 发表于 2019-12-19 00:10 来自手机 | 显示全部楼层
哥,求求你 发一下那两个头文件  急用
回复

使用道具 举报

ID:675930 发表于 2019-12-28 11:32 | 显示全部楼层
同求头文件
回复

使用道具 举报

ID:775758 发表于 2020-6-15 17:23 | 显示全部楼层
楼主,可以说一下这个是如何运行的吗?
谢谢你啦,楼主
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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