EDN首页   博客首页

日志档案

发表于 2008-5-12 11:57:40

0

标签: 51单片机  LCD1602使用  DS1302使用  DS18B20使用  

51 LCD1602综合电子钟 实验(二十三)

点击下载点击下载

这个实验是一个综合性的电子钟实验,详情见附件.

平台:FDR-1 51单片机开发板

主程序代码:

#include

#include "ds1302.h"
#include "LCD1602_4.h"
#include "ds18b20.h"

sbit alarm_speaker=P3^7;     //蜂鸣器的接线

unsigned char key="16";
unsigned char alarm_clock[3]={0}; //用于存放闹钟的时间:时分和闹钟的标志位

void delay(unsigned char i)    //延时函数
{
 unsigned char j;
  while(i--)
 for(j=101;j>1;j--);
}
void key_scan()
{   unsigned char X,Y,Z,k=key;
 P2=0x0f;
 P2=0x0f;          //先对P3置数  行扫描
 if(P2!=0x0f)      //判断是否有键按下
 { delay(5);      //延时,软件去干扰
   if(P2!=0x0f)     //确认按键按下X = P3;
  {
   X=P2;            //保存行扫描时有键按下时状态
   P2=0xf0;     //列扫描
   delay(5);        
   Y=P2;            //保存列扫描时有键按下时状态
    Z=X|Y;           //取出键值
   switch ( Z )     //判断键值(那一个键按下)
   {
    case 0xe7: k="4";break; //对键值赋值
    case 0xd7: k="8";break;
    case 0xb7: k="12";break;
    case 0x77: k="16";break;
    case 0xeb: k="3";break;
    case 0xdb: k="7";break;  
    case 0xbb: k="11";break;
    case 0x7b: k="15";break;
    case 0xed: k="2";break;
    case 0xdd: k="6";break;
    case 0xbd: k="10";break;
    case 0x7d: k="14";break;
    case 0xee: k="1";break;
    case 0xde: k="5";break;
    case 0xbe: k="9";break;
    case 0x7e: k="13";break;
   }
   key=k-1;
  }
 }
 P2=0xff;
}
void display_dat()       //显示时间和温度的函数
{
 CLEARSCREEN;
 LCD_write_string(0,0,"DAT:");
 LCD_write_int(4,0,2000+times[6]); //显示年份
 LCD_en_dat('-');

 LCD_write_int(9,0,times[4]/10);    //显示月份
 LCD_write_int(10,0,times[4]%10);
 LCD_en_dat('-');

 LCD_write_int(12,0,times[3]/10);   //显示日期
 LCD_write_int(13,0,times[3]%10);

 LCD_write_int(15,0,times[5]);    //显示星期

 LCD_write_int(0,1,times[2]/10);  //显示小时
 LCD_write_int(1,1,times[2]%10); 

 LCD_en_dat(':');
 LCD_write_int(3,1,times[1]/10);  //显示分钟
 LCD_write_int(4,1,times[1]%10); 

 LCD_en_dat(':');
 LCD_write_int(6,1,times[0]/10);  //显示秒
 LCD_write_int(7,1,times[0]%10); 

 LCD_write_int(10,1,zhengshu);  //显示温度的整数部分
 LCD_en_dat('.');
 LCD_en_dat(xiaoshu1+0x30);   //显示温度的小数部分
 LCD_en_dat(0x27);     //显示'号
 LCD_en_dat('C');     //显示C
}
void chang_time(unsigned char i)
{
 unsigned char tem="0",temp_time=0,clock=0,temp_clock;
 CLEARSCREEN;
 if(i<=7)
 {
  if(i==0) LCD_write_string(0,0,"Change second:");  //修改秒
  if(i==1) LCD_write_string(0,0,"Change minute:");  //修改分
  if(i==2) LCD_write_string(0,0,"Change hour:");   //修改时
  if(i==3) LCD_write_string(0,0,"Change day:");   //修改日
  if(i==4) LCD_write_string(0,0,"Change month:");   //修改月
  if(i==5) LCD_write_string(0,0,"Change week:");   //修改星期
  if(i==6) LCD_write_string(0,0,"Change year:");   //修改年
  if(i==7 && alarm_clock[2]==0) LCD_write_string(0,0,"Open AlarmClock");//修改闹钟
  if(i==7 && alarm_clock[2]!=0) LCD_write_string(0,0,"AlarmClock:");
  key=16;
  delay(250);
  while(1)
  {
   key_scan();
   if(key<10)
   {
    tem=(tem*10)+key;  
    if((i==0 || i==1 || clock==1) && tem>59) tem="59";//确保修改的数据不超出限制,
    if((i==2 || (clock==0 && i==7)) && tem>23) tem="23";  //比如分不能超过60,月不能超过12等。
    if(i==3 && tem>31) tem="31";      //如超过限制,则定为最大
    if(i==4 && tem>12) tem="12";
    if(i==5 && tem>7)
    {
     if(key<=7 && key!=0)tem=key;
      else tem="7";
    }
 
    delay(200);
    key=16;
   }
   if(key==14)
   {
    tem/=10;
    key=16;
    delay(200);
   }
   if(key==15 && i!=7)break; //确定闹钟之外的数据
   if(key==15 && i==7)
   {
    if(clock==0)
    {
     temp_clock=tem;  //确定闹钟的时
     key=16;
     tem=0;
     clock=1;
     delay(200);
    }
    else      //确定闹钟的分
    {
     alarm_clock[0]=temp_clock;
      alarm_clock[1]=tem;
     alarm_clock[2]=1;
     return;
    } 
   }
   if(key==12)return;
   if(key==13)
   {
    alarm_clock[2]=0;  //取消闹钟功能
    CLEARSCREEN;
    LCD_write_string(0,0,"Close AlarmClock");
    delay(250);
    delay(250);
    delay(250);
    delay(250);
    delay(250);
    delay(250);
    return;
   }
   if(temp_time!=tem)
   {
    LCD_write_char(8,1,' '); //实时显示修改的数据
    if(i==6)
     {
      LCD_write_int(9,1,20);
      LCD_en_dat(tem/10+0x30);
      LCD_en_dat(tem%10+0x30);
     }
    else if(clock==0)
    {
     LCD_write_int(7,1,tem);
     
     if(i==7)
     {
      LCD_en_dat(':');  //实时显示修改闹钟的数据
      LCD_en_dat(0x30);
      LCD_en_dat(0x30);
     }
    }
    
    else
    {
     LCD_write_int(7,1,temp_clock/10);
     LCD_write_int(8,1,temp_clock%10);
     LCD_en_dat(':');
     LCD_write_int(10,1,tem/10);
     LCD_write_int(11,1,tem%10);
    }
    
    temp_time=tem;
   }
   delay(100);
   read_1302_time(times);
   LCD_write_string(0,1,"Now:  ");
   if(i<6)LCD_write_int(4,1,times[i]);   //实时显示当前的数据
   else if(i==6)LCD_write_int(4,1,times[i]+2000);
    else if(i==7)
    {
     LCD_write_int(0,1,alarm_clock[0]/10); //显示当前闹钟的时间
     LCD_write_int(1,1,alarm_clock[0]%10);
     LCD_en_dat(':');
     LCD_write_int(3,1,alarm_clock[1]/10);
     LCD_write_int(4,1,alarm_clock[1]%10);
    }
  }
  read_1302_time(times);
  times[i]=tem;
  write_1302_time(times); //把数据写进1302
 }
}
void main()
{
 unsigned char temp="0";
 write_1302_time(times); //把数据写进1302
 LCD_init();
 while(1)
 {
  read_1302_time(times);  //读ds1302的时间
  key_scan();     //扫描键盘
  if(key<8)     //如果键盘值小于8则进入修改界面
  {
   chang_time(key);
   key=16;
  }
  if(times[1]==alarm_clock[1] && times[2]==alarm_clock[0] && alarm_clock[2]==1)//如时间到,闹钟响
  {
   if(key==16)alarm_speaker=0;
    
  }
  delay(30);
  alarm_speaker=1;
  delay(170);
  display_dat();//显示时间和温度
  Read_18B20();
 }

}

系统分类: 单片机   |   用户分类: 51单片机专区   |   来源: 原创   |   【推荐给朋友】   |   【添加到收藏夹】

    阅读(486)    回复(1)  

投一票您将和博主都有获奖机会!