基于单片机的电子钟程序设计与调试

一、硬件

单片机、DS18B20、实时时钟、数码管、独立按键、led

二、功能描述
3.1 初始化
        1)关闭蜂鸣器、继电器等无关外设;
        2)设备初始化时钟为23 时59 分50 秒,闹钟提醒时间0 时0 分0 秒。
3.2 显示功能
        1) 时间显示格式
                                1 2 - 0 0 - 0 2
                                                       12 时间隔0 分间隔2 秒
        2) 温度显示格式
                                 8 8 8 8 8 2 1 C
                                   熄灭        温度

3.3 按键功能
       1)按键S7 定义为“时钟设置”按键,通过该按键可切换选择待调整的时、分、秒,当前选择的显示单元以1 秒为间隔亮灭,时、分、秒、时钟显示的调整需注意数据边界属性。

       2)按键S6 定义为“闹钟设置”按键,通过该按键可进入闹钟时间设置功能,数码管显示当前设定的闹钟时间。

       3) 按键S5 定义为“加”按键,在“时钟设置” 或“闹钟设置” 状态下,每次按下该按键当前选择的单元(时、分或秒)增加1 个单位。
       4) 按键S4 定义为“减”按键,在“时钟设置” 或“闹钟设置” 状态下,每次按下该按键当前选择的单元(时、分或秒)减少1 个单位。
       5) 按键功能说明:按键S4、S5 的“加”、“减”功能只在“时钟设置”或“闹钟设置”状态下有效;在“时钟显示”状态下,按下S4 按键,显示温度数据,松开按键,返回“时钟显示”界面。
3.4 闹钟提示功能
       1)指示灯L1 以0.2 秒为间隔闪烁,持续5 秒钟;
       2)闹钟提示状态下,按下任意按键,关闭闪烁提示功能。

三、代码

#include
#include
#define uint unsigned int
#define uchar unsigned char

sbit dula=P2^6;					  //控制数码管的段选端:当前数码管选中的发光段
sbit wela=P2^7;					  //控制数码管的位选端:选用什么位置的数码管
sbit led=P1^0;
sbit s4=P3^6;					  //减少键、显示温度键
sbit s5=P3^7;					  //增加键
sbit s2=P3^4;					  //“闹钟设置”按键
sbit s3=P3^5;					  //“时钟设置”按键
sbit DS=P2^2; 					  //ds温度传感器
sbit buzzer=P2^3;				  //蜂鸣器
          
uint temp;								   //温度参数
unsigned char flag = 0;                    //判断数码管的闪烁            
uchar flag1,shi1,ge1,shi2,ge2,shi3,ge3;	   //时分秒的个十位
uchar aa,aa1,hour=23,min=59,second=57;	   //时钟初始化: 23:59:50
uchar nhour=0,nmin=0,nsecond=0;			   //闹钟初始化: 00:00:00
uchar code table[]={0x3f,0x06,0x5b,0x4f,
                    0x66,0x6d,0x7d,0x07,
                    0x7f,0x6f,0x00};  //定义对应0~9,最后一个是是熄灭数码管

/***************************************************/
/*             *******温度器*******                */
/***************************************************/
void delay1(uint count)     			  //延时函数
{
  uint i;
  while(count)
  {
    i=200;
    while(i>0)
    i--;
    count--;
  }
}

void dsreset(void)       				  //初始化函数,温度传感器复位
{
  uint i;
  DS=0;
  i=103;
  while(i>0)i--;
  DS=1;
  i=4;
  while(i>0)i--;
}

bit tmpreadbit(void)       				  //读一位数据函数
{
   uint i;
   bit dat;								  
   DS=0;i++;          					 //i++起到延时作用
   DS=1;i++;i++;
   dat=DS;
   i=8;while(i>0)i--;
   return (dat);
}

uchar tmpread(void)   					  //读一个字节数据函数
{
  uchar i,j,dat;
  dat=0;
  for(i=1;i<=8;i++)
  {
    j=tmpreadbit();						   
    dat=(j<<7)|(dat>>1);   				  //读出数据最低位在最前面,这样刚好1字节在dat里
  }
  return(dat);
}

void tmpwritebyte(uchar dat)   			  //向DS18B20写入一字节数据函数
{
  uint i;
  uchar j;
  bit testb;
  for(j=1;j<=8;j++)
  {
    testb=dat&0x01;
    dat=dat>>1;
    if(testb)    						  //写1
    {
      DS=0;
      i++;i++;
      DS=1;
      i=8;while(i>0)i--;
    }
    else
    {									  //写0
      DS=0;      
      i=8;while(i>0)i--;
      DS=1;
      i++;i++;
    }

  }
}

void tmpchange(void)  					  //获取温度
{
  dsreset();
  delay1(1);
  tmpwritebyte(0xcc);  					  //写跳过读rom指令
  tmpwritebyte(0x44); 					  //写温度转换指令
}

uint tmp()               				  //读取寄存器中存储的温度数据
{
  float tt;
  uchar a,b;
  dsreset();
  delay1(1);
  tmpwritebyte(0xcc);
  tmpwritebyte(0xbe);
  a=tmpread();							  //读低8位
  b=tmpread();							  //读高8位
  temp=b;
  temp<<=8;           					  //两个字节组合为一个字
  temp=temp|a;
  tt=temp*0.0625;						  //温度在寄存器中为12位,分辨率为0.0625度
  temp=tt*10+0.5;						  //乘以10,表示为小数后面只取一位,加0.5是四舍五入
  return temp;
}

void DSdisplay(uint temp)					//显示温度函数
{
   uchar A1,A2,A2t;
   A1=temp/100;
   A2t=temp%100;
   A2=A2t/10;

   dula=1;
   P0=table[A1];		
   dula=0;
   wela=1;
   P0=0xf7;
   wela=0;
   delay1(1);

   dula=1;
   P0=table[A2];		
   dula=0;
   wela=1;
   P0=0xef;
   wela=0;
   delay1(1);
	
   dula=1;
   P0=0x58;
   dula=0;
   wela=1;
   P0=0xdf;
   wela=0;
   delay1(1);
}

void wendu()				                //按键显示温度主函数
{
   if(!s4)
   {
	   delay1(10);
		if(!s4)
		{
           uchar a=25;
           tmpchange();
	       while(a>0)  
		   {
		       a--;
			   DSdisplay(tmp());  		 
		   }
		   while(!s4);
	    }
	}
}

/***************************************************/
/*             *******时钟*******                  */
/***************************************************/         
void inint()								//定时器的设置
{											//使用定时器0和1
        TMOD=0x11;
        TH0=(65536-45872)/256;
        TL0=(65536-45872)%256;
		TH1=(65536-45872)/256;
        TL1=(65536-45872)%256;
        EA=1;
        ET0=1;					 //打开T0定时器中断
		ET1=1;					 //打开T1定时器中断
        TR0=1;					 //开始启用T0计数器/定时器
        TR1=1;					 //开始启用T1计数器/定时器
}

void delay(uint z)							//毫秒延时函数
{
        uint x,y;
        for(x=z;x>0;x--)
          for(y=110;y>0;y--);
}


void displayhour(uchar h)	     //显示小时函数
{
	 if(h==-1)
	 {
		dula=1;								
        P0=table[10];
        dula=0;
        wela=1;
        P0=0xfe;
        wela=0;
        delay(2);

        dula=1;
        P0=table[10];
        dula=0;
        wela=1;
        P0=0xfd;
        wela=0;
        delay(2);
	 }
		
	 else 
	 {
		shi1=h/10;
        ge1=h%10;
       								
        dula=1;								
        P0=table[shi1];
        dula=0;
        wela=1;
        P0=0xfe;
        wela=0;
        delay(2);

        dula=1;
        P0=table[ge1]|0x80;
        dula=0;
        wela=1;
        P0=0xfd;
        wela=0;
        delay(2);
	 }
}

void displaymin(uchar m)	 //显示分钟函数
{	 
   if(m==-1)
   {
	  dula=1;
      P0=table[10];
      dula=0;
      wela=1;
      P0=0xfb;
      wela=0;
      delay(2);

      dula=1;
      P0=table[10];
      dula=0;
      wela=1;
      P0=0xf7;
      wela=0;
      delay(2);
   }
   else
   {	  
	  shi2=m/10;
      ge2=m%10;

	  dula=1;
      P0=table[shi2];
      dula=0;
      wela=1;
      P0=0xfb;
      wela=0;
      delay(2);

      dula=1;
      P0=table[ge2]|0x80;
      dula=0;
      wela=1;
      P0=0xf7;
      wela=0;
      delay(2);
	}
}

void displaysecond(uchar s)	     //显示秒钟函数
{
  if(s==-1)
  {
    dula=1;
    P0=table[10];
    dula=0;
    wela=1;
    P0=0xef;
    wela=0;
    delay(2);

    dula=1;
    P0=table[10];
    dula=0;
    wela=1;
    P0=0xdf;
    wela=0;
    delay(2); 
  }
  else
  {	
	shi3=s/10;
    ge3=s%10;

	
    dula=1;
    P0=table[shi3];
    dula=0;
    wela=1;
    P0=0xef;
    wela=0;
    delay(2);

    dula=1;
    P0=table[ge3];
    dula=0;
    wela=1;
    P0=0xdf;
    wela=0;
    delay(2);
  }
}

void naozhong()	                 //闹钟函数
{	
    uint n=15;
    if(hour==nhour&&min==nmin&&second==nsecond)
    while(n--)
    {
		if(s5==0||s4==0||s2==0||s3==0)
		{
			delay(10);
		    if(s5==0||s4==0||s2==0||s3==0)
		    {
			   while((!s4)||(!s5)||(!s2)||(!s3));
			   break; 
			}
		}
		displayhour(hour);
		displaymin(min);
		displaysecond(second);
		led=0;
		delay(200);
		led=1;
		delay(200); 
	}
}


 /***************时钟设置键*****************/
void key7()
{	
     uchar n=1;
	 ET0=0;										 //中断定时器0
	 while(1)
	 {
	  if(n==1)          
	  {  
		while(1)
		{
			if(s3==0)
			{
				delay(10);
				if(s3==0)
				{
					while(!s3);
					n++;
					break;
				}
			}
			if(flag==1)displayhour(hour);			//闪烁数码管
			else displayhour(-1);
			displaymin(min);
			displaysecond(second);
			if(s5==0)
			{
			    delay(10);
				if(s5==0)
				{
					while(!s5);
					hour++;
					if(hour==24)hour=0;
				}
			}
			if(s4==0)
			{
				delay(10);
				if(s4==0)
				{
					while(!s4);
					hour--;
					if(hour==-1)hour=23;
				}
			}
		}
	  }
	  else if(n==2)           
		   {
			  while(1)
			  {
				  if(s3==0)
				  {
					  delay(10);
					  if(s3==0)
					  {
						while(!s3);
						n++;
						break;
					  }
				  }	
				if(flag==1)displaymin(min);
		    	else displaymin(-1);
			    displayhour(hour);
			    displaysecond(second);
				if(s5==0)
				{
					delay(10);
					if(s5==0)
					{
						while(!s5);
						min++;
						if(min==60)min=0;
					
					}
				}
				if(s4==0)
				{
					delay(10);
					if(s4==0)
					{
						while(!s4);
						min--;
						if(min==-1)min=59;
					}
				}
			  }
			}
			else if(n==3)           //?????
			{
				while(1)
				{
				  if(s3==0)
				  {
					  delay(10);
					  if(s3==0)
					  {
							while(!s3);
							n++;
							break;
					  }
				  }
				if(flag==1)displaysecond(second);
		        else displaysecond(-1);
			    displayhour(hour);
			    displaymin(min);
				if(s5==0)
				{
					delay(10);
					if(s5==0)
					{
						while(!s5);
						second++;
						if(second==60)second=0;
					}
				}
				if(s4==0)
				{
					delay(10);
					if(s4==0)
					{
						while(!s4);
						second--;
						if(second==-1)second=59;
					}
				}
			 }
			}
			
			if(n>=4)break;
		 }
		 ET0=1;								  //开启定时器1
}

 /***************闹钟设置键*******************/
void key6()
{	uchar n=1;
	 while(1)
	 {
	  if(n==1)          
	  {  
		while(1)
		{
			if(s2==0)
			{
				delay(10);
				if(s2==0)
				{
					while(!s2);
					n++;
					break;
				}
			}
			if(flag==1)displayhour(nhour);
			else displayhour(-1);
			displaymin(nmin);
			displaysecond(nsecond);
			if(s5==0)
			{
			    delay(10);
				if(s5==0)
				{
					while(!s5);
					nhour++;
					if(nhour==24)nhour=0;
				}
			}
			if(s4==0)
			{
				delay(10);
				if(s4==0)
				{
					while(!s4);
					nhour--;
					if(nhour==-1)nhour=23;
				}
			}
		}
	  }
	  else if(n==2)           
		   {
			  while(1)
			  {
				  if(s2==0)
				  {
					  delay(10);
					  if(s2==0)
					  {
						while(!s2);
						n++;
						break;
					  }
				  }	
				if(flag==1)displaymin(nmin);
		    	else displaymin(-1);
			    displayhour(nhour);
			    displaysecond(nsecond);
				if(s5==0)
				{
					delay(10);
					if(s5==0)
					{
						while(!s5);
						nmin++;
						if(nmin==60)nmin=0;
					
					}
				}
				if(s4==0)
				{
					delay(10);
					if(s4==0)
					{
						while(!s4);
						nmin--;
						if(nmin==-1)nmin=59;
					}
				}
			  }
			}
			else if(n==3)           //?????
			{
				while(1)
				{
				  if(s2==0)
				  {
					  delay(10);
					  if(s2==0)
					  {
							while(!s2);
							n++;
							break;
					  }
				  }
				if(flag==1)displaysecond(nsecond);
		        else displaysecond(-1);
			    displayhour(nhour);
			    displaymin(nmin);
				if(s5==0)
				{
					delay(10);
					if(s5==0)
					{
						while(!s5);
						nsecond++;
						if(nsecond==60)nsecond=0;
					}
				}
				if(s4==0)
				{
					delay(10);
					if(s4==0)
					{
						while(!s4);
						nsecond--;
						if(nsecond==-1)nsecond=59;
					}
				}
			 }
			}
			
			if(n>=4)break;
		 }
}		  

void main()
{
    inint();						 //初始化
	buzzer=1;						 //初始化蜂鸣器
    while(1)
   {		   
	    displayhour(hour);
		displaymin(min);
		displaysecond(second);
		if(0==s2)					   //闹钟设置
		{
		    delay(10);
			if(0==s2)
			{
				while(!s2);
				key6();
			}
		}
		if(0==s3)					   //时钟设置
		{
			delay(10);
			if(0==s3)
			{
				while(!s3);
				key7();
			}
		}
        naozhong();
		wendu();
	}
} 

void zhongduan1() interrupt 1	  //定时器0中断
{
    TH0=(65536-45872)/256;
    TL0=(65536-45872)%256;
    aa++;
    if(aa==20)
    {
       aa=0;
       second++;
       if(second==60)
       {
          second=0;
          min++;
          if(min==60)
          {
             min=0;
             hour++;
          }
        }
        if(hour==24 && second==0)
        {
           hour=0;
           min=0;
           second=0;                                                                                                                                 
        }                        
    }
}

void zhongduan2() interrupt 3	  //定时器1中断
{
   	TH1=(65536-45872)/256;
    TL1=(65536-45872)%256;
	aa1++;
	if(aa1==20)
	{
	   aa1=0;
	   if(flag==0)	flag=1;
	   else  flag=0; 
	}
}

 

你可能感兴趣的:(c程序知识)