本程序是基于AT89C51单片机+DS1302时钟芯片+DS18B20测温传感器+LCD1602液晶屏可调的电子时钟程序!
程序是上学期写好的,电路图还没画,现在拿出来跟大家分享一下,有什么可以改进的地方还请大家多多指点!
/*******************************************************************************
*标题: DS1302+DS18B20+LCD1602可调带闹铃的电子时钟 *
* *
********************************************************************************
*接线:JP8接JP5、蜂鸣器短路帽的左端接到P2^1(用一根杜邦线) *
*用杜邦线把P2^0连到led灯上(任意一个) *
*说明:本实验是在普中科技单片机开发板HC6800EM3上实现的 *
********************************************************************************/
#include
#include
#define uchar unsigned char
#define uint unsigned int
***it SCK=P3^6; //时钟
***it SDA=P3^4; //数据
***it RST=P3^5; // DS1302复位
***it lcdrs=P2^7;
***it lcdrw=P2^6;
***it lcden=P2^5;
***it key1=P1^0; //开调时键
***it key2=P1^1; //调时加键
***it key3=P1^2; //调时减键
***it key4=P1^3; //开设定闹铃键
***it key5=P1^4; //返回正常显示键
***it key6=P1^5; //闹铃开关键
***it DQ=P3^7; //温度传感器数据通信位
***it beep = P2^1; //蜂鸣器控制IO口
***it led1 = P2^0; //led灯,闹铃响标志
bit ReadRTC_Flag,Display_Flag,Alarm_Flag,flag; //定义标志位
uchar miao,fen,shi,ri,yue,week,nian,T,C=0,k=0,m=0,n=0;
uchar set_miao,set_fen,set_shi,set_ri,set_yue,set_nian,TempBuffer[5],temp_value;
char l_tmpdate[7]={0x50,0x08,0x011,0x07,0x10,0x01,0x12};//设置初始时间,秒分时日月周年12-10-07 01:08:50
uchar code write_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分时日月周年 最低位写位
uchar code read_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; //秒分时日月周年 最低位读位
uchar code table1[]="SUN"; //星期字表
uchar code table2[]="MON";
uchar code table3[]="TUE";
uchar code table4[]="WED";
uchar code table5[]="THU";
uchar code table6[]="FRI";
uchar code table7[]="SAT";
uchar code tab1[]="20 - - ";
uchar code tab2[]=" : :";
uchar code tab3[14]=" Set Alarm! ";
char tab4[]={0,0,12};
/******************************************************************/
/* 函数声明 */
/******************************************************************/
void Init_DS18B20(void);
unsigned char ReadOneChar(void);
void WriteOneChar(uchar dat);
void ReadTemp(void);
void temp_to_str(); //温度数据转换成液晶字符显示
void Write_Ds1302_byte(uchar temp);
void Write_Ds1302( uchar address,uchar dat );
uchar Read_Ds1302 ( uchar address );
void Read_RTC(void);
void Set_RTC(void);
void delay(uchar a);
void delay1(uchar a);
void di();
void lcd_mang();
void write_lcd1602(uchar cmd,uchar i);
void ini_lcd1602();
void write_week(uchar xq);
void write_nyr(uchar add,uchar dat);
void write_sfm(uchar add,uchar dat);
void display();
void keyscan();
void alarm();
/******************************************************************/
/* 主函数 */
/******************************************************************/
void main(void)
{
ini_lcd1602();
Init_DS18B20();
Set_RTC(); //写入时钟值,如果使用备用电池时候,不需要没每次上电写入,此程序应该屏蔽
while(1)
{
ReadTemp();
temp_to_str();
keyscan();
if(ReadRTC_Flag==0)
{
Read_RTC();
if(Display_Flag==0)
{
display();
}
if(flag==1)
{
alarm();
}
}
}
}
/******************************************************************/
/* 毫秒级延时函数 */
/******************************************************************/
void delay(uchar a)
{
uchar i;
while(a--)
{
for(i=0;i<250;i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
void delay1(uchar a)
{
uchar i;
while(a--)
{
for(i=0;i<5;i++)
{}
}
}
/******************************************************************/
/* 蜂鸣器发声函数 */
/******************************************************************/
void di()
{
uchar i;
while(key1==0||key2==0||key3==0||key4==0||key5==0||key6==0)
{
for(i=0;i<50;i++)
{
delay1(4);
beep=~beep;
}
}
}
/******************************************************************/
/* ds18b20延迟子函数(晶振12MHz) */
/******************************************************************/
void delay_18B20(unsigned int i)
{
while(i--);
}
/******************************************************************/
/* ds18b20初始化函数 */
/******************************************************************/
void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ复位
delay_18B20(8); //稍做延时
DQ = 0; //单片机将DQ拉低
delay_18B20(80); //精确延时 大于 480us
DQ = 1; //拉高总线
delay_18B20(14);
x = DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay_18B20(20);
DQ = 1;
}
/******************************************************************/
/* ds18b20读一个字节 */
/******************************************************************/
unsigned char ReadOneChar(void)
{
uchar i=0;
uchar dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
delay_18B20(4);
}
return(dat);
}
/******************************************************************/
/* ds18b20写一个字节 */
/******************************************************************/
void WriteOneChar(uchar dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay_18B20(5);
DQ = 1;
dat>>=1;
}
}
/******************************************************************/
/* 读取ds18b20当前温度 */
/******************************************************************/
void ReadTemp(void)
{
unsigned char a=0;
unsigned char b=0;
unsigned char t=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
delay_18B20(100); // this message is wery important
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
delay_18B20(100);
a=ReadOneChar(); //读取温度值低位
b=ReadOneChar(); //读取温度值高位
temp_value=b<<4;
temp_value+=(a&0xf0)>>4;
}
/******************************************************************/
/* 温度数据转换 */
/******************************************************************/
void temp_to_str() //温度数据转换成液晶字符显示
{
TempBuffer[0]=temp_value/10+'0'; //十位
TempBuffer[1]=temp_value%10+'0'; //个位
//TempBuffer[2]=0xdf; //温度符号
//TempBuffer[3]='C';
//TempBuffer[4]=' |