新闻  |   论坛  |   博客  |   在线研讨会
转:键盘扫描+8种LED亮灭模式控制(基于ATmega16)
tvb2058 | 2009-01-04 10:37:46    阅读:2400   发布文章

实现用键盘对应KEY键选择8种LED亮灭模式。
当前存在的问题:当前模式运行时切换其他模式时必须先复位,否则不能实现切换,希望朋友们帮忙提出解决办法,以实现模式切换不需复位,随时可以切换。

/*******************************************************************************
Platform : AVR mega16学习板(
www.iccavr.com
Project  : 实验四:按键扫描+8种LED亮灭模式控制
Clock F  : 3.6864M
Software : ICCAVR7.14C
Author   : 林夕依然
Version  : 08.11.22
comments :
1、以学习板八个LED灯和八个按键为硬件电路,JP7短路块需装上
2、AVR单片机端口寄存器的使用及理解
3、练习程序模块化,结构化的书写
4、端口电平检测程序的编写方法
5、8种LED点亮模式由对应的KEY键选择
Problem :
1、当前模式运行时切换其他模式时必须先复位,否则不能实现切换,考虑自动切换实现方法)
*******************************************************************************/

/*---------------------------------------------------------------------------------
     延时程序计算方法
     计数个数j = 延时时间/6*晶振频率 - 1
---------------------------------------------------------------------------------*/

#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
 
 
void DelayMs(uint i)                //1ms延时,准确性较Delay();高
   {
    while(i--)
    {                         
     uint j;               
        for(j=1;j<=613;j++)  
      ;              
    }                      
   }
  
void LED_on()                            //打开所有LED
    {
 PORTB =0X00;
 DelayMs(100);
 } 
 
void LED_off()                           //关闭所有LED
    {
 PORTB = 0xFF;
 DelayMs(100); 
 }

void LED_01(int i)                  //LED亮灭控制
    {
    PORTB = ~BIT(i);                //输出低电平
    DelayMs(100);                   //调用延时程序
    }
 
void LED_02(int i)                  //间隔点亮
    {
 PORTB=~(BIT(i)|BIT(i-2));
 DelayMs(100);
 }
 
void LED_03(int i)                 //相临点亮
    {
 PORTB=~(BIT(i)|BIT(i-1));      //~后内容需用括号括起来
 DelayMs(100);
 }
 
void LED_04(int i)                 //发散聚集点亮
    {
 switch(i)
  {
  case 0:PORTB=0xE7;DelayMs(100);break;    //延时100ms
  case 1:PORTB=0xDB;DelayMs(100);break;
  case 2:PORTB=0xBD;DelayMs(100);break;
  case 3:PORTB=0x7E;DelayMs(100);break;
  default:break;
  }
 }
 
void LED_05(int i)                 //00,0F,F0,FF方式显示
    {
 switch(i)
  {
  case 0:PORTB=0x00;DelayMs(100);break;    //延时100ms
  case 1:PORTB=0x0F;DelayMs(100);break;
  case 2:PORTB=0xF0;DelayMs(100);break;
  case 3:PORTB=0xFF;DelayMs(100);break;
  default:break;
  }
 }
 
void LED_06(int i)
   {
   switch(i)
    {
 case 0:PORTB=0XAA;DelayMs(100);break;
 case 1:PORTB=0X55;DelayMs(100);break;
 }
   }

void main()
    {
    int l,m,n,o,p,q,r,s,i,j;
 DDRA =0X00;                         //端口上拉输入
 PORTA=0XFF;
    DDRB =0xFF;                         //端口输出
    PORTB="0xFF";                         //输出高电平,LED熄灭
 DDRC =0X00;
 PORTC=0XFF;
 DDRD =0X00;
 PORTD=0XFF;

    while (1)
     {
    if((PINA&(1<<PA0))==0)          //模式1:顺序点亮
          {
      PORTB="0XFF";
      while(1)
      {
     for (i = 0; i < 8; i++)     //顺序单个点亮LED
              LED_01(i);
              for (i = 6; i > 0; i--)     //逆序单个点亮LED
              LED_01(i);
   }
   
    }
     
    if((PINA&(1<<PA1))==0)         //模式2:顺序单个间隔点亮
    {
      PORTB="0XFF";
      while(1)        
      {
             for (i = 0; i < 8; i += 2)  //顺序间隔点亮LED
             LED_01(i);
             for (i = 7; i > 0; i -= 2)  //逆序间隔点亮LED
             LED_01(i);
      }
    }
     
    if((PINA&(1<<PA2))==0)         //模式3:间隔点亮
    {
      PORTB="0XFF";
      while(1)
       {
     for (i = 2; i < 8; i++)     //间隔顺序同时点亮
     LED_02(i);
     for (i = 6; i > 2; i--)  //间隔逆序同时点亮
     LED_02(i);
       }
    }
   
    if((PINA&(1<<PA3))==0)         //模式4:相临点亮
    {
      PORTB="0XFF";
      while(1)
    {
     for (i = 1; i < 8; i++)     //相临顺序同时点亮
     LED_03(i);
     for (i = 6; i > 1; i--)  //相临逆序同时点亮
     LED_03(i);
       }
    }  

    if((PINA&(1<<PA4))==0)         //模式5:发散聚集点亮
    {
      PORTB="0XFF";
      while(1)
       {
     for(i=0;i<4;i++)            //发散点亮
     LED_04(i);
        for(i=2;i>0;i--)            //聚集点亮
     LED_04(i);    
       }
    }

    if((PINA&(1<<PA5))==0)         //模式6:四四点亮
    {
      PORTB="0XFF";
      while(1)
       {
     for(i=0;i<4;i++)            //四四顺序点亮
     LED_05(i);
        for(i=2;i>0;i--)            //四四逆序点亮
     LED_05(i);    
       }
    }
   
    if((PINA&(1<<PA6))==0)         //模式7:四四点亮
    {
      PORTB="0XFF";
      while(1)
       {
     for(i=0;i<2;i++)            //四四顺序点亮
     LED_06(i);   
       }
    }
   
    if((PINA&(1<<PA7))==0)         //模式8:全部点亮熄灭
    {
      PORTB="0XFF";
      while(1)
      {
    LED_on();
    LED_off();
   }
    }
     }
  //MCUCR=0x40;          //空闲模式,CPU占用100%
  //MCUCR=0x50;          //ADC噪声抑制模式,CPU占用100%
  //MCUCR=0x60;          //掉电模式,CPU占用80%
  //MCUCR=0x70;          //省电模式,CPU占用4%
  //MCUCR=0xE0;          //Standby模式,CPU占用80%
  MCUCR=0xF0;            //扩展Standby模式,CPU占用4%
  asm("sleep");          //CPU休眠指令
    }

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客