综合实例:51单片机(AT89C52)万年历(温度闹钟年月日时分秒星期)

来源:互联网 发布:7天逆回购利率知乎 编辑:程序博客网 时间:2024/06/01 07:21

功能说明:

LCD1602液晶显示年、月、日、时、分、秒、星期、温度,三个按键控制时间日期调整以及闹钟设定。

 

三个按键:

1、“校时”键,每次按下分别对应调整秒、调整分钟、调整小时、调整星期、调整日、调整月份、调整年份、调整闹钟分钟、调整闹钟小时、退出校时模式;

2、“增加/开闹钟功能”键,校时模式下按下此键则数值加一,非校时模式下按下此键则显示出闹钟时间并打开闹钟功能(屏幕显示字母A);

3、“减小/关闹钟功能”键,校时模式下按下此键则数值减一,非校时模式下按下此键则关闭闹钟显示并关闭闹钟功能(屏幕字母A消失);

 

 

#include<reg52.h>   typedef unsigned char uchar;  typedef unsigned int uint;  #define rs_h P3|=0x01//单片机向LCD1602液晶RS引脚输出高电平   #define rs_l P3&=0xfe   #define rw_h P3|=0x02   #define rw_l P3&=0xfd   #define en_h P3|=0x04    #define en_l P3&=0xfb   #define temp_h P3|=0x40//单片机向DS18B20输出高电平   #define temp_l P3&=0xbf//单片机向DS18B20输出低电平   #define rst_h P3|=0x08//单片机向DS1302时钟芯片RST引脚输出高电平   #define rst_l P3&=0xf7   #define sck_h P3|=0x10   #define sck_l P3&=0xef   #define io_h P3|=0x20   #define io_l P3&=0xdf   #define SECADD 0X80//秒寄存器地址   #define MINADD 0x82   #define HRADD 0x84   #define DATEADD 0x86   #define MONTHADD 0x88   #define DAYADD 0x8a   #define YEARADD 0x8c   #define CONTROLADD 0x8e   #define PORT (P2)//P2连接LCD1602的8个数据引脚   sbit time=P3^5;//DS1302输入输出引脚   sbit tmp=P3^6;//DS18B20输入输出引脚   void delayms(uint x);//延时函数   void lcd_com(uchar com);//LCD1602液晶写命令函数   void lcd_dat(uchar dat);//LCD1602液晶写数据函数   void lcd_write(uchar c,uchar r,uchar dat);//向LCD1602液晶指定行、指定列写数据函数   void lcd_init();//LCD1602液晶初始化   void Ds1302Init();//DS1302初始化   void WriteByte(uchar dat);//往DS1302写一字节   uchar ReadByte();//从DS1302读一字节   uchar BCDtoDex(uchar dat);//BCD码转十进制   uchar DextoBCD(uchar dat);//十进制转BCD码   void Ds1302Write(uchar add,uchar dat);//往DS1302指定地址写数据   uchar Ds1302Read(uchar add);//读DS1302制定地址的数据   void Ds18b20_reset();//DS18B20温度传感器复位   void Ds18b20_write(uchar dat);//往DS18B20写一字节   void showtem();//显示温度   uchar Ds18b20_read();//从DS18B20读一字节   char keyscan();//按键检测,有键按下返回1,否则返回0   uchar Timflag;//表示50ms时间到   uchar Temflag;//让"命令DS18B20转换温度"和"读温度值"两个模块错开执行   uchar dat1,dat2;//读回的温度值,dat1保存低字节,dat2保存高字节   uchar keystate=2;//按键状态标志,初始化为2,是为了程序第一次运行时能够进入keystat1分支   #define keystate0 1//keystate0在keyscan()函数中,代表按下确认功能   #define keystate1 2//keystate1在keyscan()函数中,代表无按键按下   uchar keynum;//调用keyscan()函数,如果该函数返回1,说明有键按下,keynum保存按键值   uchar keynum1=0;//指示键1按下了多少次   uchar TimeShowEn=1;//设置此变量是为了在校时状态期间,不让主函数再刷新时间显示   uchar TimeChanged;//用来指示用户是否修改了时间   sbit led1=P0^0;//键1指示灯,按下键1此灯变换状态   sbit led2=P0^1;//键2指示灯,按下键2此灯变换状态   sbit led3=P0^2;//键3指示灯,按下键3此灯变换状态   sbit buzz=P1^0;//蜂鸣器接口   uchar AlarmEn,AlarmCome;//AlarmEn指示是否开启了闹钟功能,AlarmCome指示定时时间是否到了   char AlarmMin,AlarmHr;//保存闹钟分钟、闹钟小时   uchar CountForAlarm;//用于累加时间,时间到,翻转蜂鸣器接口电平,决定蜂鸣器响声频率   uchar ToShowAlarm;//ToShowAlarm为1,则允许主函数中显示闹钟时间模块执行   uchar CountForShowAlarm;//CountForShowAlarm用于累加闹钟显示时间..................void Timer0() interrupt 1   {      TH0=(65536-50000)/256;      TL0=(65536-50000)%256;      Timflag=1;//Timflag 为1说明50ms定时时间到了   }  void Ds1302Init()  {      rst_l;      sck_l;      Ds1302Write(CONTROLADD,0);//关闭写保护       Ds1302Write(MINADD,DextoBCD(06));      Ds1302Write(HRADD,DextoBCD(19));      Ds1302Write(DATEADD,DextoBCD(20));      Ds1302Write(MONTHADD,DextoBCD(5));      Ds1302Write(DAYADD,DextoBCD(7));      Ds1302Write(YEARADD,DextoBCD(12));      Ds1302Write(SECADD,DextoBCD(30));//写秒,同时启动时钟       //Ds1302Write(CONTROLADD,0x80);//写保护   }  void WriteByte(uchar dat)//上升沿输出   {      uchar i;      for(i=8;i>0;i--)      {          sck_l;//低电平时数据线可变           if(dat&0x01)              io_h;          else              io_l;          sck_h;          dat>>=1;      }  }  uchar BCDtoDex(uchar dat)//BCD码转十进制   {      uchar i;      i=dat/16;      dat%=16;      i=i*10+dat;      return i;  }  uchar DextoBCD(uchar dat)//十进制转BCD码   {      uchar i;      i=dat/10;      dat%=10;      i=i*16+dat;      return i;  }  uchar ReadByte()//下降沿输出   {      uchar i;      uchar dat;      for(i=8;i>0;i--)//要考虑之前写完后的状态,第一次进入此循环体即有下降沿       {          dat>>=1;          sck_l;          if(time==1)              dat|=0x80;          sck_h;      }      return dat;  }  void Ds1302Write(uchar add,uchar dat)  {      rst_l;      sck_l;      rst_h;      WriteByte(add);//最低位为0表示写       WriteByte(dat);      rst_l;  }  uchar Ds1302Read(uchar add)  {      uchar dat;      rst_l;      sck_l;      rst_h;      WriteByte(add+1);//地址最低位置1表示读       dat=ReadByte();      rst_l;      return dat;  }  void delayms(uint x)//延时1ms   {      uint y,z;      for(y=x;y>0;y--)          for(z=111;z>0;z--);  }  void lcd_init()//LCD1602初始化   {      lcd_com(0x38);      lcd_com(0x0c);      lcd_com(0x06);      lcd_write(0,5,0xb0);//显示-       lcd_write(0,8,0xb0);//显示-       lcd_write(1,3,0x3a);//显示:       lcd_write(1,6,0x3a);//显示:   }  void lcd_com(uchar com)//向LCD1602写命令   {      rs_l;      rw_l;      PORT=com;      delayms(1);      en_h;      delayms(1);      en_l;  }  void lcd_dat(uchar dat)//向LCD1602写数据   {      rs_h;      rw_l;      PORT=dat;      delayms(1);      en_h;      delayms(1);      en_l;  }  void lcd_write(uchar c,uchar r,uchar dat)//向LCD1602指定行、指定列、写数据   {      lcd_com(0x80+0x40*c+r);      lcd_dat(dat);  }  ...  ...............


 


原创粉丝点击