×
单片机 > 单片机程序设计 > 详情

AVR单片机Atmega16电子时钟程序+仿真,内部定时器实现

发布时间:2020-08-26 发布时间:
|

Atmega16电子时钟,内部定时器,有可调闹钟。

仿真原理图如下
 

单片机源程序如下:

#include

#include

#define  key_bz    0b00000111

char smg_zx[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d, 0x7d,0x07,0x7f,0x6f};// 全局变量

  

char hour=12;

char min;

char sec;

char nz_hour=12;

char nz_min=1; 

char mode=0;

char set;


void delay_ms(unsigned int k)                        

{

    unsigned int i,j;

    for(i=0;i

    {

      for(j=0;j<570;j++);

    }

}

// 用定时器实现定时

void T0_init(void)// 端口初始化函数

{

TIFR=0XFF;

TCCR0=0X0B; //64FENPIN, CTC MODE

TCNT0=0;

OCR0=250;

TIMSK=0X02;


}


void port_init(void)// 端口初始化函数

{

  DDRC  |= 0b11110000;  // PC4 5 OUT PUT

  PORTC |= 0b00111111; //m103 output only


PORTD = 0x00; //  上电关闭数码管, 因为上电电压不稳

DDRD  = 0xff;

DDRB  |= 0b11100000;  // PC5 6 7OUT PUT

}


//call this routine to initialize all peripherals

void init_devices(void)

{

//stop errant interrupts until set up

CLI(); //disable all interrupts

port_init();//smg_zx[0]=1;

  T0_init();

SEI(); //re-enable interrupts

//all peripherals are now initialized

}

//miao=45;


void key (void)

{


if(!(PINC&0X01))

{

   delay_ms(2);

   if(!(PINC&0X01)) 

   {

    TIMSK=0X00;

    mode++;

        mode%=3;

        set=0;

        if(mode==0)TIMSK=0X02;

        while(!(PINC&0X01));

   }

}



if(!(PINC&0X02))

{

   delay_ms(2);

   if(!(PINC&0X02)) 

   {

    if(mode==1)

        {

         set++;

         set%=3;

        }

        if(mode==2)

        {

         set++;

         set%=2;

        }

        while(!(PINC&0X02));

   }

}



if(!(PINC&0X04))

{

   delay_ms(2);

   if(!(PINC&0X04)) 

   {


    if(mode==1)

        {

         if(set==0)

         {

          hour++;

          hour%=24;

         }

         if(set==1)

         {

          min++;

          min%=60;

         } 

         if(set==2)

         {

          sec++;

          sec%=60;

         }  


        }

        if(mode==2)

        {

         if(set==0)

         {

          nz_hour++;

          nz_hour%=24;

         }

         if(set==1)

         {

          nz_min++;

          nz_min%=60;

         } 

        }

        while(!(PINC&0X04));

   }

  

}


//主函数

void main()

{/// 变量声明

   

char zz;  

  // 调用初始化哈数 

//port_init();

init_devices();

// 特定代码

   while(1)

   {

   

   

if(mode==0)  

{

   

    PORTD=~smg_zx[hour/10];  // 给5的字形编码  

    PORTB|=1<

        delay_ms(2);

        PORTB&=0B00111111;//        

                

   

    PORTD=~smg_zx[hour%10];  // 给5的字形编码  

         PORTB|=1<

         delay_ms(2);

     PORTB&=0B00111111;//

   

   

   

     PORTD=~smg_zx[min/10];  // 给5的字形编码  

     PORTC|=1<

         delay_ms(2);

         PORTC&=0B00001111;//        

                

   

    PORTD=~smg_zx[min%10];  // 给5的字形编码  

        PORTC|=1<


         delay_ms(2);

    PORTC&=0B00001111;//

   

    PORTD=~smg_zx[sec/10];  // 给5的字形编码  

    PORTC|=1<

        delay_ms(2);

        PORTC&=0B00001111;//        

                

   

     PORTD=~smg_zx[sec%10];  // 给5的字形编码  

         PORTC|=1<

         delay_ms(2);

     PORTC&=0B00001111;//

}


else if(mode==1)  

{

   

    PORTD=~smg_zx[hour/10];  // 给5的字形编码  

    PORTB|=1<

        delay_ms(2);

        PORTB&=0B00111111;//        

                

   

    PORTD=~smg_zx[hour%10];  // 给5的字形编码  

        if(set==0)  PORTD&=0x7f;//控制小数点亮

         PORTB|=1<

         delay_ms(2);

     PORTB&=0B00111111;//

   

   

   

     PORTD=~smg_zx[min/10];  // 给5的字形编码  

     PORTC|=1<

         delay_ms(2);

         PORTC&=0B00001111;//        

                

   

    PORTD=~smg_zx[min%10];  // 给5的字形编码  

         if(set==1)  PORTD&=0x7f;//控制小数点亮

        PORTC|=1<


         delay_ms(2);

    PORTC&=0B00001111;//

   

    PORTD=~smg_zx[sec/10];  // 给5的字形编码  

    PORTC|=1<

        delay_ms(2);

        PORTC&=0B00001111;//        

                

   

     PORTD=~smg_zx[sec%10];  // 给5的字形编码  

         if(set==2)  PORTD&=0x7f;//控制小数点亮

         PORTC|=1<

         delay_ms(2);

     PORTC&=0B00001111;//

}

else if(mode==2)

{


     PORTD=~smg_zx[nz_hour/10];  // 给5的字形编码  

    PORTB|=1<

        delay_ms(2);

        PORTB&=0B00111111;//        

                

   

    PORTD=~smg_zx[nz_hour%10];  // 给5的字形编码  

        if(set==0)  PORTD&=0x7f;//控制小数点亮

         PORTB|=1<

         delay_ms(2);

     PORTB&=0B00111111;//

   

   

   

     PORTD=~smg_zx[nz_min/10];  // 给5的字形编码  

     PORTC|=1<

         delay_ms(2);

         PORTC&=0B00001111;//        

                

   

     PORTD=~smg_zx[nz_min%10];  // 给5的字形编码  

         if(set==1)  PORTD&=0x7f;//控制小数点亮

         PORTC|=1<

         delay_ms(2);

     PORTC&=0B00001111;//

   


}



   if((hour==nz_hour)&&(min==nz_min))//闹钟

   {

    if(zz++>20)

        {

     PORTB^=1<

         zz=0;

        }

   }

   else

   PORTB|=1<

        

    

         key ();

        

        

    



   }

  }

   //T0中断服务程序 //  2ms 进入中断

   #pragma interrupt_handler timer0_ocf_isr:20

  void timer0_ocf_isr(void)

  {static int count=0;

   if(++count>=500)

   { count=0;

     sec++;

         if(sec>=60)

         {

         sec=0;

         min++;

          if(min>=60)



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
浅谈AVR中定时器几种工作模式