想要更多项目私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); //精确延时 大于 480usDS = 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);
}