这是DS1602+DS1302完整程序,其中P1口接独立键盘。
DS1602部分:
# include "SYSTEM.H"
//#ifndef __LCD1602_8_H__
//#define __LCD1602_8_H__
//LCD接口定义
sfr io = 0x80; //P0-0x80,P1-0x90,P2-0xA0,P3-0xB0;
sbit rs = P2^6; //LCD数据/命令选择端(H/L)
sbit rw = P2^5; //LCD读/写选择端(H/L)
sbit ep = P2^7; //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 lcd_sef_chr();
//void printc(unsigned char CHAR); //显示字符
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)
{
//unsigned char i;
//do{lcd_wdat(string[i]);i++;}while(string[i]!='\0');//生成代码比for循环大
for(i=0;string[i]!='\0';i++)lcd_wdat(string[i]); //有时用for循环也好哈//
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的显示内容
}
DS1302部分:
# include "SYSTEM.H"
//#ifndef __DS1302_A_H__
//#define __DS1302_A_H__
//引脚及位的定义
sbit DS1302_CLK = P3^6; //时钟引脚
sbit DS1302_IO = P3^4; //数据引脚
sbit DS1302_RST = P3^5; //复位引脚
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
//函数声明
void DS1302_InputByte(unchar Data); //写入一个字节(内部函数)
unchar DS1302_OutputByte(void); //读取一个字节(内部函数)
void Write1302(unchar Address, unchar Data); //在指定地址写入指定的数据
unchar Read1302(unchar Address); //读取DS1302指定地址中的数据
void DS1302_SetProtect(bit Flag); //DS1302是否写入保护
void DS1302_SetTime(unchar Address, unchar Value);//设置时间函数
void DS1302_GetTime(SYSTEMTIME *Time); //读出时间
void DateToStr(SYSTEMTIME *Time); //日期转化成字符
void TimeToStr(SYSTEMTIME *Time); //时间转化成字符
void DS1302_Initial (void); //DS1302初始化
//写入一个字节(内部函数)
void DS1302_InputByte(unchar Data)
{
unchar i;
ACC = Data;
for(i=8; i>0; i--)
{
DS1302_CLK = 0;
DS1302_IO = ACC0; //由低位到高位
DS1302_CLK = 1; //上升沿写入数据
ACC >>= 1;
}
}
//读取一个字节(内部函数)
unchar DS1302_OutputByte(void)
{
unchar i;
for(i=8; i>0; i--)
{
DS1302_CLK = 0; //下降沿读出DS1302的数据
ACC >>= 1; //读出由低到高位,只能移7次有效位!!!
ACC7 = DS1302_IO; //第一个数据
DS1302_CLK = 1;
}
return (ACC);
}
//在指定地址写入指定的数据
void Write1302(unchar Address, unchar Data)
{
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302_InputByte(Address);
DS1302_InputByte(Data);
DS1302_CLK = 1;
DS1302_RST = 0;
}
//读取1302指定地址中的数据
unchar Read1302(unchar Address)
{
unchar Data;
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1; //RST拉高,启动数据传送
DS1302_InputByte(Address|0x01);//读取指定地址数据指令
Data = DS1302_OutputByte();
DS1302_CLK = 1;
DS1302_RST = 0;
return (Data);
}
//是否写入保护
void DS1302_SetProtect(bit Flag)
{
if(Flag)
Write1302(0x8E,0x80); //0x8e控制字节地址,bit7=WP WP=1 禁止数据写入DS1302
else
Write1302(0x8E,0x00); //WP=0 允许数据写入DS1302
}
//设置时间函数
void DS1302_SetTime(unchar Address, unchar Value)
{
DS1302_SetProtect(0);
Write1302(Address,((Value/10)<<4|(Value)));
DS1302_SetProtect(1);
}
//读出时间
void DS1302_GetTime(SYSTEMTIME *Time)
{
unchar ReadValue;
ReadValue = Read1302(DS1302_SECOND);
Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
ReadValue = Read1302(DS1302_MINUTE);
Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
ReadValue = Read1302(DS1302_HOUR);
Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
ReadValue = Read1302(DS1302_DAY);
Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
ReadValue = Read1302(DS1302_WEEK);
Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
ReadValue = Read1302(DS1302_MONTH);
Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
ReadValue = Read1302(DS1302_YEAR);
Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
}
//日期转化成字符
void DateToStr(SYSTEMTIME *Time)
{
Time->DateString[0] = Time->Year/10 + '0';
Time->DateString[1] = Time->Year + '0';
Time->DateString[2] = '-';
Time->DateString[3] = Time->Month/10 + '0';
Time->DateString[4] = Time->Month + '0';
Time->DateString[5] = '-';
Time->DateString[6] = Time->Day/10 + '0';
Time->DateString[7] = Time->Day + '0';
Time->DateString[8] = '\0';
}
//时间转化成字符
void TimeToStr(SYSTEMTIME *Time)
{
Time->TimeString[0] = Time->Hour/10 + '0';
Time->TimeString[1] = Time->Hour + '0';
Time->TimeString[2] = ':';
Time->TimeString[3] = Time->Minute/10 + '0';
Time->TimeString[4] = Time->Minute + '0';
Time->TimeString[5] = ':';
Time->TimeString[6] = Time->Second/10 + '0';
Time->TimeString[7] = Time->Second + '0';
Time->TimeString[8] = '\0';
}
//初始化DS1302
void DS1302_Initial (void)
{
unchar Second=Read1302(DS1302_SECOND);
if(Second&0x80)//bit7=CH CH=0 振荡器允许工作,CH=1振荡器停止工作
DS1302_SetTime(DS1302_SECOND,0);
}
函数声明SYSTEM.H:
//包含头文件
#include
#include
//#include"LCD1602_8.H"
//#include"DS1302_A.H"
//P0 Bit Registers
sbit P0_0 = 0x80;
sbit P0_1 = 0x81;
sbit P0_2 = 0x82;
sbit P0_3 = 0x83;
sbit P0_4 = 0x84;
sbit P0_5 = 0x85;
sbit P0_6 = 0x86;
sbit P0_7 = 0x87;
//P1 Bit Registers
sbit P1_0 = 0x90;
sbit P1_1 = 0x91;
sbit P1_2 = 0x92;
sbit P1_3 = 0x93;
sbit P1_4 = 0x94;
sbit P1_5 = 0x95;
sbit P1_6 = 0x96;
sbit P1_7 = 0x97;
//P2 Bit Registers
sbit P2_0 = 0xA0;
sbit P2_1 = 0xA1;
sbit P2_2 = 0xA2;
sbit P2_3 = 0xA3;
sbit P2_4 = 0xA4;
sbit P2_5 = 0xA5;
sbit P2_6 = 0xA6;
sbit P2_7 = 0xA7;
//P3 Bit Registers (Mnemonics & Ports)
sbit P3_0 = 0xB0;
sbit P3_1 = 0xB1;
sbit P3_2 = 0xB2;
sbit P3_3 = 0xB3;
sbit P3_4 = 0xB4;
sbit P3_5 = 0xB5;
sbit P3_6 = 0xB6;
sbit P3_7 = 0xB7;
//宏定义便于理解
#define unchar unsigned char
#define unint unsigned int
#define DS1302_SECOND 0x80
#define DS1302_MINUTE 0x82
#define DS1302_HOUR 0x84
#define DS1302_WEEK 0x8A
#define DS1302_DAY 0x86
#define DS1302_MONTH 0x88
#define DS1302_YEAR 0x8C
#define DS1302_RAM(X) (0xC0+(X)*2)
//用于计算RAM地址的宏运算
//定义时间类型
typedef struct _SYSTEMTIME_
{
unchar Second;
unchar Minute;
unchar Hour;
unchar Week;
unchar Day;
unchar Month;
unchar Year;
unchar DateString[9];
unchar TimeString[9];
}SYSTEMTIME;
//LCD1602外部引用函数
extern void lcd_init(void); //LCD初始化设定程序
extern void prints(unsigned char *string); //显示字符串
extern void lcd_pos (unsigned char x, bit y); //LCD数据指针位置程序
extern void lcd_sef_chr() ;
extern void lcd_wcmd(unsigned char cmd);//写入指令到LCD程序
//*DS1302外部引用函数
extern void DS1302_SetTime(unchar Address, unchar Value); //设置时间函数
extern void DS1302_Initial (void); //DS1302初始化
extern void DS1302_GetTime(SYSTEMTIME *Time); //读出时间
extern void DateToStr(SYSTEMTIME *Time); //日期转化成字符
extern void TimeToStr(SYSTEMTIME *Time); //时间转化成字符
MAIN函数部分:
#include "SYSTEM.H"
SYSTEMTIME CurrentTime;
unsigned char k = 0; //键值
unsigned char K1,K2,K3,M1,M2,M3,K1J,K2J,K3J,K4J; //键值
unsigned char Set; //调整值
char Set_Mode = 0;
void Keysan(void);
void delay200ms(void);
//主函数
void main(void)
{
lcd_init();
//lcd_sef_chr(); //写入自定义字符号
DS1302_Initial();
lcd_pos(0,0);
prints("Date:");
lcd_pos(0,1);
prints("Time:");
k = 6; //不改变时间
while(1)
{
Keysan();
DS1302_GetTime(&CurrentTime);
DateToStr(&CurrentTime);
TimeToStr(&CurrentTime);
lcd_pos(6,0);
prints(CurrentTime.DateString);
lcd_pos(6,1);
prints(CurrentTime.TimeString);
//lcd_pos(7,0);
//lcd_wcmd(0x0E);
delay200ms();
}
}
//键盘扫描
void Keysan(void)
{
if(~P1_2&K1J) { k++; }
K1J=~(~P1_2);
if(~P1_3&K2J) { Set++; }
K2J=~(~P1_3);
if(~P1_4&K3J) { Set--; }
K3J=~(~P1_4);
if(k == 7) {k = 0; }
switch(k)
{
case 0: DS1302_SetTime(DS1302_SECOND, Set&0x3f); break;
case 1: DS1302_SetTime(DS1302_MINUTE, Set&0x3f); break;
case 2: DS1302_SetTime(DS1302_HOUR , Set&0x1f); break;
case 3: DS1302_SetTime(DS1302_DAY , Set&0x0f); break;
case 4: DS1302_SetTime(DS1302_MONTH , Set&0x0f); break;
case 5: DS1302_SetTime(DS1302_YEAR , Set&0x7f); break;
default: break;
}
}
//延时200000+0us 函数定义
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--);
}