基于51的多功能小风扇,可以实现定时,摇头,超声波自动调速等功能

最近也是想加入一个实验室,考核题目就是写一个小风扇!下面是题目要求
基于51的多功能小风扇,可以实现定时,摇头,超声波自动调速等功能_第1张图片
由于我也是大一新生,也就自学了一点51和c语言知识,代码写的可能有点拙,还请多多指教!

#include <REGX52.H>
typedef unsigned char uchar;
typedef unsigned int uint;

uint PWM,compare,Speed;//调速
uchar Nixie_Flag;//数码管扫描标志位
uchar irtime;//红外用全局变量
uchar ircord[4];  //客户码1+客户码2+操作码+操作反码
uchar irdata[33];  //1+8+8+8+8=33																	    
uchar H=0;//关闭自动调速用变量
bit I=0;
uchar J=0;//定时用变量
bit K=0;
bit L=0;
uchar PWM1,compare1=2;//舵机角度用变量
uint Time;//摇头
uchar Q;
bit S;
uint Flag1,Flag2;	//按键扫描
bit Start;
bit Over;
int One_Minute=2000;//数码管显示时间用变量
int hundred=9;
int unit=9;
bit irpro_ok,irok;//红外
sbit IR=P3^2;
sbit Trig=P1^7;//超声波
sbit Echo=P1^6;
sbit ENA=P2^6;//电机
sbit IN1=P2^4;
sbit IN2=P2^5;
sbit IN3=P3^4;//舵机
sbit IN4=P3^5;
sbit LED1=P2^3;//LED显示遥控逐级档
sbit LED2=P1^3;//LED显示按键档
sbit LED3=P1^4;
sbit LED4=P1^5;
sbit Key1=P2^2;//按键
sbit Key2=P3^3;
sbit Key3=P2^1;
sbit Key4=P2^0;
sbit Control=P2^7;//舵机控制

//void Delay(unsigned int xms)		//软件延时?太逊了吧
//{
//	unsigned char i, j;
//	while(xms)
//	{
//		i = 2;
//	j = 239;
//	do
//	{
//		while (--j);
//	} while (--i);
//		xms--;
//	}
//}

uint NixieTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴极数码管
void Nixie(uint Location ,Number)
{
	switch(Location)
	{
		case 1:P1_0=0;P1_1=1;P1_2=1;break;
		case 2:P1_0=1;P1_1=0;P1_2=1;break;
		case 3:P1_0=1;P1_1=1;P1_2=0;break;
	}
	P0=NixieTable[Number];
}
void Nixie_Scan()	//数码管扫描
{
	if(Nixie_Flag==0) Nixie(1,compare);
	else if(Nixie_Flag==2) Nixie(2,hundred);
	else if(Nixie_Flag==4) Nixie(3,unit);
	else P0=0X00;
}
void Key_scan()	//按键扫描干活
{
	if(Flag1<15){Start=1;return;}
	if(Flag1>=15)
	{		
		Start=0;
		Flag1=0;
		if(Key1==0)
		{
			H=0;
			Speed++;
			Speed%=4;
			if(Speed==0){compare=0;LED2=1;LED3=1;LED4=1;}
			else if(Speed==1){compare=2;LED2=0;LED3=1;LED4=1;}
			else if(Speed==2){compare=5;LED2=1;LED3=0;LED4=1;}
			else{compare=9;LED2=1;LED3=1;LED4=0;}
			Over=1;
			return;
		}
		else if(Key2==0)
		{	
			H++;
			I=H%2;
			Over=1;
			return;
		}
		else if(Key3==0)
		{
			hundred--;
			if(hundred<0) hundred=9;
			Over=1;
			return;
		}
		else
		{
			unit--;
			if(unit<0) unit=9;
			Over=1;
			return;
		}
	}
}
unsigned long Distance() //超声波处理程序
{
	unsigned char i=2;
	float time;
	float a;
	int distance=(int)a;

	T2CON=0;			//定时器2初始化
	TL2=0;
	TH2=0;
	RCAP2L=0;
	RCAP2H=0;
	Trig=0;
	Trig=1;
	while(--i);
	Trig=0;
	while(!Echo);
	TR2=1;						//定时器2计算超声波时间
	while(Echo);
	TR2=0;
	time=(TH2*256+TL2)*0.9216;
	TH2=0;
	TL2=0;
	a=(time*1.7)/100;
	return distance;
}
void Timer1_Init(void)	//定时器1初始化用于红外记时译码
{
	TMOD &=0x0f;
	TMOD |=0x20;
	TH1=0X00;
	TL1=0X00;
	ET1=1;
	TR1=1;
}
void INT0_Init(void)	//用于红外接收外部中断0初始化
{
	IT0=1;
	EX0=1;
}
void ir_work(void) 	//红外遥控器键码读取执行程序     			 
{
	switch(ircord[2])
	{	
		case 0x19:compare=0;H=0;	//0 
		break;	
		case 0x45:compare=1;H=0;	//1
		break;
		case 0x46:compare=2;H=0;	//2
		break;	
		case 0x47:compare=3;H=0;	//3
		break;
		case 0x44:compare=4;H=0;	//4
		break;
		case 0x40:compare=5;H=0;	//5
		break;
		case 0x43:compare=6;H=0;	//6
		break;
		case 0x07:compare=7;H=0;	//7
		break;
		case 0x15:compare=8;H=0;	//8
		break;
		case 0x09:compare=9;H=0;	//9
		break;
		case 0x16:H++;I=H%2;			//*
		break;
		case 0x0d:J++;K=J%2;L=1;	//#
		break;
		case 0x18:hundred--;if(hundred<0){hundred=9;}		//上
		break;
		case 0x52:unit--;if(unit<0){unit=9;}						//下
		break;
		case 0x08:compare1++;if(compare1>4){compare1=1;}//左
		break;
		case 0x5a:compare1--;if(compare1<1){compare1=4;}//右
		break;
		case 0x1c:Q++;S=Q%2;														//ok
		break;
		default:break;
	}
}

void ircordpro(void)		//读取红外数据码
{
	unsigned char i,j,k;
	unsigned char cord,value;
	k=1;
	for(i=0;i<4;i++)
	{	
		for(j=1;j<=8;j++)
		{
			cord=irdata[k];
			if(cord>7)
				value|=0x80;
			if(j<8)
			{
				value>>=1;
			}
			k++;
		}
		ircord[i]=value;
		value=0;
	}
	irpro_ok=1;
}

void Timer1_Routine(void) interrupt 3 using 1		//定时器1中断用于红外记时译码
{
	irtime++;
}
void Int0_Routine(void) interrupt 0		//外部中断0处理红外NFC协议客户码
{
	static unsigned char i;
	static bit startflag;
	if(startflag)
	{
		if(irtime<50&&irtime>=33)
			i=0;
		irdata[i]=irtime;
		irtime=0;
		i++;
		if(i==33)
		{
			irok=1;
			i=0;
		}
	}
	else
	{
		irtime=0;
		startflag=1;
	}
}

void Timer0_init()  //定时器0初始化
{
	TMOD &=0Xf0;
	TMOD |=0x01;
	TH0=(65536-542)/256;
	TL0=(65536-542)%256;
	TF0=0;
	TR0=1;
	PT0=0;	//最低
	PT1=1;	//次低
	PX0=0;	//红外次高
	PX1=1;	//按键中断最高
	IPH=0x05;
	EA=1;
	ET0=1;
}
void Timer0_Routine() interrupt 1				//定时器0中断干活!
{
	TH0=(65536-542)/256;
	TL0=(65536-542)%256;
	//风扇电机
	PWM++;
	if(PWM>10) PWM=0;
	if(PWM<compare){ENA=1;LED1=0;}
	else {ENA=0;LED1=1;}
	//数码管扫描
	Nixie_Flag++;
	if(Nixie_Flag>=6) Nixie_Flag=0;
	Nixie_Scan();
	//舵机角度
	PWM1++;
	if(PWM1>40) PWM1=0;
	if(PWM1<compare1) Control=1;
	else Control=0;
	//自动摇头
	Time++;
	if(Time>12000) Time=0;
	//定时
	if(K==1)
	{		
		if(L==1)
		{
			One_Minute--;	
			if(One_Minute==0){unit--;}
			if(One_Minute<0){One_Minute=2000;}
			if(unit<0){unit=9;hundred--;}
			if(unit==0&&hundred==0){unit=9;hundred=9;IN1=0;IN2=0;L=0;S=0;Q=0;}
		}
		else{unit=9;hundred=9;}
	}
	else{IN1=0;IN2=1;}
	//按键扫描
	if(Start==1)
	{
		Flag1++;
	}
	if(Over==1)
	{
		Flag2++;
		if(Flag2>400){Flag2=0;Over=0;}
	}
	if(Key1==0||Key2==0||Key3==0||Key4==0)
	{
		if(Over==0) Key_scan();
	}
	//红外接收处理
	if(irok)
	{
		ircordpro();
		irok=0;
	}
	if(irpro_ok)
	{
		ir_work();
		ircord[2]=0;
	}
}
void main()
{
	INT0_Init();
	Timer1_Init();
	Timer0_init();
	IN1=0;
	IN2=1;
	IN3=1;
	IN4=0;
	P2_0=1;P2_1=1;P2_2=1;P1_3=1;P1_4=1;P1_5=1;P2_7=0;
	for(;;)
	{
		if(S==1)	//摇头
		{
			while(1)
			{
				if(S==0) break;
				if(I==1) {S=0;compare=2;break;}
						
				if(Time<=2000) compare1=1;
				else if(Time<=4000) compare1=2;
				else if(Time<=6000) compare1=3;
				else if(Time<=8000) compare1=4;
				else if(Time<=10000) compare1=3;
				else compare1=2;
			}
		}
		if(I==1)	//超声波测距调速
		{
			while(1)
			{					
				if(H==0) break;
				if(I==0){compare=0;break;}
				if(S==1) {I=0;break;}
							
				if(Distance()<=10) compare=2;
				else if(Distance()<=20) compare=3;
				else if(Distance()<=30) compare=5;
				else if(Distance()<=40) compare=6;
				else if(Distance()<=60) compare=7;
				else compare=9;
			}
		}
	}
}

你可能感兴趣的:(笔记,51单片机,嵌入式硬件)