永发信息网

51与DS12887的程序

答案:1  悬赏:60  手机版
解决时间 2021-11-15 10:46
  • 提问者网友:伴风望海
  • 2021-11-14 21:54
51与DS12887的程序
最佳答案
  • 五星知识达人网友:轮獄道
  • 2021-11-14 22:05
//==========直接上代码吧

//===============LCD12887_1.C 主文件

//包含头文件
#include
#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
#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


//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 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 工作方式。
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯