最近也是想加入一个实验室,考核题目就是写一个小风扇!下面是题目要求
由于我也是大一新生,也就自学了一点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;
}
}
}
}