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

2008-5-12 11:57 4585 6 8 分类: MCU/ 嵌入式

点击下载点击下载


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


平台: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);   //实时显示当前的数据
   else if(i==6)LCD_write_int(4,1,times+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=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();
 }


}

PARTNER CONTENT

文章评论2条评论)

登录后参与讨论

用户183085 2009-6-10 08:25

谢谢楼主分享

用户161927 2008-10-18 21:08

好东西啊,谢谢楼主
相关推荐阅读
正点原子 2013-05-17 23:47
【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第六十一章 战舰STM32开发板综合实验(标准例程终结篇)
   第六十一章 战舰STM32开发板综合实验        前面已经给大家讲了55个实例了,本章将设计一个综合实例,作为本指南的最后一个实验 ,该实验向大家展示了STM...
正点原子 2013-05-03 23:02
【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第六十章 UCOSII实验3-消息队列、信号量集和软件定时器
   第六十章 UCOSII实验3-消息队列、信号量集和软件定时器   上一章,我们学习了UCOSII的信号量和邮箱的使用,本章,我们将学习消息队列、信号量集和软件定时器...
正点原子 2013-05-03 20:42
【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第五十七章 ENC28J60网络实验
第五十七章 ENC28J60网络实验   本章,我们将向大家介绍ALIENTEK ENC28J60网络模块及其使用。本章,我们将使用ALIENTEK ENC28J60网络模块...
正点原子 2013-05-01 23:00
【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第五十九章 UCOSII实验2-信号量和邮箱
第五十九章 UCOSII实验2-信号量和邮箱      上一章,我们学习了如何使用UCOSII,学习了UCOSII的任务调度,但是并没有用到任务间的同步与通信,本章我们将学习两个最基本的...
正点原子 2013-04-30 10:55
【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第五十八章 UCOSII实验1-任务调度
  第五十八章 UCOSII实验1-任务调度      前面我们所有的例程都是跑的裸机程序(裸奔),从本章开始,我们将分3个章节向大家介绍UCOSII(实时多任务操作系...
正点原子 2013-04-26 23:16
【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第五十七章 ENC28J60网络实验
 第五十七章 ENC28J60网络实验  本章,我们将向大家介绍ALIENTEK ENC28J60网络模块及其使用。本章,我们将使用ALIENTEK ENC28J60网络模块和uIP 1...
我要评论
2
6
关闭 站长推荐上一条 /3 下一条