基于AT89C51单片机的万年历源程序

发布时间:2023-01-05  

#include //调用单片机头文件

#define uchar unsigned char //无符号字符型 宏定义 变量范围0~255

#define uint unsigned int //无符号整型 宏定义 变量范围0~65535

#include "eeprom52.h"

#include "nongli.h"

#include "intrins.h"

bit flag_200ms ;

bit flag_100ms ;

sbit beep = P3^7; //蜂鸣器定义

bit flag_beep_en;

uint clock_value; //用作闹钟用的

sbit dq = P3^1; //18b20 IO口的定义

uint temperature ; //温度变量

uchar flag_nl; //农历 阳历显示标志位

uchar menu_1,menu_2;

uchar key_time,flag_value; //用做连加的中间变量

bit key_500ms ;

uchar n_nian,n_yue,n_ri; //农历显示的函数

#include "ds1302.h"

#include "lcd1602.h"

/******************把数据保存到单片机内部eeprom中******************/

void write_eeprom()

{

SectorErase(0x2000);

byte_write(0x2000, fen1);

byte_write(0x2001, shi1);

byte_write(0x2002, open1);

byte_write(0x2058, a_a);

}

/******************把数据从单片机内部eeprom中读出来*****************/

void read_eeprom()

{

fen1 = byte_read(0x2000);

shi1 = byte_read(0x2001);

open1 = byte_read(0x2002);

a_a = byte_read(0x2058);

}

/**************开机自检eeprom初始化*****************/

void init_eeprom()

{

read_eeprom(); //先读

if(a_a != 1) //新的单片机初始单片机内问eeprom

{

fen1 = 3;

shi1 = 8;

open1 = 1;

a_a = 1;

write_eeprom(); //保存数据

}

}

/***********************18b20初始化函数*****************************/

void init_18b20()

{

bit q;

dq = 1; //把总线拿高

delay_uint(1); //15us

dq = 0; //给复位脉冲

delay_uint(80); //750us

dq = 1; //把总线拿高 等待

delay_uint(10); //110us

q = dq; //读取18b20初始化信号

delay_uint(20); //200us

dq = 1; //把总线拿高 释放总线

}

/*************写18b20内的数据***************/

void write_18b20(uchar dat)

{

uchar i;

for(i=0;i<8;i++)

{ //写数据是低位开始

dq = 0; //把总线拿低写时间隙开始

dq = dat & 0x01; //向18b20总线写数据了

delay_uint(5); // 60us

dq = 1; //释放总线

dat >>= 1;

}

}

/*************读取18b20内的数据***************/

uchar read_18b20()

{

uchar i,value;

for(i=0;i<8;i++)

{

dq = 0; //把总线拿低读时间隙开始

value >>= 1; //读数据是低位开始

dq = 1; //释放总线

if(dq == 1) //开始读写数据

value |= 0x80;

delay_uint(5); //60us 读一个时间隙最少要保持60us的时间

}

return value; //返回数据

}

/*************读取温度的值 读出来的是小数***************/

uint read_temp()

{

uint value;

uchar low; //在读取温度的时候如果中断的太频繁了,就应该把中断给关了,否则会影响到18b20的时序

init_18b20(); //初始化18b20

write_18b20(0xcc); //跳过64位ROM

write_18b20(0x44); //启动一次温度转换命令

delay_uint(50); //500us

init_18b20(); //初始化18b20

write_18b20(0xcc); //跳过64位ROM

write_18b20(0xbe); //发出读取暂存器命令

EA = 0;

low = read_18b20(); //读温度低字节

value = read_18b20(); //读温度高字节

EA = 1;

value <<= 8; //把温度的高位左移8位

value |= low; //把读出的温度低位放到value的低八位中

value *= 0.625; //转换到温度值 小数

return value; //返回读出的温度 带小数

}

/******************1ms 延时函数*******************/

void delay_1ms(uint q)

{

uint i,j;

for(i=0;i

for(j=0;j<120;j++);

}

/******************写星期函数*******************/

void write_week(uchar hang,uchar add,uchar week)//写星期函数

{

if(hang==1)

write_com(0x80+add);

else

write_com(0x80+0x40+add);

write_com(0x80+0x40+add);

switch(week)

{

case 1:write_data('M');//星期数为1时,显示

write_data('O');

write_data('N');

break;

case 2:write_data('T');//星期数据为2时显示

write_data('U');

write_data('E');

break;

case 3:write_data('W');//星期数据为3时显示

write_data('E');

write_data('D');

break;

case 4:write_data('T');//星期数据为4是显示

write_data('H');

write_data('U');

break;

case 5:write_data('F');//星期数据为5时显示

write_data('R');

write_data('I');

break;

case 6:write_data('S');//星期数据为6时显示

write_data('T');

write_data('A');

break;

case 7:write_data('S');//星期数据为7时显示

write_data('U');

write_data('N');

break;

}

}

/*************时钟显示***************/

void init_1602_ds1302()

{

write_sfm2_ds1302(1,1,shi); //显示时

write_sfm2_ds1302(1,4,fen); //显示分

write_sfm2_ds1302(1,7,miao); //显示秒

write_week(2,12,week);

//write_sfm1(1,14,week); //显示星期

write_sfm3_18B20(1,11,temperature); //显示温度

if(flag_nl == 0) //显示阳历

{

write_sfm2_ds1302(2,2,nian); //显示年

write_sfm2_ds1302(2,5,yue); //显示月

write_sfm2_ds1302(2,8,ri); //显示日

}

else //显示农历

{

write_sfm2_ds1302(2,2,n_nian); //显示年

write_sfm2_ds1302(2,5,n_yue); //显示月

write_sfm2_ds1302(2,8,n_ri); //显示日

}

}

/*************定时器0初始化程序***************/

void init_time0()

{

EA = 1; //开总中断

TMOD = 0X01; //定时器0、工作方式1

ET0 = 1; //开定时器0中断

TR0 = 1; //允许定时器0定时

}

/*************闹钟报警函数***************/

void menu_dis()

{

static uchar mm,value;

if(flag_100ms == 1) //100ms执行一次

{

flag_100ms = 0;

if(open1 == 1) //如果闹钟打开

{

if((miao == 0) && (fen == fen1) && (shi == shi1))

{

flag_beep_en = 1; //有报警 打开蜂鸣器响的标志位

}

if(flag_beep_en == 1) //闹钟以被打开

{

clock_value++;

if(clock_value <= 30)

beep = ~beep; //蜂鸣器叫3秒

else if(clock_value > 30)

{

beep = 1; //蜂鸣器停1秒

if(clock_value > 40)

{

clock_value = 0;

}

}

}

// 1 分钟后自动关闭闹钟

value ++;

if(value >= 10)

{

value = 0;

mm++;

if(mm >= 60)

{

mm = 0;

flag_beep_en = 0;

beep = 1;

}

}

}

}

}

}

/********************独立按键程序*****************/

uchar key_can; //按键值

void key() //独立按键程序

{

static uchar key_new;

key_can = 20; //按键值还原

P3 |= 0x78; //对应的按键IO口输出为1

文章来源于:电子工程世界    原文链接

本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>