蓝桥杯单片机省赛——第四届“模拟智能灌溉系统”程序

往期回顾

第三届蓝桥杯单片机省赛


前言

程序是之前打的,没有进行过优化,希望能互相学习并借鉴


一、任务要求

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、代码部分

1.蜂鸣器控制部分

bit on
bit----------C51扩展的变量类型
bit和int char之类的差不多,只不过char=8位, bit=“1位而已”,都是变量
其数据有两种取值:0和1,在输入0以外的其他值时,系统均把它们当1看待
一般来说我们可以用于表示真、假或是、否等二值选择

on ----------自定义的变量
这里主要是设置两种模式
on为0时关闭继电器,为1时开启蜂鸣器


为什么是0x40开启蜂鸣器
在这里插入图片描述
0x40转换成二进制是 100 0000,对应上图,蜂鸣器位置1,其他置0

代码如下:

void buzz(bit on)
{
	P2=((P2&0x1f)|0xa0);
	if(on)
		P0=0x40;
	else
		P0=0x00;
	P2&=0x1f;
}

2.继电器控制部分

代码如下:

void jdq(bit on)
{
	P2=((P2&0x1f)|0xa0);
	if(on)
		P0=0x1f;
	else
		P0=0x00;
	P2&=0x1f;
}

3.LED控制部分

int类型:int类型时有符号的整数,即int类型的值可以是正整数或者负整数

i ----------自定义的变量
这里主要是控制那些灯亮

代码如下:

void led(int i)
{
	P2=((P2&0X1F)|0X80);
	P0=i;
	P2&=0X1F;
}

4.定时器设置部分

TMOD=0x10 :
作用:设置定时器1为方式1模式(16位定时器/计数器)。

TH1=(65536-11059/12)/256;
TL1=(65536-11059/12)%256;

作用:设置初始值约为1000,可以简单理解为0.1s 刷新一次

代码如下:

void din()
{
	TMOD=0X10;
	TH1=(65536-11059/12)/256;
	TL1=(65536-11059/12)%256;
	TR1=1;
	EA=1;
	ET1=1;
}


或者也可以用stc直接生成,这是之前打的代码,之后就一般用stc了
在这里插入图片描述

5.数码管动态刷新程序

代码如下:

void display()
{
	P2=((P2&0x1f)|0xe0);
	P0=0xff;
	P2&=0x1f;
	
	P2=((P2&0x1f)|0xc0);
	P0=1<<diswela;
	P2&=0x1f;
	
	P2=((P2&0x1f)|0xe0);
	P0=dula[disdula[diswela]];
	P2&=0x1f;
	
	if(++diswela>=8)diswela=0;
}

· 1.问: 第一个P0=0xff;具体表达什么意思
答:相当于清屏,消隐

  1. 问:第二个P0=1<<diswela;具体表达什么意思
    答:diswela(全局变量)用来选定当前数码管显示位置,例如diswela=0时,点亮选中第一个数码管,diswela=1时,选中第二个数码管,只有当选中的时候才能将位码的值传给他,而这段代码也要和最下面这个一起看
if(++diswela>=8)diswela=0;

而这里的表示的意思,按顺序选择第一到第八个数码管

  1. 问:第三个P0=dula[disdula[diswela]]; 具体表达什么意思
    答:
    dula[ ]放置段码的数组,简单理解就是数码管上显示0-9的数组
    disdula[ ]放置你自己想选择的数字的数组
    dula[disdula[diswela]]在数码管上显示的具体数字
    举个例子:
    前置条件disdula[ ]={5,1,2,3,4,5,6};
    如果我想让数码管的第一位显示一个数字5的话,那这个函数会怎么样
    diswela=0------表示选择第一位数码管
    disdula[diswela] 变成了 disdula[0]-------------表示用你在这里的第一个数字5
    dula[disdula[diswela]]] 变成了 dula[5]-----------在八位数码管显示5

6.总代码

用蓝桥杯官方提供的驱动

#include<stc15f2k.h>
#include<iic.h>
#include<ds1302.h>
sbit s7=P3^0;
sbit s6=P3^1;
sbit s5=P3^2;
sbit s4=P3^3;
char ds1302_write[]={0X80,0x82,0x84};
char ds1302_read[]={0X81,0x83,0x85};
char time[]={0,30,8};
char dula[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};
char disdula[]={0,0,0,0,0,0,0,0};
int diswela,ms,key,sign,date,shezhi=3;
int date_1;
bit flag;

void buzz(bit on)
{
	P2=((P2&0x1f)|0xa0);
	if(on)
		P0=0x40;
	else
		P0=0x00;
	P2&=0x1f;
}

void jdq(bit on)
{
	P2=((P2&0x1f)|0xa0);
	if(on)
		P0=0x1f;
	else
		P0=0x00;
	P2&=0x1f;
}

void led(int on)
{
	P2=((P2&0x1f)|0x80);
	P0=on;
	P2&=0x1f;
}

void delay(int x)
{
	int i;
	while(x--)
	for(i=0;i<5*123;i++);
}

void din()
{
	TMOD=0X10;
	TH1=(65536-11059/12)/256;
	TL1=(65536-11059/12)%256;
	TR1=1;
	EA=1;
	ET1=1;
}

void display()
{
	P2=((P2&0x1f)|0xe0);
	P0=0xff;
	P2&=0x1f;
	
	P2=((P2&0x1f)|0xc0);
	P0=1<<diswela;
	P2&=0x1f;
	
	P2=((P2&0x1f)|0xe0);
	P0=dula[disdula[diswela]];
	P2&=0x1f;
	
	if(++diswela>=8)diswela=0;
}

void display_ds1302()
{
	disdula[0]=time[2]/16;
	disdula[1]=time[2]%16;
	disdula[2]=10;
	disdula[3]=time[1]/16;
	disdula[4]=time[1]%16;
	disdula[5]=11;
	disdula[6]=date/10;
	disdula[7]=date%10;
}

void bcddce()
{
	int i;
	for(i=0;i<3;i++)
	{
			time[i]=((time[i]/10)<<4)|(time[i]%10);
	}
}

void ds_write()
{
	int i;
	bcddce();
	Write_Ds1302_Byte(0x8e,0x00);
	for(i=0;i<3;i++)
	{
		Write_Ds1302_Byte(ds1302_write[i],time[i]);
	}
	Write_Ds1302_Byte(0x8e,0x80);
}

void ds_read()
{
	int i;
	for(i=0;i<3;i++)
	{
		time[i]=Read_Ds1302_Byte(ds1302_read[i]);
	}
}

char ad()
{
	int date;
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x03);
	IIC_WaitAck();
	IIC_Stop();
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	date=IIC_RecByte();
	IIC_WaitAck();
	IIC_SendAck(1);
	IIC_Stop();
	
	if(date>=255)date=254;
	date=(date*100)/255;
	return date;
}

char anjian()
{
	static int key_up=1;
	int keyscan=0;
	if(key_up&&(s7==0||s6==0||s5==0||s4==0))
	{
		key_up=0;
		delay(20);
		if(s4==0)keyscan=4;
		else if(s5==0)keyscan=5;
		else if(s6==0)keyscan=6;
		else if(s7==0)keyscan=7;
	}else if(s7==1&&s6==1&&s5==1&&s4==1)key_up=1;
	return keyscan;
}

void zawu()          //¼ÌµçÆ÷ºÍledµÄÄÚÈÝ
{
	if(date>=date_1)
		jdq(0);
	else if(date<date_1)
		jdq(1);	
}

void display_zidong() //shezhiΪ0µÄʱºòΪ×Ô¶¯£¬1µÄʱºòΪÊÖ¶¯,3µÄʱºòΪ³£¹æ
{
	disdula[0]=10;
	disdula[1]=10;
	disdula[2]=11;
	disdula[3]=11;
	disdula[4]=11;
	disdula[5]=11;
	disdula[6]=date_1/10;
	disdula[7]=date_1%10;
}

void at24c02_write(int add,int date)
{
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_SendByte(date);
	IIC_WaitAck();
	IIC_Stop();
}

char at24c02_read(int add)
{
	int date;
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	
	IIC_Start();
	IIC_SendByte(0xa1);
	IIC_WaitAck();
	date=IIC_RecByte();
	IIC_WaitAck();
	IIC_SendAck(1);
	IIC_Stop();	
	return date;
}

void main()
{	
	buzz(0);
	jdq(0);
	led(0xff);
	date_1=at24c02_read(0x01);
	if(date_1==0)date_1=50;
	delay(10);
	din();
	led(0xfe);
	ds_write();
	while(1)
	{		
		if(shezhi==1)led(0xfd);	
		else if(shezhi==0){display_zidong();}		
		else if(shezhi==3)
		{		
		zawu();	
			
		display_ds1302();
		ds_read();	
		}		
		
		if(flag==1)
		{
			date=ad();			
			flag=0;
			key=anjian();
			switch(key)
			{
				case 4:
					if(shezhi==0)
					{
						date_1--;
						if(date_1==0)date_1=0;
					}
					if(shezhi==1)
					{
						if(sign==0){jdq(1);}					
					}
				break;
					
					
				case 5:
					if(shezhi==0)
					{
						date_1++;
						if(date_1==99)date_1=99;
					}					
					if(shezhi==1)
					{
						if(sign==0){jdq(0);}
						
					}
				break;
					
					
				case 6:
					if(shezhi==3){shezhi=0;led(0xfe);}
					else if(shezhi==0){shezhi=3;at24c02_write(0x01,date_1);}
					
					if(shezhi==1)
					{
						if(sign==0){sign=1;buzz(1);}
						else if(sign==1){sign=0;buzz(0);}
					}
				break;
					
					
				case 7:
					if(shezhi==3)shezhi=1;
					else if(shezhi==1){shezhi=3;led(0xfe);}
				break;
			}
		}
	}
}


void qa() interrupt 3
{
	TH1=(65536-11059/12)/256;
	TL1=(65536-11059/12)%256;
	ms++;
	if(!(ms%100))flag=1;
	if(ms>=1500)ms=0;
	display();
}

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值