|
不好意思,我又来了,我用4个按键调节时钟(考虑手上没有与门器件没用中断,时间不够了),代码如下,可是LCD不显示,请各位帮俺看看如何修改,问题应该出在主函数和主函数上面的子函数上了,请各位帮帮忙
#include <reg52.h>
#include <string.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit SDA=P1^0; // DS1302数据线
sbit CLK=P1^1; //DS1302时钟线
sbit RST=P1^2; //DS1302复位线
sbit RS=P2^0;
sbit RW=P2^1;
sbit EN=P2^2;
sbit K1=P3^4; // 选择
sbit K2=P3^5; // 加
sbit K3=P3^6; // 减
sbit K4=P3^7; // 确定
uchar tCount=0;
//一年中每个月的天数,2月的天数由年份决定
uchar MonthsDays[]={31,31,30,31,30,31,31,30,31,30,31};
uchar *WEEK[]={"SAT","SUN","MON","TUS","WEN","THU","FRI"};
uchar LCD_DSY_BUFFER1[]={"Date 00-00-00 "}; //LCD显示缓冲
uchar LCD_DSY_BUFFER2[]={"Time 00:00:00 "};
uchar DateTime[7]; //所读取的日期时间
char Adjust_Index=-1;
uchar Change_Flag[]="-MHDM-Y"; //当前调节的标志:分钟,小时,天,月,年
void DelayMS(uint x)
{
uchar i;
while(x--) for(i=0;i<120;i++);
}
void DS1302_Write_Byte(uchar x) //发送一个字节到DS1302通信线上
{
uchar i;
for(i=0;i<8;i++) //低位在前,移位输出
{
SDA=x&1; //输出该位数据
CLK=1; //拉高时钟
CLK=0; //拉低时钟,完成一个位的操作
x>>=1;
}
}
uchar DS1302_Read_Byte()
{
uchar i,b,t;
for(i=0;i<8;i++)
{
b>>=1;
t=SDA;
b|=t<<7;
CLK=1;
CLK=0;
}
return b/16*10+b%16;
}
uchar Read_Data(uchar addr)
{
uchar dat;
RST=0;
CLK=0;
RST=1;
DS1302_Write_Byte(addr);
dat=DS1302_Read_Byte();
CLK=1;
RST=0;
_nop_(); //以下为DS1302复位的稳定时间,必须的。
CLK = 1;
_nop_();
SDA = 0;
_nop_();
SDA = 1;
_nop_();
return dat;
}
void Write_DS1302(uchar addr,uchar dat)
{
CLK=0;
RST=1;
DS1302_Write_Byte(addr);
DS1302_Write_Byte(dat);
CLK=0;
RST=0;
}
void SET_DS1302()
{
uchar i;
Write_DS1302(0x8e,0x00);
for(i=0;i<7;i++)
{
Write_DS1302(0x80+2*i,(DateTime[i]/10<<4|(DateTime[i]%10)));
}
Write_DS1302(0x8e,0x80);
}
void GetTime()
{
uchar i;
for(i=0;i<7;i++)
{
DateTime[i]=Read_Data(0x81+2*i);
}
}
uchar Read_LCD_State()
{
uchar state;
RS=0; //命令
RW=1; //读
EN=1; //读为高电平
DelayMS(1);
state=P0;
EN=0;
DelayMS(1);
return state; //要输出
}
void LCD_Busy_Wait() //LCD1602响应速度相对于单片机来说是偏慢的
{
while((Read_LCD_State()&0x08)==0x80);
DelayMS(5);
}
void Write_LCD_Data(uchar dat) //写数据
{
LCD_Busy_Wait(); //忙检测
RS=1; //数据
RW=0; //写为低电平
EN=0; //写操作时为低电平
P0=dat;
EN=1;
DelayMS(1);
EN=0;
}
void Write_LCD_Command(uchar cmd)//写命令
{
LCD_Busy_Wait();
RS=0; //命令
RW=0; //写为低电平
EN=0; //写操作时为低电平
P0=cmd;
EN=1;
DelayMS(1);
EN=0;
}
void Init_LCD() //LCD初始化
{
Write_LCD_Command(0x38); DelayMS(1);
Write_LCD_Command(0x01); DelayMS(1);
Write_LCD_Command(0x06); DelayMS(1);
Write_LCD_Command(0x0C); DelayMS(1);
}
void Set_LCD_POS(uchar p)
{
Write_LCD_Command(p+0x80);
}
void Display_LCD_String(uchar p,uchar *s)
{
uchar i;
Set_LCD_POS(p);
for(i=0;i<16;i++)
{
Write_LCD_Data(s[i]);
DelayMS(1);
}
}
void Format_DateTime(uchar d,uchar *a)
{
a[0]=d/10+'0';a[1]=d%10+'0';
}
uchar isLeapYear(uint y)
{
return (y%4==0&&y%100!=0)||(y%400==0);
}
void DateTime_Adjust(char x)
{
switch (Adjust_Index)
{
case 6: //年
if(x== 1&&DateTime[6]<99) DateTime[6]++;
if(x==-1&&DateTime[6]>0) DateTime[6]--;
MonthsDays[2]=isLeapYear(2000+DateTime[6])? 29:28;
if(DateTime[3]>MonthsDays[DateTime[4]])
DateTime[3]=MonthsDays[DateTime[4]];
//RefreshWeekDay();
break;
case 4: //月
if(x== 1&&DateTime[4]<12) DateTime[4]++;
if(x==-1&&DateTime[4]>1) DateTime[4]--;
MonthsDays[2]=isLeapYear(2000+DateTime[6])? 29:28;
if(DateTime[3]>MonthsDays[DateTime[4]])
DateTime[3]=MonthsDays[DateTime[4]];
//RefreshWeekDay();
break;
case 3: //日
MonthsDays[2]=isLeapYear(2000+DateTime[6])? 29:28;
if(x== 1&&DateTime[3]<MonthsDays[DateTime[4]]) DateTime[3]++;
if(x==-1&&DateTime[3]>0) DateTime[3]--;
//RefreshWeekDay();
break;
case 2: //时
if(x== 1&&DateTime[2]<23) DateTime[2]++;
if(x==-1&&DateTime[2]>0) DateTime[2]--;
break;
case 1: //秒
if(x== 1&&DateTime[1]<59) DateTime[1]++;
if(x==-1&&DateTime[1]>0) DateTime[1]--;
break;
}
}
void main()
{
Init_LCD();
while(1)
{
GetTime();
if(K1==0)
{
DelayMS(10); //按键消抖
while(K1==0);
if(Adjust_Index==-1||Adjust_Index==1) {Adjust_Index=7;}//uchar Change_Flag[]="-MHDM-Y";
Adjust_Index--;
if(Adjust_Index==5) Adjust_Index=4;
LCD_DSY_BUFFER2[13]='[';
LCD_DSY_BUFFER2[14]=Change_Flag[Adjust_Index];
LCD_DSY_BUFFER2[15]=']';
if(K2==0) // 加
{
DelayMS(10); //按键消抖
while (K2==0); DateTime_Adjust(1);
}
else if(K3==0) // 减
{
DelayMS(10); //按键消抖
while (K3==0); DateTime_Adjust(-1);
}
else if(K4==0) // 确定
{
DelayMS(10); //按键消抖
while(K4==0);
SET_DS1302(); //调整后的时间写入DS1302
LCD_DSY_BUFFER2[13]=' ';
LCD_DSY_BUFFER2[14]=' ';
LCD_DSY_BUFFER2[15]=' ';
Adjust_Index=-1;
}
}
}
Format_DateTime(DateTime[6],LCD_DSY_BUFFER1+5); //年
Format_DateTime(DateTime[4],LCD_DSY_BUFFER1+8); //月
Format_DateTime(DateTime[3],LCD_DSY_BUFFER1+11); //日
strcpy(LCD_DSY_BUFFER1+13,WEEK[DateTime[5]]); //week
Format_DateTime(DateTime[2],LCD_DSY_BUFFER2+5); //时
Format_DateTime(DateTime[1],LCD_DSY_BUFFER2+8); //分
Format_DateTime(DateTime[0],LCD_DSY_BUFFER2+11); //秒
Display_LCD_String(0x00,LCD_DSY_BUFFER1);
Display_LCD_String(0x40,LCD_DSY_BUFFER2);
}
|
|