蓝桥杯单片机第四届省赛题详细讲解(模拟智能灌溉系统)
看之前强烈建议先自己做一遍!!!
整个工程文件(有注释讲解)
网盘链接
先上演示效果
蓝桥杯单片机第五届模拟智能灌溉系统
首先依旧从赛题的系统框图开始讲起
首先需要做的是将系统框图里的各部分模块提前调试好,方便后续进行调试。使用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
蓝桥杯单片机第四届省赛题详细讲解(模拟智能灌溉系统)相关推荐
- 蓝桥杯单片机第三届省赛题详细讲解(自动售水机)
蓝桥杯资料包 源码 强烈建议先自己做一遍,这是蓝桥杯单片机最简单的一道题. 首先从试题的系统框图开始看 如图所示,有AD转换,所以IIC肯定是需要用的 有数码管,所以数码管先写上 有按键,但确定是独立 ...
- 蓝桥杯单片机第七届省赛题详细讲解(模拟风扇控制系统)
看之前强烈建议先自己做一遍!!! 演示视频 题目讲解 完整程序 main.c onewire.h onewire.c 工程文件 演示视频 题目讲解 首先还是从整个赛题的程序框图开始看起,如图. 做题之 ...
- 蓝桥杯单片机第四届 省赛 模拟智能灌溉系统(第五届模拟赛)
如果有用请点赞,还会继续更新的 题目: 思路: 这个程序用到的iic总线技术完成了EEPROM断电存储和ADC的模拟,然后通过了DS1302完成了时钟单元,这个程序最困扰我的就是蜂鸣器了,不得不写了一 ...
- 2013第四届蓝桥杯Java组省赛题解析
2013第四届蓝桥杯Java组省赛题解析 目录 第一题:高斯日记 第二题:马虎的算式 第三题:第39级台阶 第四题:黄金连分数 第五题:前缀判断 第六题:三部排序 第七题:错误票据 第八题:翻硬币 ...
- 十三届蓝桥杯单片机组省赛真题程序解析
第一次参加蓝桥杯,线上比赛,记录一下 比赛刚开始了十分钟才做上客观题,做上了之后才发现看一次题警告一次,当时就蚌埠住了,随便做了做就交了,手册也没怎么查(查一下直接给了3次黄牌,就没敢查了)其实老师1 ...
- 第jiu届蓝桥杯单片机省赛真题_第九届蓝桥杯单片机组省赛试题.pdf
第九届蓝桥杯单片机组省赛试题 "彩灯控制器"的程序设计与调试 (70 分) 一.基本要求 1.1 使用CT107D 单片机竞赛板,完成"彩灯控制器"功能的程序设 ...
- 蓝桥杯单片机历年初赛真题练习
蓝桥杯单片机历年初赛真题练习第三届-自动售水机 文章目录 蓝桥杯单片机历年初赛真题练习第三届---自动售水机 前言 一.题目要求 二.具体代码 1.驱动部分 2.主程序部分 总结 前言 我参加了第十二 ...
- 蓝桥杯单片机省赛——第五届(模拟智能灌溉系统)
蓝桥杯单片机省赛--第五届(模拟智能灌溉系统) 一.题目内容 二.程序源代码 1.主函数 2.ds1302驱动函数 3.iic驱动函数 注意:驱动代码需要改动一下,可以将原驱动代码按照下面的代码修改 ...
- 蓝桥杯第五届省赛模拟试题--“模拟智能灌溉系统”
题目要求 功能简述 要求"模拟智能灌溉系统" 能够实现土壤湿度测量. 土壤湿度和时间显示. 湿度阈值设定及存储等基本功能. 通过电位器 Rb2 输出电压信号,模拟湿度传感器输出信号 ...
最新文章
- Windows Server 8 Beta 初体验之三 Active Directory
- JavaSE的一些基础内容
- 基于opencv和QT的摄像头采集代码( GoQTtemplate3持续更新)
- javamail腾讯企业邮箱发送邮件
- New Currency Rate IOS APP 上线
- mysql定时发送慢日志到邮件
- 【kafka】Timeout of 60000ms expired before the position for partition could be determined
- Canvas--文字渲染
- 应急管理大数据ppt_大数据应急管理.doc
- 嵌入式单片机面试笔记
- html中标签img大小自适应
- Cadence之双击(DSN/brd)文件打开变新建文件的解决方法
- 【全网唯一】TC8一致性测试文章合集来袭(持续更新中)
- Audio AudioFocus流程
- 人机混合智能在博弈领域的发展
- php imagick加GD实现gif图换脸动画生成表情包制作功能
- 程序员转行能做什么?
- 计算机配置打开命令行,win7开机f8进入修复计算机cmd装xp
- Dockers(六)- Docker镜像使用
- 天堂祭祀php,test_《扶摇柳真真免费阅读》
热门文章
- 同济七版高等数学 上册 复习指导、公式推理简易过程、常用结论归纳
- linux内核编译系统调用,linux编译内核及添加系统调用
- 新生代垃圾回收器和老生代垃圾回收器
- excel表格横向纵向变换_表格的制作方法
- Linux 安装conda踩的那些坑
- 【译】索引进阶(六):SQL SERVER索引书签
- PythonGUI简单学生管理系统
- python怎么换背景颜色_Python给照片换底色(基于opencv模块)
- v2视频服务器退出系统怎么启动,v2视频会议系统操作手册.doc
- 小颖用计算机探索方程,数字信号处理(邓小颖)-中国大学mooc-题库零氪