蓝桥杯第四届初赛“模拟智能灌溉系统”设计任务书
文章目录
- 蓝桥杯第四届初赛“模拟智能灌溉系统”设计任务书
- Author:Luis
- Time:2022-04-10
- Version:v1.0
- 说明
- 功能简介
- 具体代码
- main.c
- iic.c
- iic.h
- ds1302.c
- ds1302.h
蓝桥杯第四届初赛“模拟智能灌溉系统”设计任务书
Author:Luis
Time:2022-04-10
Version:v1.0
说明
蓝桥杯系列的代码都是本人亲手写和调试,可能有时会有点错误,请见谅。此外,代码仅供大家学习,祝福各位在蓝桥杯比赛中能获得比较满意的成绩。
忙着期中考试,今天就来“水”一下今天的博客。
从第五届的题目开始,我就会开始一步步地分析题目并且写出代码。分析能力和思路更重要,代码只是实现手段,大家不能局限于代码。
功能简介
1.1 自动工作状态,根据湿度数据自动控制打开或关闭灌溉设备,以L1 点亮指示;
1.2 手动工作状态,通过按键控制打开或关闭灌溉设备,以L2 点亮指示;
1.3 系统上电后处于自动工作状态,系统初始湿度阈值为50%,此时若湿度低于
50%,灌溉设备自动打开,达到50%后,灌溉设备自动关闭;
1.4 灌溉设备打开或关闭通过继电器工作状态模拟。
具体代码
main.c
/******************************************************************************** 目标:第四届题目 “模拟智能灌溉系统”设计任务书* 注意:J3跳线配置为IO方式,J5配置为BTN、J2配置为1-3和2-4*******************************************************************************/
#include <STC15F2K60S2.h>
#include "intrins.h"
#include "ds1302.h"
#include "iic.h"unsigned char *time_ds1302; // 时间
unsigned char ds1302_flag = 0; // 0 1unsigned char key_value = 0;
unsigned char key_flag = 0;unsigned char adc_flag = 0;
// 小数点是第8位为0 原本数字 - 0x80
unsigned char data_pros[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0xff, 0xbf};
unsigned char dspbuf[8] = {10, 10, 10, 10, 10, 10, 10, 10}; //显示缓冲区// 初始化值
void close_init()
{P2 = 0xA0;P0 = 0x00;P2 = 0x80;P0 = 0xff;P2 = 0x00;
}void Delay5ms() //@11.0592MHz
{unsigned char i, j;i = 54;j = 199;do{while (--j);} while (--i);
}void Delay500ms() //@11.0592MHz
{unsigned char i, j, k;_nop_();_nop_();i = 22;j = 3;k = 227;do{do{while (--k);} while (--j);} while (--i);
}// 显示函数 dspbuf为数码管的缓冲区
void display()
{static unsigned char dspnum = 0; // 数码管的位置P2 = 0xE0;P2 = 0xff; // 消影P2 = 0xc0;P0 = (1 << dspnum);P2 = 0xe0;P0 = data_pros[dspbuf[dspnum]];P2 = 0x00;if (++dspnum == 8)dspnum = 0;
}void Timer0Init(void) // 1毫秒@11.0592MHz
{AUXR |= 0x80; //定时器时钟1T模式TMOD &= 0xF0; //设置定时器模式TL0 = 0xCD; //设置定时初值TH0 = 0xD4; //设置定时初值TF0 = 0; //清除TF0标志TR0 = 1; //定时器0开始计时// addTH1 = 0;TL1 = 0;ET0 = 1;EA = 1;
}// 读取独立键值 J5为BTN模式
unsigned char read_key()
{static unsigned char key_press = 0; // 按下次数unsigned char key_temp;static bit key_re = 0;static unsigned char key_value = 0;key_temp = (P3 & 0x0f); // 取低位值/**************多次检测,可以可以防止抖动*********************/if (key_temp != 0x0f)key_press++;elsekey_press = 0;if (key_press == 5) // 连续5次按压{key_press = 0;key_re = 1; // 按下switch (key_temp){case 0x0e:key_value = 1; // S7break;case 0x0d:key_value = 2; // S6break;case 0x0b:key_value = 3; // S5break;case 0x07:key_value = 4; // S4break;}}//连续5次检测到按键被按下,并且该按键已经释放if ((key_re == 1) && (key_temp == 0x0f)){key_re = 0;return key_value;}return 0xff; //无按键按下或被按下的按键未被释放
}void main()
{unsigned char eeprom_value[2] = {5, 0};unsigned char eeprom_location[2] = {0x00, 0x01};unsigned char shidu = 0; // 湿度unsigned char i = 0;bit mode = 1; // 模式 0 手动 1 自动bit mode6 = 0; // 模式 自动模式 调节页面unsigned char adc_pcf8591_value = 0;bit buzz_flag = 1; // 警报声bit guangai = 0; // 是否打开灌溉系统close_init();Timer0Init();SetRTC();init_pcf8591();Delay5ms();// for (i = 0; i < 2; i++)// {// Write_EEPROM(eeprom_location[i], eeprom_value[i]);// Delay500ms();// }for (i = 0; i < 2; i++){eeprom_value[i] = Read_EEPROM(eeprom_location[i]);Delay500ms();}shidu = 10 * eeprom_value[0] + eeprom_value[1];dspbuf[6] = shidu / 10;dspbuf[7] = shidu % 10;P2 = 0x80;P0 = 0xFE;P2 = 0x00;while (1){if ((ds1302_flag == 1) && (mode6 == 0)){ds1302_flag = 0;time_ds1302 = ReadRTC();// 更新时间dspbuf[0] = time_ds1302[0];dspbuf[1] = time_ds1302[1];dspbuf[2] = 11;dspbuf[3] = time_ds1302[2];dspbuf[4] = time_ds1302[3];}if (key_flag == 1){key_value = read_key();if (key_value != 0xff){switch (key_value){case 1:{mode = !(mode);if (mode == 0) // 手动模式必须 mode6=0{mode6 = 0;P2 = 0x80;P0 = 0xFD;P2 = 0x00;}if (mode == 1){mode6 = 0;P2 = 0x80;P0 = 0xFE;P2 = 0x00;P2 = 0xA0;P0 = 0x00;P2 = 0x00; // 关掉蜂鸣器}}break;case 2:{buzz_flag = 1; // 给检测权限mode6 = !(mode6); // mode=0 mode6=0是打开警报 mode=1 mode6=1 是开启状态if ((mode == 1) && (mode6 == 1)) // 自动模式下调节S6{dspbuf[0] = 11;dspbuf[1] = 11;for (i = 2; i < 6; i++)dspbuf[i] = 10;dspbuf[6] = shidu / 10;dspbuf[7] = shidu % 10;}if ((mode == 1) && (mode6 == 0)){Write_EEPROM(eeprom_location[0], dspbuf[6]);Delay500ms();Write_EEPROM(eeprom_location[1], dspbuf[7]);}}break;case 3:{if (mode == 0)guangai = 1;if (mode6 == 1){shidu++;if (shidu >= 100)shidu = 99;dspbuf[6] = shidu / 10;dspbuf[7] = shidu % 10;}}break;case 4:{if (mode == 0)guangai = 0;if (mode6 == 1){shidu--;if (shidu <= 0)shidu = 1;dspbuf[6] = shidu / 10;dspbuf[7] = shidu % 10;}}break;}}}if ((mode == 0) && (adc_flag == 1) && (guangai == 1)){adc_flag = 0;adc_pcf8591_value = adc_pcf8591(); // 255 -->100shidu = (adc_pcf8591_value * 99 / (255.0));dspbuf[6] = shidu / 10;dspbuf[7] = shidu % 10;}if ((mode == 0) && (shidu < 50)) // 湿度检测 低于50 且 mode6模式为开响{if ((mode6 == 0) && (buzz_flag == 1)){buzz_flag = 0; // 防止鬼影P2 = 0xA0;P0 = 0x40;P2 = 0x00;}if ((mode6 == 1)){P2 = 0xA0;P0 = 0x00;P2 = 0x00;}}if ((mode == 0) && (shidu >= 50)){buzz_flag = 1;P2 = 0xA0;P0 = 0x00;P2 = 0x00;}}
}void isr_time_0() interrupt 1
{static unsigned char ds1302_time = 0;static unsigned char key_time = 0;static unsigned char adc_time = 0;display();if (++ds1302_time == 200) // 必须设置刷新时间,不然有问题{ds1302_time = 0;ds1302_flag = 1;}if (++key_time == 20){key_time = 0;key_flag = 1;}if (++adc_time == 200){adc_time = 0;adc_flag = 1;}
}
iic.c
/*程序说明: IIC总线驱动程序软件环境: Keil uVision 4.10硬件环境: CT107单片机综合实训平台 8051,12MHz日 期: 2011-8-9
*/#include "reg52.h"
#include "intrins.h"#define DELAY_TIME 5#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1//总线引脚定义
sbit SDA = P2 ^ 1; /* 数据线 */
sbit SCL = P2 ^ 0; /* 时钟线 */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; // 0:应答,1:非应答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;
}//通过I2C总线发送数据
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;elseSDA = 0;IIC_Delay(DELAY_TIME);SCL = 1;byt <<= 1;IIC_Delay(DELAY_TIME);}SCL = 0;
}//从I2C总线上接收数据
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;
}// add
// AT24C02
// 写数据
void Write_EEPROM(unsigned char addr, unsigned char dat)
{EA = 0;IIC_Start();IIC_SendByte(0xA0); // 看芯片手册Figure 7 -W为低电平有效IIC_WaitAck();IIC_SendByte(addr); // 0x00-0xffIIC_WaitAck();IIC_SendByte(dat);IIC_WaitAck();IIC_Stop();EA = 1;
}// 读数据
unsigned char Read_EEPROM(unsigned char addr)
{unsigned char da;EA = 0;IIC_Start();IIC_SendByte(0xA0);IIC_WaitAck();IIC_SendByte(addr);IIC_WaitAck();IIC_Start();IIC_SendByte(0xA1);IIC_WaitAck();da = IIC_RecByte();IIC_SendAck(1); // 非应答,停止读取IIC_Stop();EA = 1;return da;
}// addd
// PCF8591
void init_pcf8591()
{EA = 0;IIC_Start();IIC_SendByte(0x90);IIC_WaitAck();IIC_SendByte(0X03); // 第一通道IIC_WaitAck();IIC_Stop();EA = 1;
}// 通过I2C总线读取ADC结果
unsigned char adc_pcf8591()
{unsigned char da;EA = 0;IIC_Start();IIC_SendByte(0x91);IIC_WaitAck();da = IIC_RecByte();IIC_SendAck(1);IIC_Stop();EA = 1;return da;
}
iic.h
#ifndef __IIC_H
#define __IIC_Hvoid 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 Write_EEPROM(unsigned char addr, unsigned char dat);
unsigned char Read_EEPROM(unsigned char addr);void init_pcf8591(); // 初始化pcf8591
unsigned char adc_pcf8591(); // 通过I2C总线读取ADC结果
#endif
ds1302.c
/*程序说明: DS1302驱动程序软件环境: Keil uVision 4.10硬件环境: CT107单片机综合实训平台 8051,12MHz日 期: 2011-8-9
*/#include <reg52.h>
#include <intrins.h>sbit SCK = P1 ^ 7;
sbit SDA = P2 ^ 3;
sbit RST = P1 ^ 3; // DS1302复位void Write_Ds1302(unsigned char temp)
{unsigned char i;for (i = 0; i < 8; i++){SCK = 0;SDA = 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);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 (SDA)temp |= 0x80;SCK = 1;}RST = 0;_nop_();SCK = 0;_nop_();SCK = 1;_nop_();SDA = 0;_nop_();SDA = 1;_nop_();return (temp);
}// 添加的
code unsigned char w_rtc_address[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c}; //秒分时日月周年
code unsigned char r_rtc_address[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};unsigned char set[6] = {0, 8, 3, 0, 0, 0}; // 时间可以自己修改
unsigned char rtc[6];// 设置时间
void SetRTC(void)
{Write_Ds1302_Byte(0x8E, 0X00); // WP=0,允许写操作Write_Ds1302_Byte(w_rtc_address[0], (set[4] << 4) | (set[5])); //秒分时 10进制转16进制 组合起来Write_Ds1302_Byte(w_rtc_address[1], (set[2] << 4) | (set[3]));Write_Ds1302_Byte(w_rtc_address[2], (set[0] << 4) | (set[1]));Write_Ds1302_Byte(0x8E, 0x80); // WP=1,禁止写操作
}// 读取时间
unsigned char *ReadRTC(void)
{unsigned char i, *p;unsigned char tmp[3];p = (unsigned char *)r_rtc_address; //地址传递for (i = 0; i < 3; i++){tmp[i] = Read_Ds1302_Byte(*p);p++;}rtc[0] = (tmp[2] >> 4); // 16进制转10进制rtc[1] = (tmp[2] & 0x0F);rtc[2] = (tmp[1] >> 4);rtc[3] = (tmp[1] & 0x0F);rtc[4] = (tmp[0] >> 4);rtc[5] = (tmp[0] & 0x0F);return rtc;
}
ds1302.h
#ifndef __DS1302_H
#define __DS1302_H// void Write_Ds1302(unsigned char temp);
// void Write_Ds1302_Byte(unsigned char address, unsigned char dat);
// unsigned char Read_Ds1302_Byte(unsigned char address);// add
void SetRTC(void);
unsigned char *ReadRTC(void); // unsigned char *p_rtc;读取
#endif
蓝桥杯第四届初赛“模拟智能灌溉系统”设计任务书相关推荐
- 蓝桥杯单片机第四届省赛题详细讲解(模拟智能灌溉系统)
看之前强烈建议先自己做一遍!!! 整个工程文件(有注释讲解) 网盘链接 先上演示效果 蓝桥杯单片机第五届模拟智能灌溉系统 首先依旧从赛题的系统框图开始讲起 首先需要做的是将系统框图里的各部分模块提前调 ...
- 蓝桥杯单片机省赛——第五届(模拟智能灌溉系统)
蓝桥杯单片机省赛--第五届(模拟智能灌溉系统) 一.题目内容 二.程序源代码 1.主函数 2.ds1302驱动函数 3.iic驱动函数 注意:驱动代码需要改动一下,可以将原驱动代码按照下面的代码修改 ...
- 蓝桥杯第五届省赛模拟试题--“模拟智能灌溉系统”
题目要求 功能简述 要求"模拟智能灌溉系统" 能够实现土壤湿度测量. 土壤湿度和时间显示. 湿度阈值设定及存储等基本功能. 通过电位器 Rb2 输出电压信号,模拟湿度传感器输出信号 ...
- 第四届蓝桥杯单片机省赛 自动灌溉系统
第四届蓝桥杯单片机省赛 自动灌溉系统 新手.所用驱动为大赛提供驱动 #include<stc15f2k60s2.h> #include "intrins.h"#defi ...
- 第四届-模拟智能灌溉系统
一. 题目概述: 目的: 通过电位器 Rb2 输出电压信号,模拟湿度传感器输出信号,再通过AD 采集完成湿度测量功能: 通过 DS1302 芯片提供时间信息: 通过按键完成灌溉系统控制和湿度阈值调整功 ...
- 单片机的模拟智能灌溉系统
最近在写简历,于是我开始翻翻我的电脑里面有什么存货可以拿来晒晒,没成想,还真有不少啊,于是我就先拿出一部分当年写的单片机程序来晒晒了! 首先是我当年的得意之作,模拟智能灌溉系统: 先上原理图 这是用p ...
- 蓝桥杯单片机省赛——第四届“模拟智能灌溉系统”程序
文章目录 前言 一.任务要求 二.代码部分 1.蜂鸣器控制部分 2.继电器控制部分 3.LED控制部分 4.定时器设置部分 5.数码管动态刷新程序 6.总代码 前言 程序是之前打的,没有进行过优化,希 ...
- 【蓝桥杯单片机组第四届模拟题】— “模拟智能灌溉系统”
1.功能简述 2.设计任务及要求 2.1 系统
- 蓝桥杯单片机第四届 省赛 模拟智能灌溉系统(第五届模拟赛)
如果有用请点赞,还会继续更新的 题目: 思路: 这个程序用到的iic总线技术完成了EEPROM断电存储和ADC的模拟,然后通过了DS1302完成了时钟单元,这个程序最困扰我的就是蜂鸣器了,不得不写了一 ...
- 蓝桥杯第四届初赛-买不到的数目-数论
题目描述 小明开了一家糖果店.他别出心裁:把水果糖包成4颗一包和7颗一包的两种.糖果不能拆包卖. 小朋友来买糖的时候,他就用这两种包装来组合.当然有些糖果数目是无法组合出来的,比如要买 10 颗糖. ...
最新文章
- leetcode题解:Search in Rotated Sorted Array(旋转排序数组查找)
- java常见业务对象_Java各种对象(PO,BO,VO,DTO,POJO,DAO,Entity,JavaBean,JavaBeans)的区分...
- ​Spring事务的传播行为案例分析
- 我用AI回怼美女汽车销售系列[yolo车牌识别](五) 完结
- 从Excel读取数据,然后分析相似的数据,多线程处理(多线程比较相似的字符串,统计出相似的数量及字符串)...
- mfc控件位置随对话框窗口移动
- 百度编辑器图片上传功能解疑
- Apple Watch UX流程套件 Fresh模板
- ASP.NET MVC:实现我们自己的视图引擎
- open cv python_Open CV非常牛逼!众所周知!今天就来见识一下它究竟有多牛逼!
- (新年快乐)ABP理论学习之本地化(2016第一篇)
- Qt - 菜单栏、工具栏、状态栏(菜单栏、工具栏、状态栏添加方法)
- 我,马斯克:地球首富却要葬在火星
- 大型Web网站优化总结一
- 试用期程序员应该了解的事儿
- 2021年上半年软考真题数据库系统工程师真题
- layui数据表格的字体颜色
- 智力游戏(搬山游戏)
- python(pyqt5)多线程解决界面无响应
- 微信消息推送消息加解密(golang)
热门文章
- android底部蒙版,Android实现蒙版弹出框效果
- springboot+宿舍管理小程序 毕业设计-附源码171008
- QQ空间g_tk加密算法实现原理研究
- HDU 4699 题解
- JS旋转木马图片轮播
- 全国各地电信网通铁通DNS服务器IP地址
- dnf连不上服务器删什么文件,DNF:4.9更新“无法上游戏”,删1个文件才可登录,策划不争气!...
- 在东京,月薪25万日元能过上什么样的日子啊
- AI公开课:03月26日未来十年 AI如何进化—圆桌探讨(乌镇智库理事长、CSDN 创始人董事长、智源人工智能研究院副院长)之《AI:昨天 · 今天 · 明天》
- 关于CSDN原力计划活动说明