蓝桥杯省赛笔记之2013省赛试题
模拟智能灌溉
考
点
=
{
I
I
C
总
线
驱
动
(
P
C
F
8591
,
E
E
P
R
O
M
)
时
钟
(
D
S
1302
)
独
立
键
盘
考点=\left\{ \begin{aligned} && \ IIC总线驱动(PCF8591,EEPROM) \\ && \ 时钟(DS1302) \\ && \ 独立键盘 \end{aligned} \right.
考点=⎩⎪⎨⎪⎧ IIC总线驱动(PCF8591,EEPROM) 时钟(DS1302) 独立键盘
设计任务及要求
1. 系统工作及初始化状态说明
1.1 自动工作状态,根据湿度数据自动控制打开或关闭灌溉设备,以 L1 点亮指示;
1.2 手动工作状态,通过按键控制打开或关闭灌溉设备,以 L2 点亮指示;
1.3 系统上电后处于自动工作状态,系统初始湿度阈值为 50%,此时若湿度低于50%,灌溉设备自动打开,达到 50%后,灌溉设备自动关闭;
1.4 灌溉设备打开或关闭通过继电器工作状态模拟。
2. 数码管单元
时间及湿度数据显示格式如图 2 所示:
0 8 - 3 0 8 0 5
时(8时) 分隔符 分(30分) 熄灭 湿度(5%)
数码管DS1 数码管DS2
图 2. 显示格式(8 点 30 分,土壤湿度 5%)
3. 报警输出单元
系统工作于手动工作状态下时,若当前湿度低于湿度阈值,蜂鸣器发出提示音,并可通过按键 S6 关闭提醒功能。
4. 功能按键
2.1 按键 S7 设定为系统工作状态切换按键;
2.2 手动工作状态下按键 S6、S5、S4 功能设定如下:
按下 S6 关闭蜂鸣器提醒功能,再次按下 S6 打开蜂鸣器提醒功能,如此循环;
S5 功能设定为打开灌溉系统;
S4 功能设定为关闭灌溉系统。
2.3 自动工作状态下按键 S6、S5、S4 功能设定如下:
S6 功能设定为湿度阈值调整按键,按下 S6 后,进入湿度阈值调整界面(如图 3所示),此时按下 S5 为湿度阈值加 1,按下 S4 湿度阈值减 1,再次按下 S6 后,系统将新的湿度阈值保存到 EEPROM 中,并退出湿度阈值设定界面。
–8 8 8 8 5 2
图 3. 湿度阈值设定界面
5. 实时时钟
“模拟智能灌溉系统”通过读取 DS1302 时钟芯片相关寄存器获得时间,DS1302芯片时、分、秒寄存器在程序中设定为系统进行初始化设定,时间为 08 时 30 分。
6. 湿度检测单元
以电位器 Rb2 输出电压信号模拟湿度传感器输出信号,且假定电压信号与湿度成正比例关系 H 湿度 = KVRb2(K 为常数),Rb2 电压输出为 5V 时对应湿度为 99%。
7. EEPROM 存储单元
系统通过 EEPROM 存储湿度阈值,自动工作状态下,可通过按键 S6、S5、S4 设置和保存阈值信息。
8. 电路设计部分
使用 PTC 热敏电阻、场效应管、继电器及简单阻容元件设计“智能灌溉系统”中置于电机内部的过热保护电路,当电机内部温度超过 70℃,断开电机电源,设计电路原理图并简述设计思路与电路工作原理。
PTC 热敏电阻参数说明:
当温度小于 68℃时,热敏电阻阻值小于 100 欧姆;温度超过 68℃后,电阻值随温度
升高呈阶跃性增高,温度到达 70℃后,热敏电阻阻值接近 10kΩ。
笔记
- 温度测量,此处用滑动电阻器替代
- 读的函数得自己写
- EEPROM的读与写要自己写
- DS1302时钟
- 修改阈值
可以先写入读取EEPROM,烧录后,把读取的函数除去,再烧录 - 关于独立按键函数里面,可以创建变量,改变变量的值(0/1)再单独创建函数写关于此变量的程序。
- 蜂鸣器代码
P2=0XA0;P0=0X40//蜂鸣器开
- 取反符号:~
代码块
呈上代码:(代码非原创,大家可以品一品)
内插入笔者的注释,尽量详细
#include<STC15F2K60S2.H>
#include "intrins.h"
#include "iic.h"
#include "ds1302.h"
uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};
uchar yi,er,san,si,wu,liu,qi,ba;
uchar shidu;
uchar fazhi;
extern unsigned char shijian[];
bit s6=0,jia=0,jian=0,status=0,kai=1,relay=0;
void allinit(void);
void delayms(uint ms);
void keyscan(void);
void display1(uchar yi,uchar er);
void display2(uchar san,uchar si);
void display3(uchar wu,uchar liu);
void display4(uchar qi,uchar ba);
void main(void){
allinit();
DS_init();
P2=0X80;P0=0XFE;
yi=0;er=8;san=10;si=3;wu=0;liu=11;qi=0;ba=0;
fazhi=EEPROM_read(0x10); //阈值存入0X10 也从0X10读出来
while(1){
DS_get();
shidu=AD_read(0x03); //AD转换读出当前湿度值
if(status==0){ //自动状态
if(shidu<fazhi){ //湿度小于阈值 打开继电器
P2=0XA0;P0=0X10;
}
else{ //湿度大于阈值 关闭继电器
P2=0XA0;P0=0X00;
}
if(s6==1){ //S6被按下 进入阈值调整状态
if(jia==1){
jia=0;
fazhi=fazhi+1; //阈值加一
}
if(jian==1){
jian=0;
fazhi=fazhi-1; //阈值减一
}
yi=10;er=10;san=11;si=11;wu=11;liu=11;qi=fazhi/10;ba=fazhi%10;
}
else if(s6==0){ //S6未被按下 未进入阈值调整状态
yi=shijian[2]/10;er=shijian[2]%10;san=10;
si=shijian[1]/10;wu=shijian[1]%10;liu=11;
qi=shidu/10;ba=shidu%10;
}
}
else if(status==1){ //手动状态
if((shidu<fazhi)&&(kai==0)){ //湿度小于阈值 且蜂鸣器没开
if(relay==1){P2=0XA0;P0=0X10;} //开继电器程序
else if(relay==0){P2=0XA0;P0=0X00;}//关继电器程序
}
if((shidu<fazhi)&&(kai==1)){ //湿度小于阈值 且蜂鸣器开
if(relay==1){P2=0XA0;P0=0X50;}
else if(relay==0){P2=0XA0;P0=0X40;}
}
else if(shidu>fazhi){
if(relay==1){P2=0XA0;P0=0X10;} //开继电器程序
else if(relay==0){P2=0XA0;P0=0X00;}//关继电器程序
}
yi=shijian[2]/10;er=shijian[2]%10;san=10;
si=shijian[1]/10;wu=shijian[1]%10;liu=11;
qi=shidu/10;ba=shidu%10;
}
keyscan();
display1(yi,er);
display2(san,si);
display3(wu,liu);
display4(qi,ba);
}
}
void keyscan(void){ //独立按键程序
if(P30==0){
delayms(5);
if(P30==0){
if(status==0){
status=1; //改变自动/手动模式
P2=0X80;P0=0XFD;
}
else if(status==1){
status=0;
P2=0X80;P0=0XFE;
}
}
while(!P30);
}
else if(P31==0){
delayms(5);
if(P31==0){
if(status==0){
if(s6==0){s6=1;}
else if(s6==1){s6=0;EEPROM_write(0x10,fazhi);}
}
else if(status==1){
kai=~kai; //开蜂鸣器的变量取反
}
}
while(!P31);
}
else if(P32==0){
delayms(5);
if(P32==0){
if(status==0)jia=1;//自动模式下 控制阈值加一的自变量
else if(status==1)relay=1;//手动模式下 开灌溉系统
}
while(!P32);
}
else if(P33==0){
delayms(5);
if(P33==0){
if(status==0)jian=1;//自动模式下 控制阈值减一的自变量
else if(status==1)relay=0; //手动模式下 关灌溉系统
}
while(!P33);
}
}
void allinit(void){ //单片机初始化程序
P2=0XA0;
P0=0x00;//关闭蜂鸣器继电器
P2=0X80;
P0=0XFF;//关闭LED灯
P2=0XC0;
P0=0XFF;//选择所有数码管
P2=0XFF;
P0=0XFF;//关闭多有数码管
}
void display1(uchar yi,uchar er){ //数码管显示代码
P2=0XC0;
P0=0X01;//选择第一个数码管
P2=0XFF;
P0=tab[yi];//数码管显示内容
delayms(1);
P2=0XC0;
P0=0X02;//选择第二个数码管
P2=0XFF;
P0=tab[er];//数码管显示内容
delayms(1);
}
void display2(uchar san,uchar si){
P2=0XC0;
P0=0X04;//选择第三个数码管
P2=0XFF;
P0=tab[san];//数码管显示内容
delayms(1);
P2=0XC0;
P0=0X08;//选择第四个数码管
P2=0XFF;
P0=tab[si];//数码管显示内容
delayms(1);
}
void display3(uchar wu,uchar liu){
P2=0XC0;
P0=0X10;//选择第五个数码管
P2=0XFF;
P0=tab[wu];//数码管显示内容
delayms(1);
P2=0XC0;
P0=0X20;//选择第六个数码管
P2=0XFF;
P0=tab[liu];//数码管显示内容
delayms(1);
}
void display4(uchar qi,uchar ba){
P2=0XC0;
P0=0X40;//选择第七个数码管
P2=0XFF;
P0=tab[qi];//数码管显示内容
delayms(1);
P2=0XC0;
P0=0X80;//选择第八个数码管
P2=0XFF;
P0=tab[ba];//数码管显示内容
delayms(1);
}
void delayms(uint ms){
uint i,j;
for(i=ms;i>0;i--)
for(j=845;j>0;j--);
}