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

单片机多功能按键处理程序+视频

作者:huqin   来源:本站原创   点击数:  更新时间:2014年04月08日   【字体:

 

源程序:
/*-----------------------------------------------------------------------------
  按键用变量定义
-----------------------------------------------------------------------------*/
volatile unsigned char idata KEY1=0;//多功能按键功能识别器。


volatile  unsigned char idata KEY2=0;//多功能按键功能识别器。
volatile  unsigned char  idata KEYBZ2;
volatile    unsigned char idata KEY3=0;//多功能按键功能识别器。
volatile    unsigned char idata KEYBZ3;
 volatile   unsigned char  idata KEY4=0;//多功能按键功能识别器。

volatile   unsigned char idata KEY5=0;//多功能按键功能识别器。

volatile    unsigned   char idata KEY6=0;//多功能按键功能识别器。
volatile    bit ZT=0;
volatile  bit FWBZ;

 


 /*-----------------------------------------------------------------------------
 三变量用于默认的速度,宽度,高度。
-----------------------------------------------------------------------------*/ 
volatile unsigned char idata b=100;//单位是rpm/min
volatile unsigned char idata BBZ;
volatile unsigned  char  idata c=2; //宽度单位是毫米
volatile unsigned char  idata CBZ;
volatile unsigned char idata d=1;//高度单位是毫米
volatile unsigned char idata DBZ;

 

 
/*-------------------------------------------------------------
P0引脚定义: P0口有5种定义,每种定义根据P2口给定功能不同而不同。
每种功能不能同时实现,否则会出现混乱。

-------------------------------------------------------------*/
  
sbitLED_SD    =P0^0;      //指示灯
sbit    LED_KD      =P0^1;
sbitLED_HD  =P0^2;
sbitLED_YX       =P0^3;
sbitLED_FW       =P0^4;      //按键1--第一路调光
sbit    SM_BW     =P0^5;      //按键2--第一路开关
sbitSM_SW     =P0^6;      //按键3--第二路调光
sbitSM_GW        =P0^7;

 /*-------------------------------------------------------------
P1引脚定义 :P1口为限位检测口。

-------------------------------------------------------------*/
sbit BUZ=P1^0;
sbit ZZMC=P1^1;//主轴冲检测
sbitKEY_1=P1^2; // Z轴限位上 ,当高电平表示有限位
sbitKEY_2=P1^3; // Z轴限位下。当高电平表示有限位
sbitKEY_3=P1^4;      //主轴中点限位。当高电平表示有限位
sbitKEY_4=P1^5;      //角度限位左 。当高电平表示有限位
sbitKEY_5=P1^6;      //角度限位右  。当高电平表示有限位
sbitKEY_6    =P1^7;      //角度电机输入2
 sbitKEY_7    =P2^7;      //角度电机输入2


 


 /* -------------------------------------------------------------
  P3引脚定义:P3口为主轴电机调速端口和
  主轴编码方向编码,还有键盘中断。
-------------------------------------------------------------*/
sbit    CLK          = P3^0; //SPI通讯脉冲
sbitDATAS      =P3^1; //SPI通讯数据
sbit    STB_I        =P3^2 ; //SPI通讯反馈
sbitZZZD     =P3^4; //主轴中点检测
sbitZDATA    =P3^5; //主轴SPI通讯数据口
sbit ZCLK    =P3^6;//主轴SPI通讯脉冲口
sbitZSTB=P3^7; //SPI通讯使能口

 

 /*-----------------------------------------------------------------------------
  LED数显7段编码,调用时只需table[NUM]即可。
-----------------------------------------------------------------------------*/


 unsigned char code table[]=
{
  0x3f,0x06,0x5b,0x4f,0x66,
  0x6d,0x7d,0x07,0x7f,0x6f,
  0x77,0x7c,0x39,0x5e,0x79,
  0x71,0x00,0x40,0x00
};


/*-----------------------------------------------------------------------------
函数功能 : MS 毫秒 延迟函数
-----------------------------------------------------------------------------*/
void Delay(unsigned int i)
{
unsigned int j;
for(i;i>0;i--)
{
for(j=0;j<125;j++)
{;}
}
}


/*-----------------------------------------------------------------------------
函数功能 : us 微秒 延迟函数
-----------------------------------------------------------------------------*/
void MyDelay(unsigned int time)
{
while(time--)
{
_nop_();
}
}

/*-----------------------------------------------------------------------------
函数功能 : us 微秒 精确US延迟 12MHZ延迟6us
-----------------------------------------------------------------------------*/
   void MyDelay2()
{
_nop_();
}

 
/*-----------------------------------------------------------------------------
函数功能 :显示功能显示数码管百位十位个位显示 工作参数
-----------------------------------------------------------------------------*/
  void XSGN(unsigned char a)
      {
       unsigned char  b,c,d;//百位、十位、个位,数显。
        EA=0;//关中断等待全部数据送完    
        b=a/100;//求模运算,取A的百位到百位变量。  
        if(b==0)
          {
            P2=0xff;//百位没有数则没有显示
            SM_BW=1;
          }
        else
           {
            P2=~table[b];//百位有显示则输出参数
            SM_BW=1;
        _nop_();
        _nop_();
  }  
  SM_BW=0; //关闭百位数显
  c=a%100;//取余数运算,取得数为十位和个位。
  d=c; //保存十位和个位数。
  c=c/10; //求模运算 取十位数。   
  if(c==0&&b==0)
 {
  P2=0xff;
  SM_SW=1;
 }
 else
 {
  P2=~table[c];
  SM_SW=1;
_nop_();
_nop_();
  }
 SM_SW=0; 
 d=d%10; //取个位。
 Delay(20); 
if(d==0&&c==0&&b==0)
{
  P2=0xff;
SM_GW=1;
}
 else
  {
  P2=~table[d];
  SM_GW=1;
  _nop_();
_nop_();
  }
 SM_GW=0;
  IE1=0;
 IE0=0;
EA=1;//打开键盘中断
}


   /*-----------------------------------------------------------------------------
函数功能 :运行状态指示LED指示灯,与送入参数。
-----------------------------------------------------------------------------*/
 


 
   /*-----------------------------------------------------------------------------
函数功能 :SPI通讯(输出)16BIT输出,DH的高4位决定输出控制指令还是参数数据。当DH高4位且低4位全0那么输出为控制指令
当高4位全高,由低4位决定送出的数据是对应于哪一块的数据。 具体参数介绍  Control (0,0);系统关闭中。Control (0,1);电源开启中。
Control (0,2);系统复位中Control (0,3);系统运行中。Control (0,4);系统暂停中。 Control (0,5);系统从暂停开始运行。
送入数据示意:Control(  0xf0,b); 送入的参数是速度参数。Control(  0xf1,c); 送入的参数是宽带参数。  Control(  0xf2,d);
送入的数据是厚度参数。


-----------------------------------------------------------------------------*/

 void Control(unsigned char DH,unsigned char DL)
{
unsigned int i,cmd;
EA=0;
 EX0=0;
cmd=DL;
cmd|=DH<<8;
STB_I = 0;//拉低片选
Delay(1);
for(i=0;i<16;i++)

CLK = 0;
 
//这里大约是100us
if(cmd & 0x8000)DATAS = 1;//把datas的参数与16进制数8000进行位与运算把结果给datas(如果有数则DAT=1
else DATAS = 0;//否则DAT=0
MyDelay(50) ;

CLK = 1;
MyDelay(50) ;//这里大约是100us
cmd <<= 1;
}
DATAS = 1;
STB_I = 1;
CLK = 1;
 
 IE1=0;
 IE0=0;

EA=1;

}

 

 

 

/*-----------------------------------------------------------------------------
函数功能 :电源开启下屏闪烁功能

-----------------------------------------------------------------------------*/

 

 

/*-----------------------------------------------------------------------------
函数功能 : 数据集中处理
-----------------------------------------------------------------------------*/
void main(void)

        BBZ=b;     //b数据的判断代码 用于判断速度值的改变
CBZ=c;     //c数据的判断代码
DBZ=d;
KEYBZ2= KEY2;
        SM_BW=0;   //数码管百位
SM_SW=0;   //数码管十位
SM_GW=0;   //数码管个位
BUZ=1;     //蜂鸣器关断           
     EX1=1;     //开启按键响应
   EA=1;      //开启所有设备响应
   IT1=1;     //设定键盘响应为下降沿响应
  
   IT0=1;   //复位识别为下降沿识别
  
  while(1)
  {
  if(KEY1==0){P2=0XFF;P0=0XFF;  Control (0,0); }
while(KEY1==0){;}
if(KEY1==1) {Control(  0,1);}
while(KEY1==1)
         {
SM_BW=1;
SM_SW=1;
SM_GW=1;
P2=0;
LED_SD=0;
LED_KD=0;
LED_HD=0;
LED_YX=0;
LED_FW=0;
BUZ=1;
Delay(500);
P2=0XFF;
LED_SD=1;
LED_KD=1;
LED_HD=1;
LED_YX=1;
LED_FW=1;
BUZ=0;    
Delay(500); 
    }

   if(KEY1==2){P2=0XFF;LED_SD=1;LED_KD=1;LED_HD=1;LED_YX=1;LED_FW=0;BUZ=1; Control(  0,2); IE0=0; EX0=1;   }//复位状态
while(KEY1==2){Delay(200);}
  
if(KEY1==3)
{
 LED_FW=1;LED_YX=0;LED_SD=0;  XSGN(b); 
}
while(KEY1==3)
    {
 if (KEY1==3&&ZT==0){LED_YX=0;  Control(  0,3);}
 while(KEY1==3&&ZT==0)
 {
  if(KEYBZ2!=KEY2)
    {
     if(KEY2==0){ LED_SD=0;LED_KD=1;LED_HD=1;LED_YX=0;LED_FW=1; XSGN(b); }
     if(KEY2==1) {LED_SD=1;LED_KD=0;LED_HD=1;LED_YX=0;LED_FW=1; XSGN(c);}
     if(KEY2==2){ LED_SD=1;LED_KD=1;LED_HD=0;LED_YX=0;LED_FW=1; XSGN(d);}
 KEYBZ2=KEY2;
}
  if(BBZ!=b)
    {
XSGN(b);
Control(  0xf0,b); 
BBZ=b;
}
  if(CBZ!=c)
{
XSGN(c);
Control(  0xf1,c); 
CBZ=c;
}
if(DBZ!=d)
{
XSGN(d);
Control(  0xf2,d); 
DBZ=d;
}
 }
 if(KEY1==3&&ZT==1){Control(  0,4);}                                    //系统暂停中
 while(KEY1==3&&ZT==1)
 {
  if(KEYBZ2!=KEY2)
    {
     if(KEY2==0){ LED_SD=0;LED_KD=1;LED_HD=1;LED_YX=0;LED_FW=1; XSGN(b); }
     if(KEY2==1) {LED_SD=1;LED_KD=0;LED_HD=1;LED_YX=0;LED_FW=1; XSGN(c);}
     if(KEY2==2){ LED_SD=1;LED_KD=1;LED_HD=0;LED_YX=0;LED_FW=1; XSGN(d);}
 KEYBZ2=KEY2;
}
  if(BBZ!=b)
    {
XSGN(b);
Control(  0xf0,b);
BBZ=b;
}
  if(CBZ!=c)
{
XSGN(c);
Control(  0xf1,c);
CBZ=c;
}
if(DBZ!=d)
{
XSGN(d);
Control(  0xf2,d);
DBZ=d;
}

 LED_YX=~LED_YX;Delay(100);
 }   
}
     
  }
 
}
  
 
   /*-----------------------------------------------------------------------------
函数功能 : 复位功能入口
-----------------------------------------------------------------------------*/
   void  KEYYXFW() interrupt 0//复位完成入口。
  
   {         
  
       EX1=1;
  IE1=0;
  
   }
 
 void  Keyan() interrupt 2 


   
       unsigned int idata i, j;
FWBZ=0;
        
  if(KEY_1==0)
    {
IT1=1;
    BUZ=0;
    i=50;
    for(i;i>0;i--)
       {
   for(j=0;j<125;j++)
      {;}
       }
  BUZ=1;
  KEY1++;
   if(KEY1==2){ FWBZ=1;}
  while(KEY1 ==4 ) {KEY1=0;ZT=0;}
  while(KEY_1==0 ) {           ;}
  i=50;
  for  (i;i>0;i--)
       {
   for(j=0;j<125;j++)
      {;}
         }
     }

 if(KEY_2==0&&KEY1==3)
   {
   BUZ=0;
   i=50;
   for(i;i>0;i--)
      {
   for(j=0;j<125;j++)
      {;}
      }
   BUZ=1;
  FWBZ=0;
   KEY2++;
   while(KEY2==3 ){KEY2=0; }
   while(KEY_2==0){       ;}
   i=50;
   for(i;i>0;i--)
    {
for(j=0;j<125;j++)
   {;}
    }
 }

if(KEY_3==0&&KEY1==3)
  {
   BUZ=0;
   i=50;
        for(i;i>0;i--)
      {
  for(j=0;j<125;j++)
     {;}
      }
  BUZ=1;
FWBZ=0;
  if(KEY2==0){b=b+10;while(b>=250)b=100;  } 
  if(KEY2==1){c++;while(c>=6)c=1;         }   
  if(KEY2==2){d++;while(d>=4)d=1;         }
  while(KEY_3==0){;}
  i=50;
  for(i;i>0;i--)
     {
 for(j=0;j<125;j++)
    {;}
     } 
  }
      

if(KEY_4==0&&KEY1==3) 
 {
  BUZ=0;
  i=50;
  for(i;i>0;i--)
      {
   for(j=0;j<125;j++)
      {;}
       }
BUZ=1;
FWBZ=0;
if(KEY2==0){b=b-10;while(b<=100)b=240;  } 
     if(KEY2==1){c--;  while(c<1)c=5;         }   
     if(KEY2==2){d--;  while(d<1)d=3;         }
while(KEY_4==0){;}
     i=50;
for(i;i>0;i--)
   {
    for(j=0;j<125;j++)
        {;}
   }
 }

 

if(KEY_5==0&&(KEY1==2||ZT==1))//当在复位状态和暂停状态下Z周可以调节高。
{
 IT1=0; //z轴连续可调。
 BUZ=0;
 i=50;
 for(i;i>0;i--)
    {
 for(j=0;j<125;j++)  {;}
  
    }
 BUZ=1; 
 FWBZ=0;

}
if(KEY_6==0&&(KEY1==2||ZT==1))//当在复位状态和暂停状态下Z周可以调节低。
 {
IT1=0;
   BUZ=0;
   i=50;
   for(i;i>0;i--)
  {
for(j=0;j<125;j++){;}
  }
  BUZ=1; 
  FWBZ=0;

}

if(KEY_7==0&&KEY1==3)
 {
  IT1=1;
  BUZ=0;
  i=50;
  for(i;i>0;i--)
     {
  for(j=0;j<125;j++)
     {;}
     }
  BUZ=1;
  FWBZ=0;
  ZT=~ZT;
  while(KEY_7==0){;}
  i=50;
  for(i;i>0;i--)
      {
      for(j=0;j<125;j++) {;}
        
       }
  }
    if(KEY1==2&&FWBZ==1){EX1=1;}//当状态是复位状态关闭键盘响应,等待复位完成。
else        {EX1=1;}

 


}

关闭窗口

相关文章