单片机设计_万年历与计算器(AT89C51)

想要更多项目私wo!!!

一、简介

此系统主要由AT89C51、DS18B20温度模块、LCD1602液晶显示屏、DS1302时钟模块和矩阵按键组成。

二、运行效果图

  

三、部分代码

#include <reg52.h>
#include <intrins.h>  //包含_nop_()函数定义的头文件
#define uchar unsigned char
#define uint  unsigned int
//以下是对1302的定义 
sbit  clk= P2^3;              //实时时钟时钟线引脚 
sbit  IO= P2^2;              //实时时钟数据线引脚 
sbit  rst =P2^1;              //实时时钟复位线引脚
uchar second,minute,hour,week,day,month,year;       //8421码表示的时间  高四位用于表示十位,低四位用于表示个位
char second1,minute1,hour1,week1,day1,month1,year1;//十进制表示的时间  也即普通意义下的时间
uchar read_byte(uchar com);
uchar readyear_byte(uchar com);
void write_byte(uchar com,uchar date); 
void init_1302();
void readtime(); 
//以下是对lcd1602的定义
sbit wela=P2^6;
sbit dula=P2^7;
uchar table[]="0123456789";
sbit LCM_RS=P2^6;    //寄存器选择位,将RS位定义为P2.6引脚
sbit LCM_EN=P2^5;     //使能信号位,将E位定义为P2.5引脚
bit lcd_bz(void);
void write_com(unsigned char CMD);
void write_date(unsigned char dataW);
void init_1602();
void displaytime();
void delaynms(unsigned char n);
//以下是对按键调时程序的定义
sbit mode=P1^0;	 //调整闹钟或者时间时的选择按键
sbit plus=P1^1;	 //加1键
sbit minus=P1^2; //减1键
sbit s1=P1^3;	 //计算器和万年历切换键
void key();
void delay20ms(); 
//以下是对温度采集部分的定义 
sbit DS=P2^0; 			 //DS18B20数据端口
uchar code wendu[]="0123456789";        //利用一个温度表解决温度显示乱码 
void write_byte(uchar com,uchar date);	 //写一个字节
void tmpDelay(int num);					// 延时
void Init_DS18B20();					//初始化DS18B20
unsigned char ReadOneChar();		    //读一个字节
void WriteOneChar(unsigned char dat);	//写数据
unsigned int Readtemp();				//读温度
void display();							//显示温度


/**************************************************************
主程序
*************************************************************/
main()
{	init_1602();   //LCD1602初始化
	while(1)
	{readtime();	//读时间 	
	 displaytime();	//显示时间
	 key();			//调整时间键盘
	 display();	   //读温度并显示
	 switchfunction();//调功能切换程序,若功能切换键按下,进入计算器显示模式
	 } 	
}  

/*************DS18B20温度读取模块*************/
void tmpDelay(int num)//延时函数
{
	while(num--) ;
}

void Init_DS18B20()//初始化ds1820
{
	unsigned char x=0;
	DS = 1;    //DS复位
	tmpDelay(8);  //稍做延时
	DS = 0;    //单片机将DS拉低
	tmpDelay(80); //精确延时 大于 480us
	DS = 1;    //拉高总线
	tmpDelay(14);
	x=DS;      //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
	tmpDelay(20);
}

unsigned char ReadOneChar()//读一个字节
{
	unsigned char i=0;
	unsigned char dat = 0;
	for (i=8;i>0;i--)
	{
		DS = 0; // 给脉冲信号
		dat>>=1;
		DS = 1; // 给脉冲信号
		if(DS) 	dat|=0x80;
		tmpDelay(4);
	}
	return(dat);
}

void WriteOneChar(unsigned char dat)//写一个字节
{	char i;
	for (i=8; i>0; i--)	{
		DS = 0;	DS = dat&0x01;	tmpDelay(5);
		DS = 1;	dat>>=1;  }
}

unsigned int Readtemp()//读取温度
{
	unsigned char a=0;
	unsigned char b=0;
	unsigned int t=0;
	float tt=0;	
	Init_DS18B20();
	WriteOneChar(0xCC); // 跳过读序号列号的操作
	WriteOneChar(0x44); // 启动温度转换
	Init_DS18B20();
	WriteOneChar(0xCC); //跳过读序号列号的操作
	WriteOneChar(0xBE); //读取温度寄存器
	a=ReadOneChar();   //连续读两个字节数据   //读低8位 
	b=ReadOneChar();                          //读高8位
	t=b;
	t<<=8;
	t=t|a; 			//两字节合成一个整型变量。
	tt=t*0.0625;  	//得到真实十进制温度值,因为DS18B20可以精确到0.0625度,所以读回数据的最低位代表的是0.0625度
	t= tt*10+0.5; 	//放大十倍,这样做的目的将小数点后第一位也转换为可显示数字,同时进行一个四舍五入操作。
	return(t);
}

void display()
{
	uint num;                   //定义的时候用uchar宏定义就会出错
	uint shi,ge,xiaoshu;	    //这里的num,shi,ge,xiaoshu 必须用uint无符号整数来表示,用uchar字符型则显示错误
	num=Readtemp();
	shi=num/100; 	ge=num/10%10; 	xiaoshu=num%10;	  //
	write_com(0x80+0x40+0xa);	write_date(wendu[shi]);
	write_com(0x80+0x40+0xb);	write_date(wendu[ge]);
	write_com(0x80+0x40+0xc); 	write_date(0x2e);
	write_com(0x80+0x40+0xd);	write_date(wendu[xiaoshu]);	
	write_com(0x80+0x40+0xe); 	write_date(0xdf);
	write_com(0x80+0x40+0xf); 	write_date(0x43); 
}		 	
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值