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

AVR单片机电子钟C程序

作者:佚名   来源:本站原创   点击数:  更新时间:2012年05月25日   【字体:
#include<iom16v.h>
#include<macros.h>
#define uchar unsigned char
#define uint unsigned int
#define setb(val,bitn) (val|=(1<<(bitn)))//设置某IO口某位为1
#define clr(val,bitn) (val&=~(1<<(bitn)))//设置某IO口某位为0
#define get(val,bitn) (val&(1<<(bitn)))//读取某位状态
uchar shi=20,fen=39,miao,a=0xff,num;
#pragma interrupt_handler zhong:9//它所对应的位置
#pragma data:code//定义程序存在ROM里面
const uchar table[]={
0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90,
0x88,0x83,0xc6,0xa1,0x86,
0x8e
};
/***********************************************/
/*******************延时子程序******************/
/***********************************************/
void delay(uchar z)
{
   uchar x,y;
  for(x=0;x<255;x++)
  for(y=0;y<z;y++);
}
/***********************************************/
/*******************响一声子程序****************/
/***********************************************/
void bbtt()
{
   DDRA|=BIT(1);
  clr(PORTA,1);
  delay(250);
  setb(PORTA,1);
  delay(250);
}
/***********************************************/
/*******************显示子程序******************/
/***********************************************/
void xian(uchar shia,uchar fena)
{
  PORTB=table[shia/10];//小时十位
  clr(PORTC,3);
  delay(2);
  setb(PORTC,3);
  if(a==0)//如果标志位等于0xff,则关闭小时个位数码管
  PORTB=table[shia%10]|0x80;//小时个位
  else//否则
  PORTB=table[shia%10]&0x7f;//小时个位数码管强行点亮
  clr(PORTC,2);
  delay(2);
  setb(PORTC,2);
  PORTB=table[fena/10];//分钟十位
  clr(PORTC,1);
  delay(2);
  setb(PORTC,1);
  PORTB=table[fena%10];//分钟个位
  clr(PORTC,0);
  delay(2);
  setb(PORTC,0);
}
/***********************************************/
/*****************按键处理子程序****************/
/***********************************************/
void sk()
{
  uchar k;//定义一个变量来存数
    DDRD&=0Xf0;//设置PD IO口为输入方式,高4位不管
 PORTD|=0X0f;//设置IO口低4位为输入方式且带上拉电阻,即高电平
/***********************************************/
/****************主功能键产生键值***************/
/***********************************************/
 if(!get(PIND,0))//如果键值为0则说明有按键按下了
 {
   delay(1);//消抖一下
  if(!get(PIND,0))//再次判断一下
  {
    bbtt();//调用铃声
    num++;//键值标志加1
   a=0x00;//标志位变为0
   if(num==4)//如果标志位为4则清0
   {
     num=0;
    TIMSK|=BIT(2);//打开定时器中断
    a=0x00;
   }
  }
  while(!get(PIND,0));//按键松手检测,即如果键值处理程序

为1则说明有键按下,
 }
/***********************************************/
/*****************键值判断控制******************/
/***********************************************/
 switch(num)
 {
/*****************如果键值等于1时******************/
   case 1:
  TIMSK&=~BIT(2);//关闭定时器中断
  break;
/*****************如果键值等于2时******************/
  case 2:
  if(!get(PIND,1))//如果键值为0则说明有按键按下了
  {
      delay(1);//消抖一下
    if(!get(PIND,1))//再次判断一下
    {
        bbtt();
        shi++;//将小时加1
     if(shi==24)
     shi=0;
       while(!get(PIND,1));//按键松手检测,

即如果键值处理程序为1则说明有键按下,
    }
  }
  if(!get(PIND,2))//如果键值为0则说明有按键按下了
  {
      delay(1);//消抖一下
    if(!get(PIND,2))//再次判断一下
    {
        bbtt();
        shi--;//将小时减1
     if(shi==(0-1))
     shi=23;
       while(!get(PIND,2));//按键松手检测,

即如果键值处理程序为1则说明有键按下,
    }
  }
  break;
/*****************如果键值等于3时******************/
  case 3:
  if(!get(PIND,1))//如果键值为0则说明有按键按下了
  {
      delay(1);//消抖一下
    if(!get(PIND,1))//再次判断一下
    {
        bbtt();
        fen++;//分钟加1
     if(fen==60)
     shi=59;
       while(!get(PIND,1));//按键松手检测,

即如果键值处理程序为1则说明有键按下,
    }
  }
  if(!get(PIND,2))//如果键值为0则说明有按键按下了
  {
      delay(1);//消抖一下
    if(!get(PIND,2))//再次判断一下
    {
        bbtt();
        fen--;//分钟减1
     if(fen==(0-1))
     shi=59;
       while(!get(PIND,2));//按键松手检测,

即如果键值处理程序为1则说明有键按下,
    }
  }
  break;
 }
}
/***********************************************/
/*******************主程序*********************/
/***********************************************/
void main()
{
    DDRB=0XFF;//设置PA口为输出方式
 DDRC|=0x0f;//设置两位为输出方式
 TCCR1B=0X04;//设置256分频 6M晶体=6000000/256分频-65535化成16

进制
 TCNT1H=0XD2;//给它高位赋值
 TCNT1L=0X38;//给它低位赋值
 TIMSK|=BIT(2);//打开定时器中断
 SREG|=BIT(7);//打开总中断
 
 while(1)
 {
   sk();//按键调用
   xian(shi,fen);//显示调用
 }
}
/***********************************************/
/*****************中断服务子程序***************/
/***********************************************/
void zhong()
{
  TCNT1H=0XD2;//给它高位赋值
 TCNT1L=0X38;//给它低位赋值
 miao++;//将变量加1
 a=~a;//将标志位取反,小数点闪烁标志位
 if(miao==120)
 {
   miao=0;
  fen++;
  if(fen==60)
  {
    fen=0;
   shi++;
   if(shi==24)
   shi=0;
  }
 }
 
}

完整代码下载地址:http://www.51hei.com/f/dzza.rar

关闭窗口

相关文章