硬件制作資料從http://www.zg4o1577.cn/bbs/dpj-19358-1.html 下載
//課題:無線遙控自行車風(fēng)火輪
//程序編寫:潘觀學(xué)
//單片機(jī):STC89C54RD
//晶振:12MHZ
//單片機(jī)時(shí)鐘模式:6T
#include<stc89.h>
#include "fenghuolun.h" //定義在這里
/*********************************
延時(shí)函數(shù)
***********************************/
void delay_ms(unsigned int i)//1ms基準(zhǔn)延時(shí)
{ unsigned char j;
while(i--)
{ for(j=0;j<246;j++)
{ ;
}
}
}
void delay_us(unsigned int n) //10us延時(shí)
{ uchar i;
uchar j;
for(i=0;i<n;i++) //延時(shí)程序
for(j=0;j<2;j++);
}
/*******************************
呼吸燈
********************************/
void huxi()
{
uint k=0,t,i,j;
for(i=0;i<=350;i++)
{
if((i%4)==0)
k++;
for(t=0;t<=16;t++)
{
led=0;
for(j=0;j<=52;j++)
if(j==k)
led=1;
}
if(enable==1)break;
}
for(i=0;i<=350;i++)
{
if((i%4)==0)
k--;
for(t=0;t<=16;t++)
{
led=0;
for(j=0;j<=90;j++) //j越大速度越慢
if(j==k)
led=1;
}
if(enable==1)break;
}
led=0xff;
delay_ms(200);
}
/******************************
閃爍函數(shù)
*****************************/
void shan()
{
led=0;
delay_ms(100);
led=1;
delay_ms(400);
}
void shan1()
{
led=0;
delay_ms(100);
led=1;
delay_ms(100);
led=0;
delay_ms(100);
led=1;
delay_ms(300);
}
/**********************************
蜂鳴器函數(shù)
************************************/
void beep()
{
fmq=0;
delay_ms(100);
fmq=1;
}
/*******************************
畫面切換函數(shù)
********************************/
void huan()
{ uchar i;
P1=0xff;//P1口設(shè)置為輸入狀態(tài) 先全部寫1
i=P1;//賦值給臨時(shí)存貯變量
i=i&0x0f;//和0x0f相與 屏蔽高四位,讀取無線遙控碼
if (i==0x04)//如果是0x04,則代表無線遙控器的按鍵A按下
{
if(moshi==0)
{
modle0++;//下一個(gè)靜態(tài)畫面
if(modle0>9)
modle0=0;
}
if(moshi==1)
{
modle1++;//下一個(gè)動(dòng)態(tài)畫面
if(modle1>2)
modle1=0;
}
beep(); //提示音
}
if (i==0x01)//如果是0x01,則代表無線遙控器的按鍵B按下
{
if(moshi==0)
{
modle0--;//上一個(gè)靜態(tài)畫面
if(modle0<0)
modle0=9;
}
if(moshi==1)
{
modle1--;//上一個(gè)動(dòng)態(tài)畫面
if(modle1<0)
modle1=2;
}
beep(); //提示音
}
if (i==0x08)//如果是0x08,則代表無線遙控器的按鍵C按下
{
moshi=~moshi;
beep(); //提示音
}
if (i==0x02)//如果是0x02,則代表無線遙控器的按鍵D按下
{
enable=~enable;
beep();
}
}
/*******************
靜態(tài)畫面顯示函數(shù)
*******************/
void display(uchar n)
{ uint i;//0-255形成整個(gè)圓
uchar a=8;//發(fā)送循環(huán)次數(shù)
uchar h1,h2,h3,h4;
for(i=0;i<256;i++)
{
h4=tab[n][i*4+3];
st_cp4=0;
while(a--)//發(fā)送第4個(gè)8位
{ ds4=h4&0x01;
sh_cp4=0;
h4=h4>>1;
sh_cp4=1;
}
a=8;
h3=tab[n][i*4+2];
st_cp3=0;
while(a--)//發(fā)送第3個(gè)8位
{ ds3=h3&0x01;
sh_cp3=0;
h3=h3>>1;
sh_cp3=1;
}
a=8;
h1=tab[n][i*4];
st_cp1=0;
while(a--)//發(fā)送第1個(gè)8位
{ ds1=h1&0x01;
sh_cp1=0;
h1=h1>>1;
sh_cp1=1;
}
a=8;
h2=tab[n][i*4+1];
st_cp2=0;
while(a--)//發(fā)送第2個(gè)8位
{ ds2=h2&0x01;
sh_cp2=0;
h2=h2>>1;
sh_cp2=1;
}
a=8;
st_cp1=1;
st_cp2=1;
st_cp3=1;
st_cp4=1;
delay_us(time1); //每顯示一組產(chǎn)生一個(gè)延時(shí)
}
}
/********************************
動(dòng)態(tài)畫面顯示函數(shù)
*********************************/
/*******自動(dòng)切換畫面*********/
void zidong()
{
if(z0>=20) //每顯示20次切換
{
z0=0;
z1++;
}
if(z1>9)
z1=0;
}
/***********速度顯示函數(shù)*************/
void sudu() //速度越快,亮燈越多
{
uint i;//0-255形成整個(gè)圓
uchar a=8;//發(fā)送循環(huán)次數(shù)
uchar h1,h2,h3,h4;
// l=30-((time/4)-1); //l等于0~31
if(time<=64)
{
if(time<=15)
time=0;
if(time>15&&time<=20)
time=10;
if(time>20&&time<=24)
time=16;
if(time>24&&time<=27)
time=20;
if(time>27&&time<=29)
time=24;
l=32-time/2;
for(i=0;i<256;i++)
{
h4=tabd[l*4+3];
st_cp4=0;
while(a--)//發(fā)送第4個(gè)8位
{ ds4=h4&0x80;
sh_cp4=0;
h4=h4<<1;
sh_cp4=1;
}
a=8;
h3=tabd[l*4+2];
st_cp3=0;
while(a--)//發(fā)送第3個(gè)8位
{ ds3=h3&0x80;
sh_cp3=0;
h3=h3<<1;
sh_cp3=1;
}
a=8;
h1=tabd[l*4];
st_cp1=0;
while(a--)//發(fā)送第1個(gè)8位
{ ds1=h1&0x80;
sh_cp1=0;
h1=h1<<1;
sh_cp1=1;
}
a=8;
h2=tabd[l*4+1];
st_cp2=0;
while(a--)//發(fā)送第2個(gè)8位
{ ds2=h2&0x80;
sh_cp2=0;
h2=h2<<1;
sh_cp2=1;
}
a=8;
st_cp1=1;
st_cp2=1;
st_cp3=1;
st_cp4=1;
delay_us(time1+30); //每顯示一組產(chǎn)生一個(gè)延時(shí)
}
}
}
/************開傘燈函數(shù)***************/
void kaisan()
{ uint i;
uchar a=8;//發(fā)送循環(huán)次數(shù)
uchar h1,h2,h3,h4;
if((s-b)>0)
{
for(i=0;i<256;i++)
{
h4=tabd[s*4+3];
st_cp4=0;
while(a--)//發(fā)送第4個(gè)8位
{ ds4=h4&0x80;
sh_cp4=0;
h4=h4<<1;
sh_cp4=1;
}
a=8;
h3=tabd[s*4+2];
st_cp3=0;
while(a--)//發(fā)送第3個(gè)8位
{ ds3=h3&0x80;
sh_cp3=0;
h3=h3<<1;
sh_cp3=1;
}
a=8;
h1=tabd[s*4];
st_cp1=0;
while(a--)//發(fā)送第1個(gè)8位
{ ds1=h1&0x80;
sh_cp1=0;
h1=h1<<1;
sh_cp1=1;
}
a=8;
h2=tabd[s*4+1];
st_cp2=0;
while(a--)//發(fā)送第2個(gè)8位
{ ds2=h2&0x80;
sh_cp2=0;
h2=h2<<1;
sh_cp2=1;
}
a=8;
st_cp1=1;
st_cp2=1;
st_cp3=1;
st_cp4=1;
delay_us(time1+37); //每顯示一組產(chǎn)生一個(gè)延時(shí)
}
}
b=s;
}
/****************************
初始化函數(shù)
*****************************/
void init()
{
uchar a=8;//發(fā)送循環(huán)次數(shù)
uchar h1,h2,h3,h4;
delay_ms(50);
beep();
delay_ms(50); //測試蜂鳴器
led=0;
delay_ms(100);
led=1;
delay_ms(100); //測試led
//測試排燈,亮
oe1=0;
oe2=0;
oe3=0;
oe4=0;
h4=0xFF;
st_cp4=0;
while(a--)//發(fā)送第4個(gè)8位
{ ds4=h4&0x80;
sh_cp4=0;
h4=h4<<1;
sh_cp4=1;
}
a=8;
h3=0xFF;
st_cp3=0;
while(a--)//發(fā)送第3個(gè)8位
{ ds3=h3&0x80;
sh_cp3=0;
h3=h3<<1;
sh_cp3=1;
}
a=8;
h1=0xFF;
st_cp1=0;
while(a--)//發(fā)送第1個(gè)8位
{ ds1=h1&0x80;
sh_cp1=0;
h1=h1<<1;
sh_cp1=1;
}
a=8;
h2=0xFF;
st_cp2=0;
while(a--)//發(fā)送第2個(gè)8位
{ ds2=h2&0x80;
sh_cp2=0;
h2=h2<<1;
sh_cp2=1;
}
a=8;
st_cp1=1;
st_cp2=1;
st_cp3=1;
st_cp4=1;
delay_ms(100);
//測試排燈,滅
oe1=0;
oe2=0;
oe3=0;
oe4=0;
h4=0x00;
st_cp4=0;
while(a--)//發(fā)送第4個(gè)8位
{ ds4=h4&0x80;
sh_cp4=0;
h4=h4<<1;
sh_cp4=1;
}
a=8;
h3=0x00;
st_cp3=0;
while(a--)//發(fā)送第3個(gè)8位
{ ds3=h3&0x80;
sh_cp3=0;
h3=h3<<1;
sh_cp3=1;
}
a=8;
h1=0x00;
st_cp1=0;
while(a--)//發(fā)送第1個(gè)8位
{ ds1=h1&0x80;
sh_cp1=0;
h1=h1<<1;
sh_cp1=1;
}
a=8;
h2=0x00;
st_cp2=0;
while(a--)//發(fā)送第2個(gè)8位
{ ds2=h2&0x80;
sh_cp2=0;
h2=h2<<1;
sh_cp2=1;
}
a=8;
st_cp1=1;
st_cp2=1;
st_cp3=1;
st_cp4=1;
delay_ms(50);
}
/*****************************
主函數(shù)
*****************************/
void main()
{
IP=0x05;//設(shè)定兩個(gè)外部中斷為你高優(yōu)先級(jí)
TMOD=0x01; //定時(shí)器T0工作在方式1
ET0=1; //允許定時(shí)器T0中斷
TH0=(65536-10000)/256; //定時(shí)器T0高八位賦初值 10ms
TL0=(65536-10000)%256; //定時(shí)器T0低八位賦初
IT0=1;//P3.2下降沿觸發(fā)
EX0=1;//開外部中斷0
IT1=1;//P3.3下降沿觸發(fā)
EX1=1;//外部1
EA=1;//開總中斷
modle0=0;
modle1=0;
t=0;
time=0;
man=1;//上電時(shí)為慢狀態(tài)
enable=1;//上電使能
moshi=1;//
s=0;
b=0;
fmq=1;//等于1的時(shí)候關(guān)蜂鳴器
led=1;//等于1關(guān)閉led
init();//初始化
while(1)
{
if(enable==1)//使能有效
{
/*********模式0*************/
if(moshi==0)//模式0下顯示靜態(tài)畫面
{
if(time>=10&&time<=70&&t<=70)
{ //判斷速度如果小于10,則程序反應(yīng)不過來
if(man==1)
{
man=0;
beep();
}
}
if(time>70||t>70)
{
if(man==0)
{
man=1;
beep();
}
}
if(man==0)
{
led=1;
oe1=0;
oe2=0;
oe3=0;
oe4=0;
display(modle0);//速度正常則根據(jù)modle顯示靜態(tài)畫面
}
if(man==1)
{
oe1=1;
oe2=1;
oe3=1;
oe4=1;
shan();//當(dāng)速度太慢,關(guān)閉595,開LED閃爍
}
}
/*******模式1*************/
if(moshi==1)//模式1下顯示動(dòng)態(tài)畫面
{
/*判斷速度 如果小于10,則程序反應(yīng)不過來*/
/*這個(gè)t小于等于70,可以避免突然剎車的時(shí)候,蜂鳴器響不停*/
if(time>=10&&time<=70&&t<=70)
{
if(man==1)
{
man=0;
beep();
}
}
if(time>70||t>70||t==0)
{
oe1=1;
oe2=1;
oe3=1;
oe4=1;
shan1();//當(dāng)速度太慢,關(guān)閉595,開LED閃爍1
if(man==0)
{
man=1;
beep();
}
}
if(modle1==0&&man==0)
{
led=1;
oe1=0;
oe2=0;
oe3=0;
oe4=0;
zidong();//自動(dòng)切換畫面
display(z1);
}
if(modle1==1)
{
led=1;
oe1=0;
oe2=0;
oe3=0;
oe4=0;
kaisan();//開傘效果
}
if(modle1==2&&man==0)
{
led=1;
oe1=0;
oe2=0;
oe3=0;
oe4=0;
sudu();//速度越快,亮燈越多
}
}
}
if(enable==0)
{
oe1=1;
oe2=1;
oe3=1;
oe4=1;
huxi();//使能無效,關(guān)595,開LED呼吸
}
}
}
/*********************************
外部中斷O
*********************************/
void intersvr0() interrupt 0
{
huan();//畫面切換
TR0=0;//每切換畫面都從新開始運(yùn)行
t=0;
time=0;
}
/**********************************
外部中斷1
**********************************/
void intersvr1() interrupt 2
{
TR0=1;//開啟定時(shí)器T0中斷
time=t;
if(t>=10)
time1=(t*1000-9500)/256;
/*轉(zhuǎn)換成10us,減掉程序執(zhí)行的95ms 再265等份*/
/*因?yàn)閡s延時(shí)函數(shù)最小單位是10us,所以轉(zhuǎn)換成10us為單位*/
t=1;
s=s+y;
if(s>=31||s==0)
{
y=y*(-1);
}
if(moshi==1&&modle1==0)
z0++;
}
/*********************************
定時(shí)器T0的中斷
**********************************/
void T0int() interrupt 1
{
t++;
if(t>127)//1.28s每圈,25寸輪子周長2.14m,速度是每小時(shí)6公里
t=127;
TH0=(65536-20000)/256;//定時(shí)器T0高八位賦初值 10ms
TL0=(65536-20000)%256;//定時(shí)器T0低八位賦初
}