蓝桥杯第七届省赛 风扇模拟系统

【冉冰的成长日记001】

咕咕咕,鸽了17天我他喵终于写了一篇省赛。写这篇文章的目的是用以复习和留念一下,如若能帮助到他人和下一届的学弟学妹自然是极好的。QAQ话不多说,上代码。

#include<STC15F2K60S2.h>
#include"onewire.h"

unsigned char LED[]={
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0xBF,0xFF,0xC6  
};							//定义数码管
unsigned char LEDbuff[]={
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
};							//数码管缓冲区
sbit S7=P3^0;
sbit S6=P3^1;
sbit S5=P3^2;
sbit S4=P3^3;  				
unsigned int num=0;			//用于定时器0计数,每一秒获取一次温度和工作剩余时间倒计时
unsigned char Temp,cnt=0;	//Temp用于获取DS18B20的温度。cnt用于风扇pwm输出占空比的计算
unsigned char S4_flag=1,S5_time=0; //S4_flag用于切换模式,S5_time用于S6按键计时和按键定时
bit MOTOR=0,Check_S4 = 0,Check_S5 = 0,Check_S6 = 0,Check_S7 = 0,S7_flag=0;
//MOTOR用于外设输出,Check_Sx用于检测按键按下,S7_flag用于切换模式四

void Initial();		//初始化函数
void KEY();			//按键
void Display();		//数码管显示
void Timer0Init();	//定时器0
void Timer1Init();	//定时器1
void main()
{
	Initial();
	Timer0Init();
	Timer1Init();
	while(1)
	{
		KEY();
		if(num>=10000)	  //num每0.1ms加一,10000即1s
		{
			if(S5_time>0)  
			{
				S5_time--;//工作剩余时间
			}
			num=0;	
			DS18B20_Start();	//每一秒获取一次温度
			Temp=DS18B20_Get();
		}
	}
}

void Initial()		//初始化函数
{
	P2 = (P2&0x1F)|0x80;
	P0 = 0xFF;		//初始化LED

	P2 = (P2&0x1F)|0xA0;
	P0 = 0x00;		//初始化继电器和蜂鸣器

	P2 = (P2&0x1F)|0xC0;
	P0 = 0xFF;
	P2 = (P2&0x1F)|0xE0;
	P0 = 0xFF;      //初始化数码管
}

void Timer0Init(void)		//100微秒@11.0592MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0xAE;		//设置定时初值
	TH0 = 0xFB;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时

	EA = 1;
	ET0 = 1;
}

void Timer1Init(void)		//1毫秒@11.0592MHz
{
	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0xCD;		//设置定时初值
	TH1 = 0xD4;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时

	EA = 1;
	ET1 = 1;
}

void delay(int ms)			//某up debug测的1s我借用了,也可以用定时器来写delay函数
{
	int X=0,Y=0;
	for(X=0;X<ms;X++)
	{
		for(Y=846;Y>0;Y--);
	}
}

void Display1()	   //控制高四位数码管
{
	LEDbuff[7]=LED[10];
	LEDbuff[6]=LED[S4_flag];
	LEDbuff[5]=LED[10];
	LEDbuff[4]=LED[11];	 //不显示
		
}

void Display2()	   //控制低四位数码管
{
	LEDbuff[3]=LED[0];
	LEDbuff[2]=LED[S5_time/100];
	LEDbuff[1]=LED[S5_time/10%10];
	LEDbuff[0]=LED[S5_time%10];
}

void Display3()
{
	 LEDbuff[7]=LED[10];
	 LEDbuff[6]=LED[4];
	 LEDbuff[5]=LED[10];
	 LEDbuff[4]=LED[11];
	 LEDbuff[3]=LED[11];
	 LEDbuff[2]=LED[Temp/10];
	 LEDbuff[1]=LED[Temp%10];
	 LEDbuff[0]=LED[12];	   //题干摄氏度的C
}

void Display()
{
	Display1();
	Display2();
}

void KEY_S4()			   //S4切换工作模式
{
	if(S4==0)
	{
		delay(5);
		if(S4==0)
		Check_S4=1;	
	}
	if((S4==1)&&(Check_S4==1))
	{
		Check_S4=0;	
		S4_flag++;
		if(S4_flag>=4)
		S4_flag=1;
	}	
}
						   //设置计时
void KEY_S5()
{
	if(S5==0)
	{
		delay(5);
		if(S5==0)
		Check_S5=1;	
	}
	if((S5==1)&&(Check_S5==1))
	{
		Check_S5=0;	
		S5_time = S5_time+60;
		if(S5_time>=60&&S5_time<120)	S5_time=60;
		if(S5_time>=120&&S5_time<180)	S5_time=120;
		if(S5_time>=180)				S5_time=0;
	}		
}

void KEY_S6()			   //清零
{
	if(S6==0)
	{
		delay(5);
		if(S6==0)
		Check_S6=1;	
	}
	if((S6==1)&&(Check_S6==1))
	{
		Check_S6=0;
		S5_time=0;
		MOTOR=0;
	}		
}

void KEY_S7()			  //显示温度
{
	if(S7==0)
	{
		delay(5);
		if(S7==0)
		Check_S7=1;	
	}
	if((S7==1)&&(Check_S7==1))
	{
		Check_S7=0;
		S7_flag = ~S7_flag;	
	}
}

void KEY()
{
	KEY_S4();
	KEY_S5();
	KEY_S6();
	KEY_S7();
}

void Show1()			//LED小灯随工作模式变化
{
	if(S4_flag==1)
	{
		P2 = (P2&0x1F)|0x80;
		P0 = 0xFE;	
	}

	if(S4_flag==2)
	{
		P2 = (P2&0x1F)|0x80;
		P0 = 0xFD;	
	}

	if(S4_flag==3)
	{
		P2 = (P2&0x1F)|0x80;
		P0 = 0xFB;	
	}
}

void Show2()				   //模式四关闭LED
{
	 	P2 = (P2&0x1F)|0x80;
		P0 = 0xFF;

}

void InterruptTimer0() interrupt 1
{
 	TL0 = 0xAE;		//设置定时初值
	TH0 = 0xFB;		//设置定时初值

	cnt++;
	if(cnt>=10)		{cnt=0;}					   //各工作模式占空比
	if(S4_flag==1)
	{
		if(cnt<=2)		MOTOR=1;
		else			MOTOR=0;
	}

	if(S4_flag==2)
	{
		if(cnt<=3)		MOTOR=1;
		else			MOTOR=0;
	}

	if(S4_flag==3)
	{
		if(cnt<=7)		MOTOR=1;
		else			MOTOR=0;
	}

	num++;
}

void InterruptTimer1() interrupt 3
{
	static unsigned char i = 0;
	TL1 = 0xCD;		//设置定时初值
	TH1 = 0xD4;		//设置定时初值

	if(S7_flag==0)					   //S7切换温度显示页面
	{
	Display();
	Show1();
	}
	if(S7_flag==1)		
	{
	Display3();
	Show2();
	}

	switch(i)		//数码管动态刷新
	{
		case 0:P2=0xC0;P0=0x80;P2=0xE0;P0=LEDbuff[0];i++;break;
		case 1:P2=0xC0;P0=0x40;P2=0xE0;P0=LEDbuff[1];i++;break;
		case 2:P2=0xC0;P0=0x20;P2=0xE0;P0=LEDbuff[2];i++;break;
		case 3:P2=0xC0;P0=0x10;P2=0xE0;P0=LEDbuff[3];i++;break;
		case 4:P2=0xC0;P0=0x08;P2=0xE0;P0=LEDbuff[4];i++;break;
		case 5:P2=0xC0;P0=0x04;P2=0xE0;P0=LEDbuff[5];i++;break;
		case 6:P2=0xC0;P0=0x02;P2=0xE0;P0=LEDbuff[6];i++;break;
		case 7:P2=0xC0;P0=0x01;P2=0xE0;P0=LEDbuff[7];i=0;break;
		default :break;
	}
}

以上是main,身边的人喜欢把main.c中的key和displsy部分拆出来写成新的c文件,方便他人阅读。各有各的好处吧,我更喜欢放一起,方便调用和查阅。各位看官多多担待吧。

/*
  程序说明: 单总线驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台(外部晶振12MHz) STC89C52RC单片机
  日    期: 2011-8-9
*/
#include<STC15F2K60S2.h>
#include"onewire.h"

sbit DQ = P1^4;  //单总线接口

//单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC
{
	t=10*t;     //stc的运行速度是传统51的7-12倍
	while(t--);
}

//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(5);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(5);
}

//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		if(DQ)
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(5);
	}
	return dat;
}

//DS18B20设备初始化
bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(12);
  	DQ = 0;
  	Delay_OneWire(80);
  	DQ = 1;
  	Delay_OneWire(10); 
    initflag = DQ;     
  	Delay_OneWire(5);
  
  	return initflag;
}

void DS18B20_Start()
{
	init_ds18b20();
	Write_DS18B20(0xCC);
	Write_DS18B20(0x44);
	Delay_OneWire(200);
}

unsigned char DS18B20_Get()
{
	char temp = 0;
	unsigned char low=0,high=0;
	init_ds18b20();
	Write_DS18B20(0xCC);
	Write_DS18B20(0xBE);

	low= Read_DS18B20();
	high= Read_DS18B20();
	temp = (high<<4);
	temp |= (low>>4); 

	return temp;
	
}

以上是iic通信的c文件

#include<STC15F2K60S2.h>


#ifndef __ONEWIRE_H
#define __ONEWIRE_H

unsigned char rd_temperature(void); 
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);
void DS18B20_Start();
unsigned char DS18B20_Get();


#endif

以上是.h文件

结束

立个flag,下一篇12号之前写出来,如果没发,请私信骂我,谢谢

在这里插入图片描述

  • 20
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冉冰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值