51单片机 万年历
扫描二维码
随时随地手机看文章
这个小项目自己做了5天,小有成就感。。。感谢前辈们多多提意见。。
12864液晶、DS12C887时钟芯片、DS18B20温度传感器。。。
#define uchar unsigned char
#define uint unsigned int
uint temp;
float f_temp;
sbit Ds=P2^2;
sbit Dula=P2^6;
sbit Wela=P2^7;
sbit LcdCS=P3^5; //寄存器选择输入 通过rs确定是写数据还是写命令
sbit LcdSID=P3^6; //液晶读/写控制 因为不从液晶读取任何数据,所以rw一直为0
sbit LcdSCLK=P3^4; //液晶使能控制 给en一个高脉冲将数据送入液晶控制器
sbit LcdPSB=P3^7; //串并方式控制
sbit DSCS=P1^4; //片选信号,低电平有效
sbit DSAS=P1^5; //地址选通输入端 AS的上升沿将AD0~AD7上出现的地址信息锁存到DS12C887上,下降沿清除地址信息
sbit DSRW=P1^6; //
sbit DSDS=P1^7; //
uchar code table1[]={" CHPAVC 天若海愚"};
uchar code table3[]={"星期一"};
uchar code table4[]={"星期二"};
uchar code table5[]={"星期三"};
uchar code table6[]={"星期四"};
uchar code table7[]={"星期五"};
uchar code table8[]={"星期六"};
uchar code table9[]={"星期日"};
uchar code table10[]={"°C"};
uchar buff[4];
char year,month,day,week,miao,fen,shi;
uchar nyrsfm[17]; //Write_nyrsfm函数中,方法二nyrsfm只需申明成nyrsfm[16]
/***************************************************************
文件名称: wannianli
作者 : 天若海愚
版本号 : V1.0
说明 :
创建时间: 2013年9月17日13:30:38
修改记录: 无
备注 : 在12864液晶屏上显示从DS12C887采集到的年、月、日、时、分数据,并且利用DS18B20采集温度显示在12864上
***************************************************************/
#include
#include
#include
#include
/***********************************
函数名称: Delay()
函数功能: 延时
入口参数: z
备注 :
***********************************/
void Delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/**********************************
函数名称: Ds_reset()
函数功能: DS18B20复位,初始化函数
入口参数: 无
备注 :
**********************************/
void Ds_reset()
{
uint i;
Ds=1; //书P348,时序图,先将数据线置高电平1
_nop_(); //延时,尽可能短一点
Ds=0;
i=103;
while(i>0)
i--; //当总线停留在低电平超过480us,总线上所以器件都将被复位,这里
//延时约680us总线停留在低电平超过480μs,总线上的所有器件都将被复位
_nop_(); //延时,尽可能短一点
Ds=1;
i=5;
while(i>0)
i--; //释放总线后,如果初始化成功则在15~60us内产生一个由DDS18B20返回的低电平0,据
//该状态可以确定它的存在,但是不能无限制地等
}
/**********************************
函数名称: Ds_read_bit()
函数功能: 读一位数据函数
入口参数: 无
备注 :
**********************************/
bit Ds_read_bit()
{
uint i;
bit dat;
Ds=0; //单片机(微处理器)将总线拉低
_nop_(); //读时隙起始于微处理器将总线拉低至少1us
Ds=1; //拉低总线后接着释放总线,让从机18b20能够接管总线,输出有效数据
_nop_();
_nop_(); //小延时一下,读取18b20上的数据 ,因为从ds18b20上输出的数据,在读"时间隙"下降沿出现15us内有效
dat=Ds; //主机读从机18b20输出的数据,这些数据在读时隙的下降沿出现15us内有效
i=10;
while(i>0)
i--; //所有读"时间隙"必须60~120us,这里77us
return(dat);
}
/**********************************
函数名称: Ds_read_byte()
函数功能: 读一个字节数据函数
入口参数: 无
备注 :
**********************************/
uchar Ds_read_byte()
{
uchar i,j,dat;
dat=0; //初值不能忘
for(i=1;i<=8;i++) //此句曾写成for(i=0;i<=8;i++),导致程序显示结果出错,细节。。。
{
j=Ds_read_bit();
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在dat里
}
return(dat);
}
/**********************************
函数名称: Ds_write_byte()
函数功能: 向DS18B20写一个字节函数
入口参数:
备注 :
**********************************/
void Ds_write_byte(uchar dat)
{
uchar i;
uint j;
bit testb;
for(i=1;i<=8;i++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb)
{
Ds=0;
_nop_();
_nop_(); //看时序图,至少延时1us,才产生写"时间隙"
Ds=1; //写时间隙开始后的15μs内允许数据线拉到高电平
j=8;
while(j>0)
j--; //所有写时间隙必须最少持续60us
}
else
{
Ds=0;
j=8;
while(j>0)
j--; //主机要生成一个写0 时间隙,必须把数据线拉到低电平并保持至少60μs,
Ds=1;
_nop_();
_nop_();
}
}
}
/**********************************
函数名称: Ds_change()
函数功能: 18b20开始获取温度并转换
入口参数:
备注 :
**********************************/
void Ds_change()
{
Ds_reset(); //初始化
Delay(1);
Ds_write_byte(0xcc); //跳过ROM.直接向18b20发温度 转换指令,适用于一个从机工作
Ds_write_byte(0x44); //写温度转换指令
}
/**********************************
函数名称: Get_temp()
函数功能: 读取寄存器中存储的温度数
入口参数: 无
备注 :
**********************************/
uint Get_temp()
{
uchar a,b;
Ds_reset();
Delay(1);
Ds_write_byte(0xcc); //写跳过读ROM指令
Ds_write_byte(0xbe); //读暂存器。读内部RAM中9字节的温度数据
a=Ds_read_byte(); //读低8位
b=Ds_read_byte(); //读高8位
temp=b;
temp<<=8; //两个字节组合为一个字
temp=temp|a;
f_temp=temp*0.0625; //得到真实十进制温度值,因为DS18B20可以精确到0.0625 度,所以读回数据的最低位代表的是0.0625 度。
temp=f_temp*10+0.5; //乘以10不是小数点后面只取1位,加0.5是四舍五入
f_temp=f_temp+0.05;
return temp; //temp是整型
}
/**********************************
函数名称: init_com()
函数功能: 串口初始化
入口参数: 无
备注 :
**********************************/
void init_com()
{
TMOD=0x20; //定时器1,方式2
PCON=0x00;
SCON=0x50; //等价于REN=1;SM0=0;SM1=1;
TH1=0xFD;
TL1=0xFD; //设置波特率 9600
TR1=1; //启动定时器1
}
/**********************************
函数名称: comm()
函数功能: 串口发送数据
入口参数:
备注 :
**********************************/
void comm(uchar *parr)
{
do
{
SBUF=*parr++;
while(!TI);