看之前强烈建议先自己做一遍!!!
整个工程文件(有注释讲解)
网盘链接
先上演示效果

蓝桥杯单片机第五届模拟智能灌溉系统

首先依旧从赛题的系统框图开始讲起

首先需要做的是将系统框图里的各部分模块提前调试好,方便后续进行调试。使用IIC和DS1302的驱动,将他们复制在工程目录下,并调试好。
首先按照数码管显示要求显示时间和湿度。


顺便注意要求,湿度是由Rb2电位器产生的,时间是ds1302产生的。
主函数显示代码:

extern uchar time[7]; //ds1302.c中定义的存储时间的数组uchar tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,\
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xff,0xbf};
uchar SMG[8]={20,20,20,20,20,20,20,20};//初始显示10,全息数码管uchar SMG_mode=0,move; //数码管模式定义,滑动变阻器Rb2定义
void main(void)
{init(); //初始开发板ds1302_init(); //uchar time[7]={0,30,8,0,0,0,0}; 8:30:00while(1){get_time(); //时间获取move=IIC_read(0x90,0x03); //读取Rb2电阻阻值move=move*0.3921; //100/255 将255转换到100if(SMG_mode==0){SMG[0]=time[2]/10;SMG[1]=time[2]%10;SMG[2]=21; //时间显示SMG[3]=time[1]/10;SMG[4]=time[1]%10;SMG[5]=20;SMG[6]=move/10;SMG[7]=move%10;  //显示湿度}SMG_output();Dkey_scan();}
}

然后接着看题目要求:


信息提取:
灌溉由继电器模拟

自动模式 手动模式
L1点亮 L2点亮
根据湿度自动灌溉 通过按键控制灌溉
低于设定阈值开启继电器,高于关闭继电器 低于阈值,蜂鸣器打开,使用按键s6关闭蜂鸣器

定义变量:

bit work_mode=0; //0为自动模式,1为手动模式
char threshold=50; //定义初始湿度阈值
uchar led=0xff,buzz=0x00; //定义led口和蜂鸣器继电器口,消除其他赋值干扰

手动模式与自动模式代码

        if(work_mode==0) //自动模式{led |=0x02;led &=0xfe;P2=0X80;P0=led; //打开L1,关闭L2if(move<threshold) //低于阈值{buzz|=0X10;P2=0XA0;P0=buzz; //打开继电器}else {buzz&=0XEF;P2=0XA0;P0=buzz; //关闭继电器}}else //手动模式{led |=0x01;led &=0XFD;P2=0X80;P0=led; //打开L2,关闭L1if(move<threshold) //低于阈值{buzz|=0X40;P2=0XA0;P0=buzz; //打开蜂鸣器}else{buzz&=0Xbf;P2=0XA0;P0=buzz; //关闭蜂鸣器}}

然后就可以开始写按键了:

S7:切换自动模式和手动模式
手动模式下:
S6:关闭和打开蜂鸣器提醒功能
S5:打开灌溉
S4:关闭灌溉
自动模式下:
S6:调整阈值,且数码管显示切换,再次按下退出,且保存湿度阈值到EEPROM之中
S5:阈值加一
S4:阈值减一

代码如下:

        else if(SMG_mode==1){SMG[0]=SMG[1]=21;SMG[3]=SMG[4]=SMG[5]=20;SMG[6]=threshold/10;SMG[7]=threshold%10;  //显示湿度}
void Dkey_scan(void)
{static uchar keybyte=0;static uchar key;if(((P3&0X0F)!=0X0F)&&(keybyte==0)){delay5ms();if((P3&0X0F)!=0X0F){keybyte=1;key=P3&0x0f;}}if((keybyte==1)&&((P3&0X0F)==0X0F)){if((P3&0X0F)==0X0F){switch(key){case 0x0e:if(work_mode==0)work_mode=1;else work_mode=0;break;case 0x0d:if(work_mode==1) //手动模式下{if(buzz_state==1){buzz_state=0;P2=0XA0;P0=0X00;} //关闭蜂鸣器else {buzz_state=1;}//打开蜂鸣器使能}else  //自动模式下{if(SMG_mode==0)SMG_mode=1; //切换数码管状态else SMG_mode=0;}break;case 0x0b:if(work_mode==1) //手动模式{buzz|=0X10;P2=0XA0;P0=buzz; //打开灌溉}else //自动模式下{threshold++; //阈值加1if(threshold>99)threshold=99; //范围}break;case 0x07:if(work_mode==1)//手动模式{buzz&=0XEF;P2=0XA0;P0=buzz; //关闭灌溉}else //自动模式下{threshold--; //阈值减1if(threshold<0)threshold=0; //范围}break;}keybyte=0;}}
}

最后就做完了。
main.c

#include <stc15f2k60s2.h>
#include "intrins.h"
#include "iic.h"
#include "ds1302.h"#define uchar unsigned char
#define uint unsigned intvoid SMG_output(void);
void init(void);
void Delay1ms(void);
void delay5ms(void);
void Dkey_scan(void);extern uchar time[7]; //ds1302.c中定义的存储时间的数组uchar tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,\
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xff,0xbf};
uchar SMG[8]={20,20,20,20,20,20,20,20};//初始显示10,全息数码管uchar SMG_mode=0,move; //数码管模式定义,滑动变阻器Rb2定义
bit work_mode=0; //0为自动模式,1为手动模式
char threshold=50; //定义初始湿度阈值
uchar led=0xff,buzz=0x00; //定义led口和蜂鸣器继电器口,消除其他赋值干扰bit buzz_state=1; //为1打开蜂鸣器,为0关闭蜂鸣器
void main(void)
{init(); //初始开发板ds1302_init(); //uchar time[7]={0,30,8,0,0,0,0}; 8:30:00threshold=IIC_read(0xA0,0x00); //上电读取EEPROMwhile(1){get_time(); //时间获取move=IIC_read(0x90,0x03); //读取Rb2电阻阻值move=move*0.3921; //100/255 将255转换到100if(SMG_mode==0){SMG[0]=time[2]/10;SMG[1]=time[2]%10;SMG[2]=21; //时间显示SMG[3]=time[1]/10;SMG[4]=time[1]%10;SMG[5]=20;SMG[6]=move/10;SMG[7]=move%10;  //显示湿度}else if(SMG_mode==1){SMG[0]=SMG[1]=21;SMG[3]=SMG[4]=SMG[5]=20;SMG[6]=threshold/10;SMG[7]=threshold%10;  //显示湿度}if(work_mode==0) //自动模式{led |=0x02;led &=0xfe;P2=0X80;P0=led; //打开L1,关闭L2if(move<threshold) //低于阈值{buzz|=0X10;P2=0XA0;P0=buzz; //打开继电器}else {buzz&=0XEF;P2=0XA0;P0=buzz; //关闭继电器}}else //手动模式{led |=0x01;led &=0XFD;P2=0X80;P0=led; //打开L2,关闭L1if((move<threshold)&&(buzz_state==1)) //低于阈值且允许蜂鸣器打开{buzz|=0X40;P2=0XA0;P0=buzz; //打开蜂鸣器}else{buzz&=0Xbf;P2=0XA0;P0=buzz; //关闭蜂鸣器}}SMG_output();Dkey_scan();}
}void Dkey_scan(void)
{static uchar keybyte=0;static uchar key;if(((P3&0X0F)!=0X0F)&&(keybyte==0)){delay5ms();if((P3&0X0F)!=0X0F){keybyte=1;key=P3&0x0f;}}if((keybyte==1)&&((P3&0X0F)==0X0F)){if((P3&0X0F)==0X0F){switch(key){case 0x0e:if(work_mode==0)work_mode=1;else work_mode=0;break;case 0x0d:if(work_mode==1) //手动模式下{if(buzz_state==1){buzz_state=0;P2=0XA0;P0=0X00;} //关闭蜂鸣器else {buzz_state=1;}//打开蜂鸣器使能}else  //自动模式下{if(SMG_mode==0)SMG_mode=1; //切换数码管状态else {SMG_mode=0;IIC_write(0xA0,0x00,threshold);} //存取EEPROM}break;case 0x0b:if(work_mode==1) //手动模式{buzz|=0X10;P2=0XA0;P0=buzz; //打开灌溉}else //自动模式下{threshold++; //阈值加1if(threshold>99)threshold=99; //范围}break;case 0x07:if(work_mode==1)//手动模式{buzz&=0XEF;P2=0XA0;P0=buzz; //关闭灌溉}else //自动模式下{threshold--; //阈值减1if(threshold<0)threshold=0; //范围}break;}keybyte=0;}}
}void SMG_output(void)
{uchar i;for(i=0;i<8;i++){P2=(P2&0X1F)|0Xc0;P0=(1<<i);P2=(P2&0X1F)|0Xe0;P0=tab[SMG[i]];Delay1ms();}P2=(P2&0X1F)|0Xc0;P0=0Xff;P2=(P2&0X1F)|0Xe0;P0=0Xff;
}void init(void)
{P2=(P2&0X1F)|0XA0;P0=0X00;P2=(P2&0X1F)|0X80;P0=0Xff;P2=(P2&0X1F)|0Xc0;P0=0Xff;P2=(P2&0X1F)|0Xe0;P0=0Xff;
}void Delay1ms(void)     //@11.0592MHz
{unsigned char i, j;_nop_();_nop_();_nop_();i = 11;j = 190;do{while (--j);} while (--i);
}void delay5ms(void)     //@11.0592MHz
{unsigned char i, j;i = 54;j = 199;do{while (--j);} while (--i);
}

iic.c

#include "iic.h"#define DELAY_TIME 40void IIC_write(uchar hw_address,uchar reg_address,uchar num)
{IIC_Start();IIC_SendByte(hw_address&0xfe);IIC_WaitAck();IIC_SendByte(reg_address);IIC_WaitAck();IIC_SendByte(num);IIC_WaitAck();   IIC_Stop();
}    uchar IIC_read(uchar hw_address,uchar reg_address)
{uchar num;IIC_Start();IIC_SendByte(hw_address&0xfe);IIC_WaitAck();IIC_SendByte(reg_address);   IIC_WaitAck();IIC_Stop();IIC_Start();IIC_SendByte(hw_address|0x01);IIC_WaitAck();num=IIC_RecByte();IIC_WaitAck();IIC_Stop();  return num;
}//
void IIC_Delay(unsigned char i)
{do{_nop_();}while(i--);
}//
void IIC_Start(void)
{SDA = 1;SCL = 1;IIC_Delay(DELAY_TIME);SDA = 0;IIC_Delay(DELAY_TIME);SCL = 0;
}//
void IIC_Stop(void)
{SDA = 0;SCL = 1;IIC_Delay(DELAY_TIME);SDA = 1;IIC_Delay(DELAY_TIME);
}//
void IIC_SendAck(bit ackbit)
{SCL = 0;SDA = ackbit;                   IIC_Delay(DELAY_TIME);SCL = 1;IIC_Delay(DELAY_TIME);SCL = 0; SDA = 1;IIC_Delay(DELAY_TIME);
}//
bit IIC_WaitAck(void)
{bit ackbit;SCL  = 1;IIC_Delay(DELAY_TIME);ackbit = SDA;SCL = 0;IIC_Delay(DELAY_TIME);return ackbit;
}//
void IIC_SendByte(unsigned char byt)
{unsigned char i;for(i=0; i<8; i++){SCL  = 0;IIC_Delay(DELAY_TIME);if(byt & 0x80) SDA  = 1;else SDA  = 0;IIC_Delay(DELAY_TIME);SCL = 1;byt <<= 1;IIC_Delay(DELAY_TIME);}SCL  = 0;
}//
unsigned char IIC_RecByte(void)
{unsigned char i, da;for(i=0; i<8; i++){   SCL = 1;IIC_Delay(DELAY_TIME);da <<= 1;if(SDA) da |= 1;SCL = 0;IIC_Delay(DELAY_TIME);}return da;
}

iic.h

#ifndef _IIC_H
#define _IIC_H#include "stc15f2k60s2.h"
#include "intrins.h"#define uchar unsigned char
#define uint unsigned intsbit SDA = P2^1;
sbit SCL = P2^0;void IIC_Start(void);
void IIC_Stop(void);
bit IIC_WaitAck(void);
void IIC_SendAck(bit ackbit);
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
void IIC_write(uchar hw_address,uchar reg_address,uchar num);
uchar IIC_read(uchar hw_address,uchar reg_address);#endif

ds1302.c

#include "ds1302.h"uchar time[7]={0,30,8,0,0,0,0};void ds1302_init(void)
{uchar i,j=0x80;Write_Ds1302_Byte(0x8e,0x00);for(i=0;i<7;i++){Write_Ds1302_Byte(j,time[i]);j +=2;}Write_Ds1302_Byte(0x8e,0x80);
}void get_time(void)
{uchar i,j=0x81;Write_Ds1302_Byte(0x8e,0x00);for(i=0;i<7;i++){time[i]=Read_Ds1302_Byte(j);j +=2;}Write_Ds1302_Byte(0x8e,0x80);
}//
void Write_Ds1302(unsigned  char temp)
{unsigned char i;for (i=0;i<8;i++)        { SCK = 0;IO = temp&0x01;temp>>=1; SCK=1;}
}   //
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )
{RST=0; _nop_();SCK=0;    _nop_();RST=1;    _nop_();  Write_Ds1302(address);  Write_Ds1302(((dat/10)<<4)|(dat%10));RST=0;
}//
unsigned char Read_Ds1302_Byte ( unsigned char address )
{unsigned char i,temp=0x00;RST=0; _nop_();SCK=0;    _nop_();RST=1;    _nop_();Write_Ds1302(address);for (i=0;i<8;i++)     {        SCK=0;temp>>=1; if(IO)temp|=0x80; SCK=1;} RST=0; _nop_();SCK=0;    _nop_();SCK=1;    _nop_();IO=0; _nop_();IO=1; _nop_();return (((temp/16)*10)+(temp%16));
}

ds1302.h

#ifndef __DS1302_H
#define __DS1302_H#include <stc15f2k60s2.h>
#include <intrins.h>#define uchar unsigned char
#define uint unsigned intsbit SCK = P1^7;
sbit IO = P2^3;
sbit RST = P1^3; void Write_Ds1302(unsigned char temp);
void Write_Ds1302_Byte( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302_Byte( unsigned char address );
void get_time(void);
void ds1302_init(void);#endif

蓝桥杯单片机第四届省赛题详细讲解(模拟智能灌溉系统)相关推荐

  1. 蓝桥杯单片机第三届省赛题详细讲解(自动售水机)

    蓝桥杯资料包 源码 强烈建议先自己做一遍,这是蓝桥杯单片机最简单的一道题. 首先从试题的系统框图开始看 如图所示,有AD转换,所以IIC肯定是需要用的 有数码管,所以数码管先写上 有按键,但确定是独立 ...

  2. 蓝桥杯单片机第七届省赛题详细讲解(模拟风扇控制系统)

    看之前强烈建议先自己做一遍!!! 演示视频 题目讲解 完整程序 main.c onewire.h onewire.c 工程文件 演示视频 题目讲解 首先还是从整个赛题的程序框图开始看起,如图. 做题之 ...

  3. 蓝桥杯单片机第四届 省赛 模拟智能灌溉系统(第五届模拟赛)

    如果有用请点赞,还会继续更新的 题目: 思路: 这个程序用到的iic总线技术完成了EEPROM断电存储和ADC的模拟,然后通过了DS1302完成了时钟单元,这个程序最困扰我的就是蜂鸣器了,不得不写了一 ...

  4. 2013第四届蓝桥杯Java组省赛题解析

    2013第四届蓝桥杯Java组省赛题解析 目录 第一题:高斯日记 第二题:马虎的算式 第三题:第39级台阶 第四题:黄金连分数 ​第五题:前缀判断 第六题:三部排序 ​第七题:错误票据 第八题:翻硬币 ...

  5. 十三届蓝桥杯单片机组省赛真题程序解析

    第一次参加蓝桥杯,线上比赛,记录一下 比赛刚开始了十分钟才做上客观题,做上了之后才发现看一次题警告一次,当时就蚌埠住了,随便做了做就交了,手册也没怎么查(查一下直接给了3次黄牌,就没敢查了)其实老师1 ...

  6. 第jiu届蓝桥杯单片机省赛真题_第九届蓝桥杯单片机组省赛试题.pdf

    第九届蓝桥杯单片机组省赛试题 "彩灯控制器"的程序设计与调试 (70 分) 一.基本要求 1.1 使用CT107D 单片机竞赛板,完成"彩灯控制器"功能的程序设 ...

  7. 蓝桥杯单片机历年初赛真题练习

    蓝桥杯单片机历年初赛真题练习第三届-自动售水机 文章目录 蓝桥杯单片机历年初赛真题练习第三届---自动售水机 前言 一.题目要求 二.具体代码 1.驱动部分 2.主程序部分 总结 前言 我参加了第十二 ...

  8. 蓝桥杯单片机省赛——第五届(模拟智能灌溉系统)

    蓝桥杯单片机省赛--第五届(模拟智能灌溉系统) 一.题目内容 二.程序源代码 1.主函数 2.ds1302驱动函数 3.iic驱动函数 注意:驱动代码需要改动一下,可以将原驱动代码按照下面的代码修改 ...

  9. 蓝桥杯第五届省赛模拟试题--“模拟智能灌溉系统”

    题目要求 功能简述 要求"模拟智能灌溉系统" 能够实现土壤湿度测量. 土壤湿度和时间显示. 湿度阈值设定及存储等基本功能. 通过电位器 Rb2 输出电压信号,模拟湿度传感器输出信号 ...

最新文章

  1. Windows Server 8 Beta 初体验之三 Active Directory
  2. JavaSE的一些基础内容
  3. 基于opencv和QT的摄像头采集代码( GoQTtemplate3持续更新)
  4. javamail腾讯企业邮箱发送邮件
  5. New Currency Rate IOS APP 上线
  6. mysql定时发送慢日志到邮件
  7. 【kafka】Timeout of 60000ms expired before the position for partition could be determined
  8. Canvas--文字渲染
  9. 应急管理大数据ppt_大数据应急管理.doc
  10. 嵌入式单片机面试笔记
  11. html中标签img大小自适应
  12. Cadence之双击(DSN/brd)文件打开变新建文件的解决方法
  13. 【全网唯一】TC8一致性测试文章合集来袭(持续更新中)
  14. Audio AudioFocus流程
  15. 人机混合智能在博弈领域的发展
  16. php imagick加GD实现gif图换脸动画生成表情包制作功能
  17. 程序员转行能做什么?
  18. 计算机配置打开命令行,win7开机f8进入修复计算机cmd装xp
  19. Dockers(六)- Docker镜像使用
  20. 天堂祭祀php,test_《扶摇柳真真免费阅读》

热门文章

  1. 同济七版高等数学 上册 复习指导、公式推理简易过程、常用结论归纳
  2. linux内核编译系统调用,linux编译内核及添加系统调用
  3. 新生代垃圾回收器和老生代垃圾回收器
  4. excel表格横向纵向变换_表格的制作方法
  5. Linux 安装conda踩的那些坑
  6. 【译】索引进阶(六):SQL SERVER索引书签
  7. PythonGUI简单学生管理系统
  8. python怎么换背景颜色_Python给照片换底色(基于opencv模块)
  9. v2视频服务器退出系统怎么启动,v2视频会议系统操作手册.doc
  10. 小颖用计算机探索方程,数字信号处理(邓小颖)-中国大学mooc-题库零氪