找回密码
 立即注册

QQ登录

只需一步,快速开始

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

为什么我的单片机代码编译生成HEX文件老是出错?

[复制链接]
跳转到指定楼层
楼主
150黑币
还有要实现图片这样的仿真,我的代码还需要修改哪些?有没有哪位帮我看一下

1.png (76.06 KB, 下载次数: 79)

1.png

浇水系统.rar

5.01 KB, 下载次数: 9

最佳答案

查看完整内容

给你把几个文件合在一起。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶2 踩
回复

使用道具 举报

沙发
ID:213173 发表于 2019-4-27 18:51 | 只看该作者
给你把几个文件合在一起。



  1. #include <AT89X52.H>
  2. #include<intrins.h>
  3. #include<stdio.h>

  4. #define  uint   unsigned int          
  5. #define  uchar  unsigned char

  6. #define RS_CLR RS=0
  7. #define RS_SET RS=1

  8. #define RW_CLR RW=0
  9. #define RW_SET RW=1

  10. #define EN_CLR EN=0
  11. #define EN_SET EN=1
  12. #define  ZERO   4.5                //湿度传感器放空气中的电压值   对应湿度0%
  13. #define  FULL   0.45                //湿度传感器放水中的电压值         对应湿度100%

  14. #define DataPort P0

  15. float k,b;//计算湿度用斜率

  16. sbit RS = P2^5;   //定义LCD1602端口
  17. sbit RW = P2^6;
  18. sbit EN = P2^7;
  19. sbit KEY1=P1^0;  //取消
  20. sbit KEY2=P1^1;         //增加
  21. sbit KEY3=P1^2;         //减少
  22. sbit KEY4=P1^3;         //确认
  23. sbit CS  = P2^0; //定义ADC0832端口
  24. sbit CLK = P2^1;
  25. sbit DIO = P2^2;
  26. sbit MOETOR = P3^6;//水泵控制端口
  27. sbit DQ = P3^5;
  28. sbit beep = P3^3;   //蜂鸣器IO口定义

  29. //uint temperature,s_temp ;  //温度的变量
  30. uchar shidu;     //湿度等级
  31. uchar s_high = 70,s_low = 25;        //湿度报警参数
  32. uint temp;
  33. float  d;  //实时湿度值
  34. int RH=50; //湿度上限
  35. int RL=20; //湿度下限
  36. int RH;
  37. int RL;
  38. char KeyValue;        //返回按键值
  39. //int temperature;
  40. float temperature;         //温度值
  41. unsigned char displaytemp[16];//定义显示区域临时存储数组

  42. /*------------------------------------------------
  43.                     18b20初始化
  44. ------------------------------------------------*/
  45. /*------------------------------------------------
  46. uS延时函数,含有输入参数 unsigned char t,无返回值
  47. unsigned char 是定义无符号字符变量,其值的范围是
  48. 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
  49. 长度如下 T=tx2+5 uS
  50. ------------------------------------------------*/
  51. void DelayUs2x(unsigned char t)
  52. {   
  53.         while(--t);
  54. }
  55. /*------------------------------------------------
  56. mS延时函数,含有输入参数 unsigned char t,无返回值
  57. unsigned char 是定义无符号字符变量,其值的范围是
  58. 0~255 这里使用晶振12M,精确延时请使用汇编
  59. ------------------------------------------------*/
  60. void DelayMs(unsigned char t)
  61. {   
  62.         while(t--)
  63.         {
  64.                 //大致延时1mS
  65.                 DelayUs2x(245);
  66.                 DelayUs2x(245);
  67.         }
  68. }
  69. /*------------------------------------------------
  70.                     18b20初始化
  71. -----------------------------------------*/
  72. bit Init_DS18B20(void)
  73. {
  74.         bit dat=0;
  75.         DQ = 1;    //DQ复位
  76.         DelayUs2x(5);   //稍做延时
  77.         DQ = 0;         //单片机将DQ拉低
  78.         DelayUs2x(200); //精确延时 大于 480us 小于960us
  79.         DelayUs2x(200);
  80.         DQ = 1;        //拉高总线
  81.         DelayUs2x(50); //15~60us 后 接收60-240us的存在脉冲
  82.         dat=DQ;        //如果x=0则初始化成功, x=1则初始化失败
  83.         DelayUs2x(25); //稍作延时返回
  84.         return dat;
  85. }

  86. /*------------------------------------------------
  87.                     读取一个字节
  88. ------------------------------------------------*/
  89. unsigned char ReadOneChar(void)
  90. {
  91.         unsigned char i=0;
  92.         unsigned char dat = 0;
  93.         for (i=8;i>0;i--)
  94.         {
  95.                 DQ = 0; // 给脉冲信号
  96.                 dat>>=1;
  97.                 DQ = 1; // 给脉冲信号
  98.                 if(DQ)
  99.                 dat|=0x80;
  100.                 DelayUs2x(25);
  101.         }
  102.         return(dat);
  103. }
  104. /*------------------------------------------------
  105.                     写入一个字节
  106. ------------------------------------------------*/
  107. void WriteOneChar(unsigned char dat)
  108. {
  109.         unsigned char i=0;
  110.         for (i=8; i>0; i--)
  111.         {
  112.                 DQ = 0;
  113.                 DQ = dat&0x01;
  114.                 DelayUs2x(25);
  115.                 DQ = 1;
  116.                 dat>>=1;
  117.         }
  118.         DelayUs2x(25);
  119. }

  120. /*------------------------------------------------
  121.                     读取温度
  122. ------------------------------------------------*/
  123. unsigned int ReadTemperature(void)
  124. {
  125.         unsigned char a=0;
  126.         unsigned int b=0;
  127.         unsigned int t=0;
  128.         Init_DS18B20();
  129.         WriteOneChar(0xCC); // 跳过读序号列号的操作
  130.         WriteOneChar(0x44); // 启动温度转换
  131.         DelayMs(10);
  132.         Init_DS18B20();
  133.         WriteOneChar(0xCC); //跳过读序号列号的操作
  134.         WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
  135.         a=ReadOneChar();   //低位
  136.         b=ReadOneChar();   //高位
  137.         b<<=8;
  138.         t=a+b;
  139.         return(t);
  140. }
  141. /*------------------------------------------------
  142.               判忙函数
  143. ------------------------------------------------*/
  144. bit LCD_Check_Busy(void)
  145. {
  146.         unsigned char LCD_Status;
  147.         RS = 0;
  148.         RW = 1;
  149.         EN = 1;
  150.         DelayMs(1);
  151.         LCD_Status = DataPort;
  152.         EN = 0;
  153.         return LCD_Status;
  154. }
  155. /*------------------------------------------------
  156.               写入命令函数
  157. ------------------------------------------------*/
  158. void LCD_Write_Com(unsigned char com)
  159. {  
  160.         while((LCD_Check_Busy()&0x80)==0x80);
  161.         RS = 0;
  162.         RW = 0;
  163.         EN = 0;
  164.         DataPort = com;
  165.         EN = 1;
  166.         DelayMs(1);
  167.         EN = 0;
  168. }
  169. /*------------------------------------------------
  170.               写入数据函数
  171. ------------------------------------------------*/
  172. void LCD_Write_Data(unsigned char Data)
  173. {
  174.         while((LCD_Check_Busy()&0x80)==0x80);
  175.         RS = 1;
  176.         RW = 0;
  177.         EN = 0;
  178.         DataPort = Data;
  179.         EN = 1;
  180.         DelayMs(1);
  181.         EN = 0;
  182. }
  183. /*------------------------------------------------
  184.                 清屏函数
  185. ------------------------------------------------*/
  186. /*
  187. void LCD_Clear(void)
  188. {
  189.          LCD_Write_Com(0x01);
  190.          DelayMs(5);
  191. }*/
  192. /*------------------------------------------------
  193.               写入字符串函数
  194. ------------------------------------------------*/
  195. void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
  196. {     
  197.         if (y == 0)
  198.         {     
  199.                 LCD_Write_Com(0x80 + x);     //表示第一行
  200.         }
  201.         else
  202.         {      
  203.                 LCD_Write_Com(0xC0 + x);      //表示第二行
  204.         }        
  205.         while (*s)
  206.         {     
  207.                 LCD_Write_Data( *s);     
  208.                 s ++;     
  209.         }
  210. }
  211. /*------------------------------------------------
  212.               写入字符函数
  213. ------------------------------------------------*/
  214. /*
  215. void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
  216. {     
  217.         if (y == 0)
  218.         {     
  219.                 LCD_Write_Com(0x80 + x);     
  220.         }   
  221.         else
  222.         {     
  223.                 LCD_Write_Com(0xC0 + x);     
  224.         }        
  225.         LCD_Write_Data( Data);  
  226. }*/
  227. /*------------------------------------------------
  228.               初始化函数
  229. ------------------------------------------------*/
  230. void LCD_Init(void)
  231. {
  232.         LCD_Write_Com(0x38);    /*显示模式设置*/  
  233.         LCD_Write_Com(0x01);    /*显示清屏*/
  234.         LCD_Write_Com(0x06);    /*显示光标移动设置*/
  235.         LCD_Write_Com(0x0C);    /*显示开及光标设置*/
  236. }
  237. unsigned char Get_AD_Result()        //读取AD值
  238. {
  239.         uchar i,dat1=0,dat2=0;
  240.         CS  = 0;
  241.         CLK = 0;
  242.         DIO = 1; _nop_(); _nop_();
  243.         CLK = 1; _nop_(); _nop_();
  244.         CLK = 0;DIO = 1; _nop_(); _nop_();
  245.         CLK = 1; _nop_(); _nop_();
  246.         CLK = 0;DIO = 1; _nop_(); _nop_();
  247.         CLK = 1;DIO = 1; _nop_(); _nop_();
  248.         CLK = 0;DIO = 1; _nop_(); _nop_();
  249.         for(i=0;i<8;i++)
  250.         {
  251.                 CLK = 1; _nop_(); _nop_();
  252.                 CLK = 0; _nop_(); _nop_();
  253.                 dat1 = dat1 << 1 | DIO;       
  254.         }
  255.         for(i=0;i<8;i++)
  256.         {
  257.                 dat2 = dat2 << ((uchar)(DIO)<<i);
  258.                 CLK = 1; _nop_(); _nop_();
  259.                 CLK = 0; _nop_(); _nop_();
  260.         }
  261.         CS = 1;
  262.         dat1=50;
  263.         return dat1; //== dat2) ? dat1:0;
  264. }

  265. void clock_h_l()
  266. {
  267.         static uchar value,value1;
  268.         if(shidu <= s_low)
  269.         {
  270.                 value ++;
  271.                 if(value >= 2)
  272.                 {
  273.                         value = 10;
  274.                         beep = ~beep;          //蜂鸣器报警
  275.                         MOETOR = 0;       //打开电机
  276.                 }
  277.         }
  278.         else beep = 1;   //关闭蜂鸣器
  279.        
  280.         if(shidu >= s_high)
  281.         {
  282.                 value1 ++;
  283.                 if(value1 >= 2)
  284.                 {
  285.                         value1 = 10;
  286.                         beep = 1;   //关闭蜂鸣器
  287.                         MOETOR = 1;       //关机电机
  288.                 }
  289.         }
  290.         else value1 = 0;
  291. }
  292. /*------------------------------------------------
  293.             按键扫描函数,返回扫描键值
  294. ------------------------------------------------*/
  295. unsigned char KeyScan(void)
  296. {
  297. /********************************************************/  
  298.         if(!KEY1)  //如果检测到低电平,说明按键按下
  299.         {
  300.                 DelayMs(10); //延时去抖,一般10-20ms
  301.                 if(!KEY1)     //再次确认按键是否按下,没有按下则退出
  302.                 {
  303.                         while(!KEY1);//如果确认按下按键等待按键释放,没有则退出
  304.                         {
  305.                                 return 1;
  306.                         }
  307.                 }
  308.         }
  309.         /********************************************************/  
  310.         else if(!KEY2)  //如果检测到低电平,说明按键按下
  311.         {
  312.                 DelayMs(10); //延时去抖,一般10-20ms
  313.                 if(!KEY2)     //再次确认按键是否按下,没有按下则退出
  314.                 {
  315.                         while(!KEY2);//如果确认按下按键等待按键释放,没有则退出
  316.                         {
  317.                                 return 2;
  318.                         }
  319.                 }
  320.         }
  321.         /********************************************************/  
  322.         else if(!KEY3)  //如果检测到低电平,说明按键按下
  323.         {
  324.                 DelayMs(10); //延时去抖,一般10-20ms
  325.                 if(!KEY3)     //再次确认按键是否按下,没有按下则退出
  326.                 {
  327.                         while(!KEY3);//如果确认按下按键等待按键释放,没有则退出
  328.                         {
  329.                                 return 3;
  330.                         }
  331.                 }
  332.         }
  333.         /********************************************************/  
  334.         else if(!KEY4)  //如果检测到低电平,说明按键按下
  335.         {
  336.                 DelayMs(10); //延时去抖,一般10-20ms
  337.                 if(!KEY4)     //再次确认按键是否按下,没有按下则退出
  338.                 {
  339.                         while(!KEY4);//如果确认按下按键等待按键释放,没有则退出
  340.                         {
  341.                                 return 4;
  342.                         }
  343.                 }
  344.         }
  345.         else
  346.         return 0;
  347. }

  348. void Keyprocessing(int x)   //按键值处理函数
  349. {
  350.         switch(x)
  351.         {  
  352.                 case 1:  RH++;        break;  //上限加
  353.                 case 2:  RH--;        break;   //上限减
  354.                 case 3:  RL++;        break;  //下限加
  355.                 case 4:  RL--;        break;   //下限减       
  356.         }
  357. }
  358. /*------------------------------------------------
  359.                     主函数
  360. ------------------------------------------------*/
  361. void main(void)
  362. {        
  363.         LCD_Init();
  364.         DelayMs(10);
  365. //        Init_Timer0();
  366.         MOETOR =0;        //默认水泵关闭         
  367.         while (1)
  368.         {  
  369.                 KeyValue=KeyScan();
  370.                 if(KeyValue!=0)//如果有键按下
  371.                 {       
  372.                         Keyprocessing(KeyValue); //键值处理
  373.                 }       
  374.                 temp=ReadTemperature();  //读取温度值
  375.                 temperature=(float)temp*0.0625;
  376.                 sprintf(displaytemp,"T =%3.1f",temperature);//

  377.                 LCD_Write_String(0,0,displaytemp);// 显示温度值       
  378.                 d = Get_AD_Result()*5/255; //计算电压值
  379.                 k = 100/(FULL-ZERO);           //根据空气中和水中的电压值列函数y=kx+b 计算 k b
  380.                 b = 0-ZERO*k;
  381.                 d = k*d+b;          //计算实际的湿度值
  382.                 if(d<0)        d=0;
  383.                 if(d>100) d=100;
  384.                 //d = k*d+b;
  385.                 sprintf(displaytemp,"R =%3.1f",d);//
  386.                 LCD_Write_String(8,0,displaytemp);// 显示湿度
  387.                 sprintf(displaytemp,"RH=%2d",RH);//
  388.                 LCD_Write_String(0,1,displaytemp);// 显示湿度上限
  389.                 sprintf(displaytemp,"RL=%2d",RL);//
  390.                 LCD_Write_String(10,1,displaytemp);//        显示湿度下限       
  391.                 if(d<RL) MOETOR =1;          //低于下限 开水泵
  392.                 if(d>RH) MOETOR =0;          //高于上限 关水泵
  393. //                DelayMs(300);
  394.                 clock_h_l();
  395.         }
  396. }


复制代码



回复

使用道具 举报

板凳
ID:277550 发表于 2019-4-27 22:32 | 只看该作者
里面少文件,第1眼看到少了key.h

~~~~~~~~~~~~~~~~~~~~~
回复

使用道具 举报

地板
ID:277550 发表于 2019-4-27 22:38 | 只看该作者
还有,delay文件,头文件和源文件,都定义了函数体。。。


key.c中,还引用了主文件的变量,等等。。。。。。
回复

使用道具 举报

5#
ID:277550 发表于 2019-4-27 22:52 | 只看该作者
Watering.7z (3.4 KB, 下载次数: 5)

附件是能编译通过,但逻辑什么的,还没有修正的。

~~~~~~~~~~~~

回复

使用道具 举报

6#
ID:481641 发表于 2019-4-28 10:44 | 只看该作者
少文件
回复

使用道具 举报

7#
ID:499243 发表于 2019-4-28 13:48 | 只看该作者

链接:https://pan.baidu.com/s/1BOso_-SnEEwPBNDm6bqbZA
提取码:w5rn
这里有key.h文件但是还是在生成hex文件的时候出现问题,能不能帮我看下怎么解决
回复

使用道具 举报

8#
ID:499243 发表于 2019-4-28 13:55 | 只看该作者
devcang 发表于 2019-4-27 22:52
附件是能编译通过,但逻辑什么的,还没有修正的。

~~~~~~~~~~~~

我用keil文件编译生成hex文件,怎么导入那些定义的函数KEY.H这些求教教我
回复

使用道具 举报

9#
ID:499243 发表于 2019-4-28 13:57 | 只看该作者
devcang 发表于 2019-4-27 22:32
里面少文件,第1眼看到少了key.h

~~~~~~~~~~~~~~~~~~~~~



编译的时候就提示这个C51 FATAL-ERROR -  ACTION:  PARSING SOURCE-FILE
  ERROR:    PREPROCESSOR: MACROS TOO NESTED
C51 TERMINATED.
回复

使用道具 举报

10#
ID:499243 发表于 2019-4-29 20:29 | 只看该作者
wulin 发表于 2019-4-29 15:31
给你把几个文件合在一起。

大神用了你的代码确实可以编译了,但是测量湿度的电阻部分和浇水电机好像不工作了,还有本来在P3.3口有一个蜂鸣器我传的图上忘记加了,一直叫,请问怎么才能实现在湿度低于预设值后,发出响声,高于之后自动停止呢?麻烦帮我解决一下谢谢了

OSEI}YCNFBM`([@6YY(]G3I.png (213.75 KB, 下载次数: 27)

OSEI}YCNFBM`([@6YY(]G3I.png
回复

使用道具 举报

11#
ID:213173 发表于 2019-5-2 13:39 | 只看该作者
chenchen1 发表于 2019-4-29 20:29
大神用了你的代码确实可以编译了,但是测量湿度的电阻部分和浇水电机好像不工作了,还有本来在P3.3口有一 ...

原来的湿度换算程序和蜂鸣器程序确实有错误,已经调试好了,这个蜂鸣器在仿真中不会响,实物中会响的。



  1. #include <AT89X52.H>
  2. #include<intrins.h>
  3. #include<stdio.h>

  4. #define  uint   unsigned int          
  5. #define  uchar  unsigned char

  6. #define RS_CLR RS=0
  7. #define RS_SET RS=1

  8. #define RW_CLR RW=0
  9. #define RW_SET RW=1

  10. #define EN_CLR EN=0
  11. #define EN_SET EN=1
  12. #define  ZERO   4.5                //湿度传感器放空气中的电压值   对应湿度0%
  13. #define  FULL   0.45                //湿度传感器放水中的电压值         对应湿度100%

  14. #define DataPort P0

  15. float k,b;//计算湿度用斜率

  16. sbit RS = P2^5;   //定义LCD1602端口
  17. sbit RW = P2^6;
  18. sbit EN = P2^7;
  19. sbit KEY1=P1^0;  //取消
  20. sbit KEY2=P1^1;         //增加
  21. sbit KEY3=P1^2;         //减少
  22. sbit KEY4=P1^3;         //确认
  23. sbit CS  = P2^0; //定义ADC0832端口
  24. sbit CLK = P2^1;
  25. sbit DIO = P2^2;
  26. sbit MOETOR = P3^6;//水泵控制端口
  27. sbit DQ = P3^5;
  28. sbit beep = P3^3;   //蜂鸣器IO口定义

  29. uchar shidu;     //湿度等级
  30. uchar s_high = 70,s_low = 25;        //湿度报警参数
  31. uint temp;
  32. uchar dm;
  33. float  d;  //实时湿度值
  34. int RH=50; //湿度上限
  35. int RL=20; //湿度下限
  36. char KeyValue;        //返回按键值
  37. float temperature;         //温度值
  38. unsigned char displaytemp[16];//定义显示区域临时存储数组

  39. /*------------------------------------------------
  40.                     18b20初始化
  41. ------------------------------------------------*/
  42. /*------------------------------------------------
  43. uS延时函数,含有输入参数 unsigned char t,无返回值
  44. unsigned char 是定义无符号字符变量,其值的范围是
  45. 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
  46. 长度如下 T=tx2+5 uS
  47. ------------------------------------------------*/
  48. void DelayUs2x(unsigned char t)
  49. {   
  50.         while(--t);
  51. }
  52. /*------------------------------------------------
  53. mS延时函数,含有输入参数 unsigned char t,无返回值
  54. unsigned char 是定义无符号字符变量,其值的范围是
  55. 0~255 这里使用晶振12M,精确延时请使用汇编
  56. ------------------------------------------------*/
  57. void DelayMs(unsigned char t)
  58. {   
  59.         while(t--)
  60.         {
  61.                 //大致延时1mS
  62.                 DelayUs2x(245);
  63.                 DelayUs2x(245);
  64.         }
  65. }
  66. /*------------------------------------------------
  67.                     18b20初始化
  68. -----------------------------------------*/
  69. bit Init_DS18B20(void)
  70. {
  71.         bit dat=0;
  72.         DQ = 1;    //DQ复位
  73.         DelayUs2x(5);   //稍做延时
  74.         DQ = 0;         //单片机将DQ拉低
  75.         DelayUs2x(200); //精确延时 大于 480us 小于960us
  76.         DelayUs2x(200);
  77.         DQ = 1;        //拉高总线
  78.         DelayUs2x(50); //15~60us 后 接收60-240us的存在脉冲
  79.         dat=DQ;        //如果x=0则初始化成功, x=1则初始化失败
  80.         DelayUs2x(25); //稍作延时返回
  81.         return dat;
  82. }

  83. /*------------------------------------------------
  84.                     读取一个字节
  85. ------------------------------------------------*/
  86. unsigned char ReadOneChar(void)
  87. {
  88.         unsigned char i=0;
  89.         unsigned char dat = 0;
  90.         for (i=8;i>0;i--)
  91.         {
  92.                 DQ = 0; // 给脉冲信号
  93.                 dat>>=1;
  94.                 DQ = 1; // 给脉冲信号
  95.                 if(DQ)
  96.                 dat|=0x80;
  97.                 DelayUs2x(25);
  98.         }
  99.         return(dat);
  100. }
  101. /*------------------------------------------------
  102.                     写入一个字节
  103. ------------------------------------------------*/
  104. void WriteOneChar(unsigned char dat)
  105. {
  106.         unsigned char i=0;
  107.         for (i=8; i>0; i--)
  108.         {
  109.                 DQ = 0;
  110.                 DQ = dat&0x01;
  111.                 DelayUs2x(25);
  112.                 DQ = 1;
  113.                 dat>>=1;
  114.         }
  115.         DelayUs2x(25);
  116. }

  117. /*------------------------------------------------
  118.                     读取温度
  119. ------------------------------------------------*/
  120. unsigned int ReadTemperature(void)
  121. {
  122.         unsigned char a=0;
  123.         unsigned int b=0;
  124.         unsigned int t=0;
  125.         Init_DS18B20();
  126.         WriteOneChar(0xCC); // 跳过读序号列号的操作
  127.         WriteOneChar(0x44); // 启动温度转换
  128.         DelayMs(10);
  129.         Init_DS18B20();
  130.         WriteOneChar(0xCC); //跳过读序号列号的操作
  131.         WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
  132.         a=ReadOneChar();   //低位
  133.         b=ReadOneChar();   //高位
  134.         b<<=8;
  135.         t=a+b;
  136.         return(t);
  137. }
  138. /*------------------------------------------------
  139.               判忙函数
  140. ------------------------------------------------*/
  141. bit LCD_Check_Busy(void)
  142. {
  143.         unsigned char LCD_Status;
  144.         RS = 0;
  145.         RW = 1;
  146.         EN = 1;
  147.         DelayMs(1);
  148.         LCD_Status = DataPort;
  149.         EN = 0;
  150.         return LCD_Status;
  151. }
  152. /*------------------------------------------------
  153.               写入命令函数
  154. ------------------------------------------------*/
  155. void LCD_Write_Com(unsigned char com)
  156. {  
  157.         while((LCD_Check_Busy()&0x80)==0x80);
  158.         RS = 0;
  159.         RW = 0;
  160.         EN = 0;
  161.         DataPort = com;
  162.         EN = 1;
  163.         DelayMs(1);
  164.         EN = 0;
  165. }
  166. /*------------------------------------------------
  167.               写入数据函数
  168. ------------------------------------------------*/
  169. void LCD_Write_Data(unsigned char Data)
  170. {
  171.         while((LCD_Check_Busy()&0x80)==0x80);
  172.         RS = 1;
  173.         RW = 0;
  174.         EN = 0;
  175.         DataPort = Data;
  176.         EN = 1;
  177.         DelayMs(1);
  178.         EN = 0;
  179. }
  180. /*------------------------------------------------
  181.                 清屏函数
  182. ------------------------------------------------*/
  183. /*
  184. void LCD_Clear(void)
  185. {
  186.          LCD_Write_Com(0x01);
  187.          DelayMs(5);
  188. }*/
  189. /*------------------------------------------------
  190.               写入字符串函数
  191. ------------------------------------------------*/
  192. void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
  193. {     
  194.         if (y == 0)
  195.         {     
  196.                 LCD_Write_Com(0x80 + x);     //表示第一行
  197.         }
  198.         else
  199.         {      
  200.                 LCD_Write_Com(0xC0 + x);      //表示第二行
  201.         }        
  202.         while (*s)
  203.         {     
  204.                 LCD_Write_Data( *s);     
  205.                 s ++;     
  206.         }
  207. }
  208. /*------------------------------------------------
  209.               写入字符函数
  210. ------------------------------------------------*/
  211. /*
  212. void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
  213. {     
  214.         if (y == 0)
  215.         {     
  216.                 LCD_Write_Com(0x80 + x);     
  217.         }   
  218.         else
  219.         {     
  220.                 LCD_Write_Com(0xC0 + x);     
  221.         }        
  222.         LCD_Write_Data( Data);  
  223. }*/
  224. /*------------------------------------------------
  225.               初始化函数
  226. ------------------------------------------------*/
  227. void LCD_Init(void)
  228. {
  229.         LCD_Write_Com(0x38);    /*显示模式设置*/  
  230.         LCD_Write_Com(0x01);    /*显示清屏*/
  231.         LCD_Write_Com(0x06);    /*显示光标移动设置*/
  232.         LCD_Write_Com(0x0C);    /*显示开及光标设置*/
  233. }
  234. unsigned char Get_AD_Result(unsigned char ch)        //读取AD值
  235. {
  236.         uchar i=0,j,ndat=0,Vot=0;
  237.         uint dat=0;
  238.         if(ch==0)ch=2;
  239.         if(ch==1)ch=3;
  240.         DIO=1;_nop_();_nop_();
  241.         CS=0;_nop_();_nop_();                //拉低CS端
  242.         CLK=1;_nop_();_nop_();                //拉高CLK端
  243.         CLK=0;_nop_();_nop_();                //拉低CLK端,形成下降沿1
  244.         CLK=1;                                                //拉高CLK端
  245.         DIO=ch&0x1;_nop_();_nop_();
  246.         CLK=0;_nop_();_nop_();                //拉低CLK端,形成下降沿2
  247.         CLK=1;                                                //拉高CLK端
  248.         DIO=(ch>>1)&0x1;_nop_();_nop_();
  249.         CLK=0;                                                //拉低CLK端,形成下降沿3
  250.         DIO=1;_nop_();_nop_();                //控制命令结束
  251.         dat=0;
  252.         for(i=0;i<8;i++)
  253.         {
  254.                 dat|=DIO;                                //收数据
  255.                 CLK=1;_nop_();_nop_();
  256.                 CLK=0;_nop_();_nop_();        //形成一次时钟脉冲
  257.                 dat<<=1;
  258.                 if(i==7)
  259.                         dat|=DIO;
  260.         }
  261.         for(i=0;i<8;i++)
  262.         {
  263.                 j=0;
  264.                 j=j|DIO;                                //收数据
  265.                 CLK=1;_nop_();_nop_();
  266.                 CLK=0;_nop_();_nop_();        //形成一次时钟脉冲
  267.                 j=j<<7;
  268.                 ndat=ndat|j;
  269.                 if(i<7)
  270.                         ndat>>=1;
  271.         }
  272.         CS=1;                                                //拉低CS端
  273.         CLK=0;                                                //拉低CLK端
  274.         DIO=1;                                                //拉高数据端,回到初始状态
  275.         dat<<=8;
  276.         dat|=ndat;
  277.         return(dat);                   
  278. }

  279. void clock_h_l()
  280. {
  281.         shidu=dm;
  282.         if((shidu <= s_low)||(shidu >= s_high))
  283.                 beep = ~beep;                //蜂鸣器报警
  284.         else beep = 1;                   //关闭蜂鸣器
  285. }
  286. /*------------------------------------------------
  287.             按键扫描函数,返回扫描键值
  288. ------------------------------------------------*/
  289. unsigned char KeyScan(void)
  290. {
  291. /********************************************************/  
  292.         if(!KEY1)  //如果检测到低电平,说明按键按下
  293.         {
  294.                 DelayMs(10); //延时去抖,一般10-20ms
  295.                 if(!KEY1)     //再次确认按键是否按下,没有按下则退出
  296.                 {
  297.                         while(!KEY1);//如果确认按下按键等待按键释放,没有则退出
  298.                         {
  299.                                 return 1;
  300.                         }
  301.                 }
  302.         }
  303.         /********************************************************/  
  304.         else if(!KEY2)  //如果检测到低电平,说明按键按下
  305.         {
  306.                 DelayMs(10); //延时去抖,一般10-20ms
  307.                 if(!KEY2)     //再次确认按键是否按下,没有按下则退出
  308.                 {
  309.                         while(!KEY2);//如果确认按下按键等待按键释放,没有则退出
  310.                         {
  311.                                 return 2;
  312.                         }
  313.                 }
  314.         }
  315.         /********************************************************/  
  316.         else if(!KEY3)  //如果检测到低电平,说明按键按下
  317.         {
  318.                 DelayMs(10); //延时去抖,一般10-20ms
  319.                 if(!KEY3)     //再次确认按键是否按下,没有按下则退出
  320.                 {
  321.                         while(!KEY3);//如果确认按下按键等待按键释放,没有则退出
  322.                         {
  323.                                 return 3;
  324.                         }
  325.                 }
  326.         }
  327.         /********************************************************/  
  328.         else if(!KEY4)  //如果检测到低电平,说明按键按下
  329.         {
  330.                 DelayMs(10); //延时去抖,一般10-20ms
  331.                 if(!KEY4)     //再次确认按键是否按下,没有按下则退出
  332.                 {
  333.                         while(!KEY4);//如果确认按下按键等待按键释放,没有则退出
  334.                         {
  335.                                 return 4;
  336.                         }
  337.                 }
  338.         }
  339.         else
  340.         return 0;
  341. }

  342. void Keyprocessing(int x)   //按键值处理函数
  343. {
  344.         switch(x)
  345.         {  
  346.                 case 1:  RH++;        break;  //上限加
  347.                 case 2:  RH--;        break;   //上限减
  348.                 case 3:  RL++;        break;  //下限加
  349.                 case 4:  RL--;        break;   //下限减       
  350.         }
  351. }
  352. /*------------------------------------------------
  353.                     主函数
  354. ------------------------------------------------*/
  355. void main(void)
  356. {        
  357.         LCD_Init();
  358.         DelayMs(10);
  359. //        Init_Timer0();
  360.         MOETOR = 0;        //默认水泵关闭         
  361.         while (1)
  362.         {  
  363.                 KeyValue=KeyScan();
  364.                 if(KeyValue!=0)//如果有键按下
  365.                 {       
  366.                         Keyprocessing(KeyValue); //键值处理
  367.                 }       
  368.                 temp=ReadTemperature();  //读取温度值
  369.                 temperature=(float)temp*0.0625;
  370.                 sprintf(displaytemp,"T =%3.1f",temperature);//

  371.                 LCD_Write_String(0,0,displaytemp);// 显示温度值       
  372.                 d = (float)Get_AD_Result(0)*5/255; //计算电压值
  373.                 k = 100/(FULL-ZERO);           //根据空气中和水中的电压值列函数y=kx+b 计算 k b
  374.                 b = 0-ZERO*k;
  375.                 d = k*d+b;          //计算实际的湿度值
  376.                 if(d<0)        d=0;
  377.                 if(d>100) d=100;
  378.                 sprintf(displaytemp,"R =%3.1f",d);//
  379.                 LCD_Write_String(8,0,displaytemp);// 显示湿度
  380.                 sprintf(displaytemp,"RH=%2d",RH);//
  381.                 LCD_Write_String(0,1,displaytemp);// 显示湿度上限
  382.                 sprintf(displaytemp,"RL=%2d",RL);//
  383.                 LCD_Write_String(10,1,displaytemp);//        显示湿度下限       
  384.                 dm=d;
  385.                 if(dm<RL) MOETOR =1;          //低于下限 开水泵
  386.                 if(dm>RH) MOETOR =0;          //高于上限 关水泵
  387.                 DelayMs(300);
  388.                 clock_h_l();//蜂鸣器程序
  389.         }
  390. }
复制代码



回复

使用道具 举报

12#
ID:499243 发表于 2019-5-3 12:13 | 只看该作者
wulin 发表于 2019-5-2 13:39
原来的湿度换算程序和蜂鸣器程序确实有错误,已经调试好了,这个蜂鸣器在仿真中不会响,实物中会响的。
...

非常感谢我的问题解决了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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