标题: 利用stc89s51单片机做万年历 [打印本页]
作者: 冉光在 时间: 2018-1-5 13:55
标题: 利用stc89s51单片机做万年历
#include <reg52.h>
#include<intrins.h>
#include<stdio.h>
#include"zm.h"
#include"delay.h"
#include"lcd12864.h"
#include"ds18b20.h"
#include"ds1302.h"
#include"process.h"
/*------------------------------------
全局变量定义
------------------------------------*/
bit Temperature_Flag; //读取并显示温度标签,使温度刷新频率低些
//bit Re_Time_Flag;
//bit Flag1; //进入子菜单后置标志,中断一次Menu_Count自加一次
bit Bell_Work;
/*------------------------------------
转换表
------------------------------------*/
//code UINT8 *WEEK_TAB[]={"一","二","三","四","五","六","日",}; //星期中文字库表
/*------------------------------------
函数声明部分
------------------------------------*/
//void Display_Time();
//void System_BootScreen();
//void Timer0_Init();
//void Int0_Init();
//void Display_Temperature();
//UINT8 Conver_Week(bit c,UINT8 year,UINT8 month,UINT8 date);
/*------------------------------------
启动画面
------------------------------------*/
void System_BootScreen()
{
UINT8 i;
LCD_SendImg128x64(User0_128x64); //欢迎画面
for(i=0;i<10;i++)
DelayMs(255); //画面延时
LCD_SendImg128x64(User1_128x64); //照片显示
for(i=0;i<10;i++)
DelayMs(255);
}
/*------------------------------------
初始化定时器
------------------------------------*/
void Timer_1 int()
{
TMOD|=0x11; //两个定时器置方式一
IE=0X8a; //开总中断开关和两个定时器中断开关
PT1=1; //按键音产生中断T1权拉高,使之能在INT0下产生声响
TR0=1; //开启定时器0,刷新用
//PX0=1;
//TR1=1;
}
/*------------------------------------
初始化INT0
------------------------------------*/
void int0_Init()
{
EX0=1; //打开外中断0,中断允许
IT0=1; //设置下降沿触发
}
/*------------------------------------
INT0中断处理函数
------------------------------------*/
Void int0_IRQ() interrupt 0
{
Menu_Flag=1; //进入主菜单标签
TR1=1; //开启TR1有按键音
while(!KEY_MENU) ; //等待按键结束,使用中断做按键,能让它实时性比较
TR1=0; //按键结束,按键音结束
if(Menu0) //子菜单0(设置时间进入后)
{
Set_Hour=~Set_Hour; //因为只有时钟和分钟个设置,0和1两种状态能区分了
}
else if(Menu1) //子菜单1(设置日期进入后)
Menu1_Flag=1; //为减少中断代码长度,事实证明,用个标志更好
else if(Menu2)
Menu2_Flag=1;
else if(Menu3) Set_Bright=~Set_Bright; //子菜单3(背景光开关)
else if(Menu4) Set_Speaker=~Set_Speaker; //子菜单4(按键音开关)
Refresh_SetTime=1; //在子状态中任何状态按一下都会使产生刷新显示标签。
}
/*------------------------------------
T0中断处理函数
------------------------------------*/
void Timer0_IRQ() interrupt 1
{
static UINT8 i;
TH0=0x3;
TL0=-50000%256;
i++;
if(i==80) Temperature_Flag=1; //2.5s中产生一次(读取并刷新温度的标签)
}
/*------------------------------------
T1中断处理函数
------------------------------------*/
void Timer1_IRQ() interrupt 3
{
TH1=-600/256; //产生某种频率的按键音
TL1=-600%256; //经测试,2000HZ~4000HZ左右的比较适合做按键音
SPEAKER=~SPEAKER; //产生方波 提供某种频率的按键音
}
/*------------------------------------
主函数
------------------------------------*/
void main()
{
LCD_ClearGDRAM(); //清除DDRAM和GDRAM的显示
System_BootScreen(); //启动画面
DS1302_Init(); //初始化DS1302
Int0_Init(); //初始化外中断0
LCD_Init(); //初始化12864
Timer_Init(); //初始化定时器
LCD_ClearGDRAM(); //清屏DDRAM和GDRAM
LCD_SetCGRAM(1,User1_16x16);//写入CGRAM自定义字符 主菜单指向箭头
LCD_SetCGRAM(0,User0_16x16);//闹钟标志
LCD_SetCGRAM(2,User2_16x16);//℃
LCD_SetCGRAM(3,User4_16x16);//温度计
Display_Temperature(); //开始的时候先显示下温度,使界面比较完整不会空缺
SPEAKER=0; //断开喇叭,使之不会长时间导通烧坏
BRIGHT=1; //打开背景光
while(1)
{
SPEAKER=0; //断开喇叭,使之不会长时间导通烧坏
if(Temperature_Flag) //大循环下,温度标签置位后刷新显示温度
{
Temperature_Flag=0; //清零标签
Display_Temperature();
}
if(!Menu_Flag) //没有菜单标签则显示主时钟界面
{
DS1302_ReadDate(); //读取日期
if(Bell_Flag) //Bell标志被置位,表明在设置菜单里,开始定时了,开始往下执行,等待定时到
{
if(Hour==Bell_Hour&&Minute==Bell_Minute)
{
LCD_ClearGDRAM();
LCD_SendImg128x64(User2_128x64);
Bell_Work=1;
ET1=1;
TR1=1;
while(1)
{
if(!KEY_ENTER)
{
DelayMs(10);
if(!KEY_ENTER)
{
while(!KEY_ENTER);
Bell_Flag=0;
Temperature_Flag=1;
Bell_Work=0;
TR1=0;
Menu_Flag=0;
LCD_ClearGDRAM();
LCD_Init();
break;
}
}
}
}
}
Display_Date(); //填充显示日期
Display_Week(); //填充显示星期
DS1302_ReadTime(); //读取时间
Display_Time(); //填充显示时间
}
else if(Menu_Flag) //显示控制界面
{
LCD_ClearGDRAM(); //清屏之前的主时钟界面
LCD_RefreshMenu(); //菜单显示
FanHui1=0; //清零FanHui1标签,使之每一次进入菜单后都能停在下面那个while菜单循环中
//guide_old++; //
while(!FanHui1) //FanHui没有被置1,死循环,当主菜单下按了返回则置1,跳出循环
{
MainMenu_Pro(); //主菜单处理函数
SPEAKER=0; //断开喇叭,使之不会长时间导通烧坏
while(Enter_Menu) //进入子菜单标签
{
if(Menu0) Menu0_Pro(); //子菜单0处理函数
else if(Menu1) Menu1_Pro();
else if(Menu2) Menu2_Pro();
else if(Menu3) Menu3_Pro();
else if(Menu4) Menu4_Pro();
else if(Menu5) Menu5_Pro();
SPEAKER=0; //断开喇叭,使之不会长时间导通烧坏
}
}//一级菜单while()
Temperature_Flag=1; //每当退出主菜单,重新显示温度
}//显示界面块
}
}
欢迎光临 (http://www.51hei.com/bbs/) |
Powered by Discuz! X3.1 |