专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

基于51单片机的无线遥控自行车风火轮程序

作者:佚名   来源:本站原创   点击数:  更新时间:2013年08月11日   【字体:

硬件制作资料从http://www.51hei.com/bbs/dpj-19358-1.html 下载
//课题:无线遥控自行车风火轮
//程序编写:潘观学
//单片机:STC89C54RD
//晶振:12MHZ
//单片机时钟模式:6T
#include<stc89.h>
#include "fenghuolun.h"    //定义在这里
/*********************************
              延时函数
***********************************/
void delay_ms(unsigned int i)//1ms基准延时
{ unsigned char j;
 while(i--)
 { for(j=0;j<246;j++)
  { ;   
  }
 }
}   
void delay_us(unsigned int n) //10us延时
{ uchar i;
 uchar j;
 for(i=0;i<n;i++) //延时程序
  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);                                      
}
/******************************
  闪烁函数
*****************************/
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); 
}
/**********************************
  蜂鸣器函数
************************************/
void beep() 
{
  fmq=0;
 delay_ms(100);
 fmq=1;
}   
/*******************************
        画面切换函数
********************************/
void huan()
{ uchar i;
 P1=0xff;//P1口设置为输入状态 先全部写1
 i=P1;//赋值给临时存贮变量

 i=i&0x0f;//和0x0f相与 屏蔽高四位,读取无线遥控码

 if (i==0x04)//如果是0x04,则代表无线遥控器的按键A按下
 {  
  if(moshi==0)
  {
   modle0++;//下一个静态画面  
   if(modle0>9)
    modle0=0;
   }
  if(moshi==1)
  {
   modle1++;//下一个动态画面
   if(modle1>2)
    modle1=0;
  }
  beep(); //提示音
 }
 if (i==0x01)//如果是0x01,则代表无线遥控器的按键B按下
 {  
  if(moshi==0)
  {
   modle0--;//上一个静态画面  
   if(modle0<0)
    modle0=9;
   }   
  if(moshi==1)
  {
   modle1--;//上一个动态画面
   if(modle1<0)
    modle1=2;
  }
  beep(); //提示音
 }
 if (i==0x08)//如果是0x08,则代表无线遥控器的按键C按下
 {      
  moshi=~moshi;
  beep(); //提示音
 }
 if (i==0x02)//如果是0x02,则代表无线遥控器的按键D按下
 {  
  enable=~enable;
  beep();
 }
}

/*******************
静态画面显示函数
*******************/
void display(uchar n)
{ uint i;//0-255形成整个圆
 uchar a=8;//发送循环次数
 uchar h1,h2,h3,h4;

 for(i=0;i<256;i++)
 { 
  h4=tab[n][i*4+3];
  st_cp4=0;
     while(a--)//发送第4个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--)//发送第3个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--)//发送第1个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--)//发送第2个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);  //每显示一组产生一个延时
 } 
}

/********************************
 动态画面显示函数
*********************************/
/*******自动切换画面*********/
void zidong()   
{
 if(z0>=20)    //每显示20次切换
 { 
  z0=0;
  z1++;
 }
 if(z1>9)
  z1=0;
}
/***********速度显示函数*************/
void sudu()   //速度越快,亮灯越多

 uint i;//0-255形成整个圆
 uchar a=8;//发送循环次数
 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--)//发送第4个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--)//发送第3个8位
       { ds3=h3&0x80;
           sh_cp3=0;
           h3=h3<<1;
           sh_cp3=1;               
       }
       a=8;
    
    
    h1=tabd[l*4];
    st_cp1=0;
       while(a--)//发送第1个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--)//发送第2个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);  //每显示一组产生一个延时
  }
 }   
}
/************开伞灯函数***************/
void kaisan()
{ uint i;
 uchar a=8;//发送循环次数
 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--)//发送第4个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--)//发送第3个8位
      { ds3=h3&0x80;
          sh_cp3=0;
          h3=h3<<1;
          sh_cp3=1;               
      }
      a=8;   
   
   h1=tabd[s*4];
   st_cp1=0;
      while(a--)//发送第1个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--)//发送第2个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);  //每显示一组产生一个延时
  }
 }

 b=s;    
}

/****************************
  初始化函数
*****************************/
void init()
{
 uchar a=8;//发送循环次数
 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--)//发送第4个8位
     { ds4=h4&0x80;
         sh_cp4=0;
         h4=h4<<1;
         sh_cp4=1;               
     }
     a=8;
  
  h3=0xFF;
  st_cp3=0;
     while(a--)//发送第3个8位
     { ds3=h3&0x80;
         sh_cp3=0;
         h3=h3<<1;
         sh_cp3=1;               
     }
     a=8;
    
  h1=0xFF;
  st_cp1=0;
     while(a--)//发送第1个8位
     { ds1=h1&0x80;
         sh_cp1=0;
         h1=h1<<1;
         sh_cp1=1;               
     }
     a=8;
    
  h2=0xFF;        
     st_cp2=0;
     while(a--)//发送第2个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--)//发送第4个8位
     { ds4=h4&0x80;
         sh_cp4=0;
         h4=h4<<1;
         sh_cp4=1;               
     }
     a=8;
  
  h3=0x00;
  st_cp3=0;
     while(a--)//发送第3个8位
     { ds3=h3&0x80;
         sh_cp3=0;
         h3=h3<<1;
         sh_cp3=1;               
     }
     a=8;
  
  
  h1=0x00;
  st_cp1=0;
     while(a--)//发送第1个8位
     { ds1=h1&0x80;
         sh_cp1=0;
         h1=h1<<1;
         sh_cp1=1;               
     }
     a=8;
    
  h2=0x00;        
     st_cp2=0;
     while(a--)//发送第2个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);
}

/*****************************
            主函数
*****************************/
void main()   

 IP=0x05;//设定两个外部中断为你高优先级
 TMOD=0x01; //定时器T0工作在方式1
 ET0=1;    //允许定时器T0中断
 TH0=(65536-10000)/256;  //定时器T0高八位赋初值   10ms
 TL0=(65536-10000)%256;  //定时器T0低八位赋初

 IT0=1;//P3.2下降沿触发
  EX0=1;//开外部中断0

 IT1=1;//P3.3下降沿触发
 EX1=1;//外部1

  EA=1;//开总中断

 modle0=0;
 modle1=0;

 t=0;
 time=0;
 man=1;//上电时为慢状态

 enable=1;//上电使能
 moshi=1;//

 s=0;
 b=0;

 fmq=1;//等于1的时候关蜂鸣器
 led=1;//等于1关闭led

 init();//初始化

 while(1)
 { 
  if(enable==1)//使能有效
  { 
  /*********模式0*************/
   if(moshi==0)//模式0下显示静态画面
   { 
     if(time>=10&&time<=70&&t<=70)
    {  //判断速度如果小于10,则程序反应不过来
     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);//速度正常则根据modle显示静态画面     
    }   
    if(man==1)  
    { 
     oe1=1;
     oe2=1;
     oe3=1;
     oe4=1;
     shan();//当速度太慢,关闭595,开LED闪烁
    }
   }
   /*******模式1*************/
   if(moshi==1)//模式1下显示动态画面
   {
    /*判断速度 如果小于10,则程序反应不过来*/
    /*这个t小于等于70,可以避免突然刹车的时候,蜂鸣器响不停*/
    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();//当速度太慢,关闭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();//自动切换画面   
     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();//使能无效,关595,开LED呼吸
  }     
 }      
}

/*********************************
          外部中断O
*********************************/
void intersvr0() interrupt 0
{
 huan();//画面切换
 TR0=0;//每切换画面都从新开始运行
 t=0;
 time=0;  
}

/**********************************
  外部中断1
**********************************/
void intersvr1() interrupt 2

 TR0=1;//开启定时器T0中断
 time=t;
 if(t>=10)   
  time1=(t*1000-9500)/256;
  /*转换成10us,减掉程序执行的95ms 再265等份*/
  /*因为us延时函数最小单位是10us,所以转换成10us为单位*/
 t=1;
 s=s+y;
 if(s>=31||s==0)
 {
  y=y*(-1);
  }
 if(moshi==1&&modle1==0)
  z0++;   
}

/*********************************
         定时器T0的中断
**********************************/
void T0int() interrupt 1

 t++;       
 if(t>127)//1.28s每圈,25寸轮子周长2.14m,速度是每小时6公里
  t=127;
 TH0=(65536-20000)/256;//定时器T0高八位赋初值 10ms
 TL0=(65536-20000)%256;//定时器T0低八位赋初
}
 

关闭窗口

相关文章