⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 基于51单片机和ds12887的电子.txt

📁 很不错的
💻 TXT
字号:
//基于51单片机和ds12887的电子
//==========直接上代码吧 

//===============LCD12887_1.C 主文件 
/*--------------------------------------------------------------*/ 
//包含头文件 
#include<AT89X52.H> 
#include"LCD1602_8.H" 
#include"DS12887_1.H" 


/*--------------------------------------------------------------*/ 
unsigned char k; //键值 
unsigned char Set; //调整值 


/*--------------------------------------------------------------*/ 
//延时200ms 函数定义 
void delay200ms(void) 
{ 
unsigned char i,j,k; 
for(i=201;i>0;i--) 
for(j=32;j>0;j--) 
for(k=14;k>0;k--); 
} 


/*--------------------------------------------------------------*/ 
//延时5000+0us 函数定义 
void delay5ms(void) 
{ 
unsigned char i,j; 
for(i=185;i>0;i--) 
for(j=12;j>0;j--); 
} 


/*--------------------------------------------------------------*/ 
//键盘扫描 
void Keysan(void) //P0_0切换键,P0_1数值加,P0_1数值减 
{ 
if(P0_0 == 0) 
{ 
delay5ms(); 
if(P0_0 == 0) k++; 
if(k == 7) k = 0; 
} 
if(P0_1 == 0) {delay5ms(); if(P0_1 == 0) Set++;} 
if(P0_2 == 0) {delay5ms(); if(P0_2 == 0) Set--;} 
switch(k) 
{ 
case 0: DS12887_SetTime(DS12887_Second, Set); if(Set > 59 || Set < 0) Set = 0; break; 
case 1: DS12887_SetTime(DS12887_Minute, Set); if(Set > 59 || Set < 0) Set = 0; break; 
case 2: DS12887_SetTime(DS12887_Hour , Set); if(Set > 24 || Set < 0) Set = 0; break; 
case 3: DS12887_SetTime(DS12887_Day , Set); if(Set > 31 || Set < 0) Set = 0; break; 
case 4: DS12887_SetTime(DS12887_Month , Set); if(Set > 12 || Set < 0) Set = 0; break; 
case 5: DS12887_SetTime(DS12887_Year , Set);break; 
default: break; 
} 
} 

/*--------------------------------------------------------------*/ 
//主函数 
void main(void) 
{ 

SYSTEMTIME CurrentTime; 
lcd_init(); 
DS12887_Init(); 

lcd_pos(0,0); 
prints("Date:"); 
lcd_pos(0,1); 
prints("Time:"); 
k = 6; //不改变时间 
while(1) 
{ 
DS12887_GetTime(&CurrentTime); 
DateToStr(&CurrentTime); 
TimeToStr(&CurrentTime); 
lcd_pos(6,0); 
prints(CurrentTime.DateString); 
lcd_pos(6,1); 
prints(CurrentTime.TimeString); 
delay200ms(); 
Keysan(); 
} 
} 

//=======================包含文件1 LCD1602_8.H 
/*--------------------------------------------------------------*/ 
//包含头文件 
#include<AT89X52.H> 
#include"LCD1602_8.H" 
#include"DS12887_1.H" 


/*--------------------------------------------------------------*/ 
unsigned char k; //键值 
unsigned char Set; //调整值 


/*--------------------------------------------------------------*/ 
//延时200ms 函数定义 
void delay200ms(void) 
{ 
unsigned char i,j,k; 
for(i=201;i>0;i--) 
for(j=32;j>0;j--) 
for(k=14;k>0;k--); 
} 


/*--------------------------------------------------------------*/ 
//延时5000+0us 函数定义 
void delay5ms(void) 
{ 
unsigned char i,j; 
for(i=185;i>0;i--) 
for(j=12;j>0;j--); 
} 


/*--------------------------------------------------------------*/ 
//键盘扫描 
void Keysan(void) //P0_0切换键,P0_1数值加,P0_1数值减 
{ 
if(P0_0 == 0) 
{ 
delay5ms(); 
if(P0_0 == 0) k++; 
if(k == 7) k = 0; 
} 
if(P0_1 == 0) {delay5ms(); if(P0_1 == 0) Set++;} 
if(P0_2 == 0) {delay5ms(); if(P0_2 == 0) Set--;} 
switch(k) 
{ 
case 0: DS12887_SetTime(DS12887_Second, Set); if(Set > 59 || Set < 0) Set = 0; break; 
case 1: DS12887_SetTime(DS12887_Minute, Set); if(Set > 59 || Set < 0) Set = 0; break; 
case 2: DS12887_SetTime(DS12887_Hour , Set); if(Set > 24 || Set < 0) Set = 0; break; 
case 3: DS12887_SetTime(DS12887_Day , Set); if(Set > 31 || Set < 0) Set = 0; break; 
case 4: DS12887_SetTime(DS12887_Month , Set); if(Set > 12 || Set < 0) Set = 0; break; 
case 5: DS12887_SetTime(DS12887_Year , Set);break; 
default: break; 
} 
} 

/*--------------------------------------------------------------*/ 
//主函数 
void main(void) 
{ 

SYSTEMTIME CurrentTime; 
lcd_init(); 
DS12887_Init(); 

lcd_pos(0,0); 
prints("Date:"); 
lcd_pos(0,1); 
prints("Time:"); 
k = 6; //不改变时间 
while(1) 
{ 
DS12887_GetTime(&CurrentTime); 
DateToStr(&CurrentTime); 
TimeToStr(&CurrentTime); 
lcd_pos(6,0); 
prints(CurrentTime.DateString); 
lcd_pos(6,1); 
prints(CurrentTime.TimeString); 
delay200ms(); 
Keysan(); 
} 
} 

//================================ 包含文件2 DS12887_1.H 
/*--------------------------------------------------------------*/ 
//File: DS12887驱动程序 
//Date: 08-10-20 ~ 10-23 
//Time: 21:20 ~ 16:53 
//Source: Web 


/*--------------------------------------------------------------*/ 
#ifndef __DS12887_1_H__ 
#define __DS12887_1_H__ 


/*--------------------------------------------------------------*/ 
//接口定义 
sbit DS_AS = P3^0; //地址选择 
sbit DS_RW = P3^1; //读写选择 
sbit DS_DS = P3^2; //数据选择 
sbit DS_IRQ = P3^3; //中断,低电平有效,通过读出0x0c来清除信号 
sfr DS_DAT = 0x90; //8位数据线P1口 


/*--------------------------------------------------------------*/ 
//数据地址定义 
#define DS12887_Second 0x00 //秒 
#define DS12887_Minute 0x02 //分 
#define DS12887_Hour 0x04 //时 
#define DS12887_Week 0x06 //星期 
#define DS12887_Day 0x07 //日 
#define DS12887_Month 0x08 //月 
#define DS12887_Year 0x09 //年 


/*--------------------------------------------------------------*/ 
//定义时间类型 
typedef struct _SYSTEMTIME_ 
{ 
unsigned char Second; 
unsigned char Minute; 
unsigned char Hour; 
unsigned char Week; 
unsigned char Day; 
unsigned char Month; 
unsigned char Year; 
unsigned char DateString[9]; 
unsigned char TimeString[9]; 
}SYSTEMTIME; 


/*--------------------------------------------------------------*/ 
//函数声明 
void DS12887_Init(void); //DS12887初始化 
void DS12887_Write(unsigned char Address, unsigned char Value); //DS12887指定地址写入数据 
unsigned char DS12887_Read(unsigned char Address); //DS12887指定地址中读出数据 
void DS12887_SetTime(unsigned char Address, unsigned char Value); //设置时间函数 
void DS12887_GetTime(SYSTEMTIME *Time); //读出时间 
void DateToStr(SYSTEMTIME *Time); //日期转化成字符 
void TimeToStr(SYSTEMTIME *Time); //时间转化成字符 


/*--------------------------------------------------------------*/ 
//DS12887指定地址写入数据 
void DS12887_Write(unsigned char Address, unsigned char Value) 
{ 
DS_AS = 0; 
DS_DS = 1; 
DS_RW = 1; 
DS_AS = 1; 
DS_DAT= Address; 
DS_AS = 0; 
DS_RW = 0; 
DS_DAT= Value; 
DS_RW = 1; 
DS_AS = 1; 
} 


/*--------------------------------------------------------------*/ 
//DS12887指定地址中读出数据 
unsigned char DS12887_Read(unsigned char Address) 
{ 
unsigned char DS_RDAT; 
DS_AS = 0; 
DS_DS = 1; 
DS_RW = 1; 
DS_AS = 1; 
DS_DAT= Address; 
DS_AS = 0; 
DS_DS = 0; 
DS_DAT=0xff; 
DS_RDAT = DS_DAT; 
DS_DS = 1; 
DS_AS = 1; 
return (DS_RDAT); 
} 


/*--------------------------------------------------------------*/ 
//DS12887初始化 
void DS12887_Init(void) 
{ 
DS12887_Write(0x0a, 0x20); //启动DS12887 
DS12887_Write(0x0b, 0x86); //禁止更新,接下来初始化数据,即写入时间,日期等 
DS12887_Write(0x0b, 0x06); //正常更新,二进制格式,24进制小时 
} 


/*--------------------------------------------------------------*/ 
//设置时间函数 
void DS12887_SetTime(unsigned char Address, unsigned char Value) 
{ 
DS12887_Write(0x0b, 0x86); //禁止更新,接下来初始化数据,即写入时间,日期等 
DS12887_Write(Address,Value); 
DS12887_Write(0x0b, 0x06); //正常更新,二进制格式,24进制小时 
} 


/*--------------------------------------------------------------*/ 
//读出时间 
void DS12887_GetTime(SYSTEMTIME *Time) 
{ 
Time->Second = DS12887_Read(DS12887_Second); 
Time->Minute = DS12887_Read(DS12887_Minute); 
Time->Hour = DS12887_Read(DS12887_Hour ); 
Time->Day = DS12887_Read(DS12887_Day ); 
Time->Week = DS12887_Read(DS12887_Week ); 
Time->Month = DS12887_Read(DS12887_Month ); 
Time->Year = DS12887_Read(DS12887_Year ); 
} 


/*--------------------------------------------------------------*/ 
//日期转化成字符 
void DateToStr(SYSTEMTIME *Time) 
{ 
Time->DateString[0] = Time->Year/10 + '0'; 
Time->DateString[1] = Time->Year%10 + '0'; 
Time->DateString[2] = '-'; 
Time->DateString[3] = Time->Month/10 + '0'; 
Time->DateString[4] = Time->Month%10 + '0'; 
Time->DateString[5] = '-'; 
Time->DateString[6] = Time->Day/10 + '0'; 
Time->DateString[7] = Time->Day%10 + '0'; 
Time->DateString[8] = '\0'; 
} 


/*--------------------------------------------------------------*/ 
//时间转化成字符 
void TimeToStr(SYSTEMTIME *Time) 
{ 
Time->TimeString[0] = Time->Hour/10 + '0'; 
Time->TimeString[1] = Time->Hour%10 + '0'; 
Time->TimeString[2] = ':'; 
Time->TimeString[3] = Time->Minute/10 + '0'; 
Time->TimeString[4] = Time->Minute%10 + '0'; 
Time->TimeString[5] = ':'; 
Time->TimeString[6] = Time->Second/10 + '0'; 
Time->TimeString[7] = Time->Second%10 + '0'; 
Time->TimeString[8] = '\0'; 
} 


/*--------------------------------------------------------------*/ 
#endif 

/*--------------------------------------------------------------*/
//File: LCD1602_8.H
//Date: 08-7-29
//Time: 16:09
//Note: LCD1602 Mini Driver. 


/*--------------------------------------------------------------*/
#ifndef __LCD1602_8_H__
#define __LCD1602_8_H__
#include <intrins.h>


/*--------------------------------------------------------------*/
//LCD接口定义     
sfr   io = 0xA0;    //P0-0x80,P1-0x90,P2-0xA0,P3-0xB0;
sbit  rs = P3^4;    //LCD数据/命令选择端(H/L)
sbit  rw = P3^5;    //LCD读/写选择端(H/L)
sbit  ep = P3^6;    //LCD使能控制
sbit     bz = io^7;    //LCD忙标志位


/*--------------------------------------------------------------*/
//函数声明  
void lcd_busy(void);     //测试LCD忙碌状态程序
void lcd_wcmd(unsigned char cmd);  //写入指令到LCD程序
void lcd_wdat(unsigned char dat);  //写入数据到LCD程序
void lcd_pos (unsigned char x, bit y); //LCD数据指针位置程序
//void printc(unsigned char CHAR);  //显示字符
void prints(unsigned char *string);  //显示字符串
void lcd_init(void);     //LCD初始化设定程序


/*--------------------------------------------------------------*/
//测试LCD忙碌状态
void lcd_busy(void)
{ 
 do{
  ep = 0;
  rs = 0;  //指令
  rw = 1;  //读出
  io = 0xff;
  ep = 1;
  _nop_(); //高电平读出 1us 
 }while(bz);  //bz=1表示忙,bz=0表示空闲
 ep = 0;  
}


/*--------------------------------------------------------------*/
//写入指令到LCD
void lcd_wcmd(unsigned char cmd)
{       
 lcd_busy(); //检测忙
 rs = 0;  //指令
 rw = 0;  //写入
 ep = 1; 
 io = cmd; //指令
 ep = 0;  //下降沿有效 
}


/*--------------------------------------------------------------*/
//写入数据函数
void lcd_wdat(unsigned char Data)
{
 lcd_busy();  //检测忙
 rs = 1;   //数据
 rw = 0;   //写入
 ep = 1;
 io = Data;  //数据
 ep = 0;   //下降沿有效
}


/*--------------------------------------------------------------*/
//LCD数据指针位置程序
void lcd_pos(unsigned char x, bit y)
{      
 if(y)lcd_wcmd(x|0xc0); //y=1,第二行显示;y=0,第一行显示  0<=x<16
 else lcd_wcmd(x|0x80); //数据指针=80+地址码(00H~27H,40H~67H)
}


/*--------------------------------------------------------------*/
//显示字符
/*
void printc(unsigned char CHAR)
{
 lcd_wdat(CHAR);
}
*/


/*--------------------------------------------------------------*/
//显示字符串
void prints(unsigned char *string)
{
 while(*string) {lcd_wdat(*string);string++;}
}


/*--------------------------------------------------------------*/
//LCD初始化设定
void lcd_init()
{      
 lcd_wcmd(0x38);  //设置LCD为16X2显示,5X7点阵,八位数据接口
 lcd_wcmd(0x06);  //LCD显示光标移动设置(光标地址指针加1,整屏显示不移动)
 lcd_wcmd(0x0c);  //LCD开显示及光标设置(光标不闪烁,不显示"_")
 lcd_wcmd(0x01);  //清除LCD的显示内容
}


/*--------------------------------------------------------------*/
#endif


以下是相应的说明: 
8根并行数据线+三根控制信号线~就可以咯~ 


按键接法(按键的另一条腿接到GND上):
P0_0切换键,
P0_1数值加,
P0_1数值减 

时钟日历管脚接法: 
sbit DS_AS = P3^0; //地址选择 
sbit DS_RW = P3^1; //读写选择 
sbit DS_DS = P3^2; //数据选择 
sbit DS_IRQ = P3^3; //中断,低电平有效,通过读出0x0c来清除信号 
sfr DS_DAT = 0x90; //8位数据线P1口                       


液晶管脚接法:
sfr   io = 0xA0;    //液晶数据口 P2-0xA0;     --D0-D7
sbit  rs = P3^4;    //LCD数据/命令选择端(H/L) --RS / DI
sbit  rw = P3^5;    //LCD读/写选择端(H/L)     --RW
sbit  ep = P3^6;    //LCD使能控制             --EN
sbit     bz = io^7;    //LCD忙标志位(不用再接)

DS12887的RST接在VCC, CS接在GND, IRQ不用管, MOT悬空即可~也即选择默认的Intel 工作方式。 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -