原创 led电子沙漏 avr

2010-10-9 23:26 2128 5 5 分类: MCU/ 嵌入式

/说明:本程序使用cvavr编程平台,其中大量英文注释是它本身的框架,是使用编程向导后自动产生的。


/*****************************************************


This program was produced by the


CodeWizardAVR V1.25.6 Evaluation


Automatic Program Generator


?Copyright 1998-2007 Pavel Haiduc, HP InfoTech s.r.l.


http://www.hpinfotech.com


 


Project :


Version :


Date    : 2008-7-16


Author  : Freeware, for evaluation and non-commercial use only


Company :


Comments:


 


 


Chip type           : ATtiny2313V


Clock frequency     : 0.500000 MHz


Memory model        : Tiny


External SRAM size  : 0


Data Stack size     : 32


*****************************************************/


 


#include <tiny2313.h>


#include <delay.h> // Timer 0 output compare A interrupt service routine 


 


interrupt [TIM0_COMPA] void timer0_compa_isr(void);


 


 


// Declare your global variables here


unsigned char val;                 //


static  unsigned char setval=0;    //设定值


static unsigned char m_count=0;    //分计数


static unsigned char m_count_dsp=0; //分计数显示


static unsigned char ms_4=0;       //4毫秒计数4*250=1s


unsigned char beepmax=6;           //鸣叫起停次数


static unsigned char blink=0;      //计时中闪光标志


static unsigned char move=0;       //动感状态标志,0…4


unsigned char beepcount=0;         //鸣叫计数


unsigned char beepmark=0;          //鸣叫标志


static unsigned char s_count=0;     //秒计数


static unsigned char dspstate=0;   //


 


flash char ldsp[11]={0,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff,0xff,0xff};//下显示表


flash char udsp[11]={0,0,0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff};      //上显示表


 


interrupt [TIM0_COMPA] void timer0_compa_isr(void)  //比较中断处理


{


// Place your code here


#asm("cli")     //关中断


 


  ms_4++;       //4毫秒增加1


 


  if (ms_4>249) //中断250次为1秒4*250=1s 


     {


        ms_4=0;              //到1秒,4毫秒计数归0


        s_count++;           //秒计数加1


        m_count_dsp= m_count;//分计数显示等于分计数


        blink=~blink;        //改变闪灯状态控制VD20闪光


        move++;


        if (move>3)          //4种动态切换


            move=0;


        if (s_count>59)   //如果到达1分钟


           {


             s_count=0;   //秒计数归0


             m_count++;   //分计数加1


            


               if (m_count==setval) //如果达到设定值


           {


              m_count=0;      //分计数归0


                      PORTD.4=1;    //启动鸣叫


              beepmark=1;     //鸣叫标志


              m_count_dsp=setval;//分显示等于设定值,不和分计数图时归0


           }


                            


            }


         


         if (beepmark)           //如果鸣叫


            {


         if(beepcount<beepmax)//未达到鸣叫次数


               {


                 beepcount++;    //鸣叫计数加1


              PORTD.4=~PORTD.4;//鸣叫状态改变


           }


         else


           {


            beepmark=0;  //已经达到鸣叫次数清除鸣叫标志


            beepcount=0; //鸣叫计数归0


                PORTD.4=0;  //停叫


               


           }


             }


 


       


     }


    


     switch (dspstate)  //////////////DISPLAY显示状态切换


     {


     case 0:              //倒立状态计时下组LED显示VD1..VD10


        if(m_count_dsp<9) //9以下,9,10,LED9,LED10的发光要求


      {


      PORTD.6=0;


      PORTD.5=0;


      }


    else if(m_count_dsp==9)//


      {


      PORTD.6=1;


      PORTD.5=0;


      }


    else if (m_count_dsp==10)//


      {


      PORTD.5=1;


      PORTD.6=1;


      }


       


        PORTB=ldsp[m_count_dsp]; //LED1-LED8由查表决定和数值对应的显示


        PORTD.2=1;               //开倒立下组LED,关上组


     PORTD.3=0;


    dspstate++;               //下次转换入下一显示状态


        break;


        


     case 1:                     //动感显示,模拟沙子下落


       switch (move)


       {


        case 0:


        PORTB=0;


        PORTD.5=1;               //VD10 亮


        PORTD.2=1;               //倒立下组亮上组灭


     PORTD.3=0;


     break;


     case 1:


     PORTD.5=0;


     PORTB=0;


     PORTB.7=1;               //VD8 亮


     PORTD.2=1;               //


     PORTD.3=0;


     break;


     case 2:


     PORTB=0;


     PORTB.5=1;               //VD6 亮


     PORTD.2=1;


     PORTD.3=0;


     break;                   //


     case 3:


     PORTB=0;


     PORTB.1=1;               //VD2 亮


     PORTD.2=1;


     PORTD.3=0;


     break;


     PORTD.3=0;


     break;


        }                    //


        dspstate++;


        break;


                                 


     case 2:                      //倒立计时上组LED VD11..VD20显示状态


       


        val=(setval-m_count_dsp); //显示设定之减去分计数显示值


   PORTB=udsp[val];          //查上显示表


   if(val>=2)                //VD11 VD12的显示方法


      {


      PORTD.6=1;


      PORTD.5=1;


      }


    else if(val==1)            //


      {


      PORTD.6=0;


      PORTD.5=1;


      }


    else                       //


      {


      PORTD.5=0;


      PORTD.6=0;


      }


    PORTD.5&=blink;            //VD20闪光


    PORTD.3=1;                 //开上组LED关下组LED,下次转入下一状态


    PORTD.2=0;


        dspstate++;


        break;


     


     case 3:                        //全灭,下次转入下组显示状态


        PORTD&=0XF3;


        dspstate=0;


        break;


      


      


     }


     #asm("sei");                   //开中断


}


 


 


void check(void)                    //开机自检


{


 char i;


 PORTD.2=1;       //LED1..8 开放


 PORTB=0X01;      //LED1亮


 delay_ms(10);    //延时后


 for( i=0;i<7;i++) //各个LED依次点亮


 {


  PORTB<<=1;


  delay_ms(10);


 }


 PORTB=0;


 PORTD.6=1;    //LED9 亮


 delay_ms(10);


 PORTD.6=0;    //LED9 灭


 PORTD.5=1;    //LED10亮


 delay_ms(10);


 PORTD.5=0;    //LED10 灭


////////////////////10 LEDS LIGHT IN ORDER


 PORTD.2=0;    //LED1..10关


 PORTD.3=1;    //LED11..20开允许


 PORTB=0X01;   //LED11..20顺次亮延时灭


 delay_ms(10);


 for (i=0;i<7;i++)


 {


  PORTB<<=1;


  delay_ms(10);


 


 }


 PORTB=0;


 PORTD.6=1;


 delay_ms(10);


 PORTD.6=0;


 PORTD.5=1;


 delay_ms(10);


 PORTD.5=0;


//////////////////////OTHER LEDS LIGHT


 PORTD.3=0;  //LED11..20全灭


}


void setting(void)  //设定


{  


    TCCR0B=0;       //停止定时器T/C0


    setval++;       //设定值加1


    if (setval>10)  //设定值大于10则归1


       {


       setval=1;


       PORTD.6=0;   //VD19 VD20 灭


       PORTD.5=0;


       }


    else


       {


      


        if(setval<9)  //设定值小于9 VD19 VD20 灭


      {


       PORTD.6=0;


       PORTD.5=0;


      }


      


     else if(setval==9)  //设定值等于9 VD19 亮


      {


      PORTD.6=1;


      PORTD.5=0;


      }


     else if (setval==10)  //设定值等于10 VD19 VD20 亮


      {


       PORTD.5=1;


       PORTD.6=1;


      }


    }


                


     PORTB=ldsp[setval];      //其余LED查表


     PORTD.2=0;


     PORTD.3=1;          //VD11..VD20允许           


      


}


void main(void)          //主程序前部初始化代码自动生成


{


// Declare your local variables here


 


// Crystal Oscillator division factor: 1


#pragma optsize-


CLKPR=0x80;


CLKPR=0x03;  //晶振/8,CPU 500khz


#ifdef _OPTIMIZE_SIZE_


#pragma optsize+


#endif


 


// Input/Output Ports initialization //PORTA设置输入无上拉


// Port A initialization


// Func2=In Func1=In Func0=In


// State2=T State1=T State0=T


PORTA=0x00;


DDRA=0x00;


 


// Port B initialization //PORTB设置输出全0


// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out


// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0


PORTB=0x00;


DDRB=0xFF;


 


// Port D initialization//PORTD设置PD0 PD1上拉输入其余输出


// Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=In Func0=In


// State6=0 State5=0 State4=0 State3=0 State2=0 State1=P State0=P


PORTD=0x03;


DDRD=0x7C;


 


// Timer/Counter 0 initialization//T/C0设置CTC模式


// Clock source: System Clock


// Clock value: Timer 0 Stopped


// Mode: CTC top=OCR0A


// OC0A output: Disconnected


// OC0B output: Disconnected


TCCR0A=0x02; //CTC模式与OCR0A比较


TCCR0B=0x00; //T/C0停止


TCNT0=0x00;


OCR0A=0xF9;  //预置值,理想为250


OCR0B=0x00;


 


// Timer/Counter 1 initialization//C/T1未用


// Clock source: System Clock


// Clock value: Timer 1 Stopped


// Mode: Normal top=FFFFh


// OC1A output: Discon.


// OC1B output: Discon.


// Noise Canceler: Off


// Input Capture on Falling Edge


// Timer 1 Overflow Interrupt: Off


// Input Capture Interrupt: Off


// Compare A Match Interrupt: Off


// Compare B Match Interrupt: Off


TCCR1A=0x00;


TCCR1B=0x00;


TCNT1H=0x00;


TCNT1L=0x00;


ICR1H=0x00;


ICR1L=0x00;


OCR1AH=0x00;


OCR1AL=0x00;


OCR1BH=0x00;


OCR1BL=0x00;


 


// External Interrupt(s) initialization


// INT0: Off


// INT1: Off


// Interrupt on any change on pins PCINT0-7: Off


GIMSK=0x00;


MCUCR=0x00;


 


// Timer(s)/Counter(s) Interrupt(s) initialization


TIMSK=0x01; //定时器T/C0 OCR0A比较中断允许


// Universal Serial Interface initialization//串口未用


// Mode: Disabled


// Clock source: Register & Counter=no clk.


// USI Counter Overflow Interrupt: Off


USICR=0x00;


 


// Analog Comparator initialization//比较未用


// Analog Comparator: Off


// Analog Comparator Input Capture by Timer/Counter 1: Off


ACSR=0x80;


 


// Global enable interrupts


#asm("cli") //////全局中断禁止


 // Place your code here //以下主程序


check();                     //自检


while (1)                    //主循环


      {


       if (PIND.0)           //正立状态


        


            {


              while(PIND.1)   //无设置键,VD20闪光提示


              {


              PORTD.5=1;


              PORTD.3=1;


              delay_ms(100);


              PORTD.5=0;


              PORTD.3=0;


              delay_ms(100);


              };


                   


              while(1)           //有键循环


    


               {


                PORTD.2=0;         // 禁止VD1..VD10亮


           


               if (!(PIND.1))    //如果有键


             {


                  delay_ms(20);  //延时再检查


                  if(!(PIND.1))  //继续有键


                    {


                     while(!(PIND.1)) //等待释放


                     {;}


                   PORTD.2=0;


             PORTD.3=0;


             PORTD.4=1;    //BZ发声 100ms


                     delay_ms(100);


                     PORTD.4=0;


             delay_ms(100); //延时后改变设定值


                     setting();


                     delay_ms(20);


                    }


             }


             if(!PIND.0)        //查询是否倒立


             {


              delay_ms(20);     //延时再判


              if (!PIND.0)      //确认倒立


               {


                m_count=0;      //各个计数值初始化


                    ms_4=0;


                    s_count=0;


                    #asm("sei")   //////开全局中断


                    TCCR0B=2;     //启动 T/C0:1/8:16us计数时钟


                break;         //跳出设定循环进入主循环


               }


             }


          }     


          


         }


        /////////////倒立状态///////////////////


      else      


       {


        delay_ms(20);


        if (!PIND.0)              //确认倒立


         {


       while(1)                //进入计时循环


           {


        if(!PIND.1)            //如果按设定键才可退出计时循环


        break;


       }


          }


    }


      };


// Place your code here      


}

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
5
关闭 站长推荐上一条 /3 下一条