我是初中生,吓解释一下,
U1是处理器,U3是存储器,U1 32到39是8线地址,整个LCD工作显示取决于它。RV1是个可调电阻,它是调节液晶对比度的,RP1 为排阻另一端应该接高电位,8线地址工作只是把电位拉低,X1和X2是两个晶体振荡器,X1为U1提供工作频率,X2为U2提供,当然通过内部分频于倍频得到需要的工作频率。
你想知道工作流程,其实这些流程有些不是说一部分一部分工作的,(即使LCD没有显示,其实也工作了)几乎同时,不过还是有先后的,首先U1工作,调取U3里的数据,U3是个最简单的存储器。运算后由8线地址输出给LED。U1的9脚接了个复位开关,按下开关U1即从新启动。U1的10脚到14脚为调节开关,它会让U1的计算从某个点开始,于是时间调节才实现。还有就是定时功能,当设定的时间与时间符合,闹钟启动蜂鸣LS1
文化有限,只能说这些了,不全面的地方望指教,毕竟我初中毕业
这个好像没什么好解释的,就是单片机的最小系统加上一块DS1302时钟芯片,你需要解释那一部分?感觉你应该去看看ds1302怎么用才对
把这个程序扫到单片机就能显示出年月日时分秒
#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit lcrs=P2^6;//数据/命令
sbit lcden=P2^7;//使能
sbit SCLK = P1^0;//DS1302时钟口P1.0
sbit IO = P1^1; //DS1302数据口P1.1
sbit RS = P1^2; //DS1302片选口P1.2
sbit key1=P4^4;
sbit key2=P4^5;
sbit key3=P4^1;
sbit key4=P4^6;
//秒 分 时 日 月 星期 年
uchar init[] = {0x45, 0x40, 0x20, 0x018, 0x04, 0x03, 0x12};
uchar now[7];
uchar code table[]={48,49,50,51,52,53,54,55,56,57};
uchar dis[16];
uchar H;//定义小时
uchar Mi;//定义分钟
uchar S;//定义秒
uchar Y;//定义年
uchar Mo;//定义月
uchar D;//定义日期
uchar W;//定义星期
uchar key=0;
uchar bcdto(uchar temp);
void delayms(uint ms);
void DS1302_Initial();
void DS1302_SetTime(uchar *p);
void DS1302_GetTime(uchar *p);
////////////////////// 延时子程序/////////////////////////////
void delayms(uint ms) //在11.0592M晶振下,单周期指令的ms级延时
{
uint i;
while(ms--)
{
for(i = 0; i < 850; i++);
}
}
//////1062/////////
void ydelay(uchar x)
{
uint a,b;
for(a=x;a>0;a--)
for(b=10;b>0;b--);
}
void write_com(uchar com)
{
P0=com;
lcwr=0;
lcrs=0;
lcden=0;
ydelay(20);
lcden=1;
ydelay(20);
lcden=0;
lcwr=1;
}
void write_date(uchar date)//写数据
{
P0=date;
lcwr=0;
lcrs=1;
lcden=0;
ydelay(20);
lcden=1;
ydelay(20);
lcden=0;
lcwr=1;
}
void init1602()//初始化
{
write_com(0x38);//设置显示模式
ydelay(40);
write_com(0x0c);//开显示
ydelay(40);
write_com(0x06);//指针和光标自动加一
ydelay(40);
write_com(0x01);//清屏指令
ydelay(40);
}
void display(uchar a)//显示
{
uint i;
dis[0]='2';dis[1]='0';dis[2]=table[Y/10];dis[3]=table[Y%10];
dis[4]='.';dis[5]=table[Mo/10];dis[6]=table[Mo%10];
dis[7]='.';dis[8]=table[D/10];dis[9]=table[D%10];dis[10]=' ';
dis[11]='W';dis[12]='e';dis[13]='e';dis[14]=' ';
dis[15]=table[W%10];
if(a==3)
{dis[2]=' ';dis[3]=' ';}
else if(a==4)
{dis[5]=' ';dis[6]=' ';}
else if(a==5)
{dis[8]=' ';dis[9]=' ';}
else if(a==6)
{dis[15]=' ';}
write_com(0x0c);
write_com(0xc0);
for(i=0;i<16;i++)
write_date(dis[i]);
dis[0]=table[H/10];dis[1]=table[H%10];dis[2]=':';
dis[3]=table[Mi/10]; dis[4]=table[Mi%10];dis[5]=':';
dis[6]=table[S/10];dis[7]=table[S%10];dis[8]=' ';
if(a==1)
{
dis[0]=' ';dis[1]=' ';
}
else if(a==2)
{dis[3]=' ';dis[4]=' ';}
write_com(0x80+4);
for(i=0;i<9;i++)
write_date(dis[i]);
}
uchar tobcd(uchar temp)//十进制转换成BCD码
{
uchar a,b,c;
a=temp;
b=0;
if(a>=10)
{
while(a>=10)
{
a=a-10;
b=b+16;
c=a+b;
temp=c;
}
}
return temp;
}
uchar bcdto(uchar temp)//BCD码转换成十进制
{
uchar a,b,c;
a=temp;
b=0;
if(a>=16)
{
while(a>=16)
{
a=a-16;
b=b+10;
c=a+b;
temp=c;
}
}
return temp;
}
void keyf(uchar *num,uchar up,uchar du)
{
uint z;
if(key2==0)
{
delayms(10);
if(key2==0)
{
if(*num>=up)
{
if((key==4)||(key==5)||(key==6))
*num=1;
else
*num=0;
}
else
*num=*num+1;
for(z=0;z<50;z++)
{
display(0);
if(key2!=0)
break;
}
while(!key2)
{
for(z=0;z<25;z++)
{display(0);}
if(*num>=up)
{
if((key==4)||(key==5)||(key==6))
*num=1;
else
*num=0;
}
else
*num=*num+1;
}
}
}
if(key3==0)
{
delayms(10);
if(key3==0)
{
if(*num==du)
{
if(key==1)
*num=23;
else if(key==2)
*num=59;
else if(key==3)
*num=99;
else if(key==4)
*num=12;
else if(key==5)
*num=31;
else if(key==6)
*num=7;
}
else
*num=*num-1;
for(z=0;z<50;z++)
{
display(0);
if(key3!=0)
break;
}
while(!key3)
{
for(z=0;z<25;z++)
{display(0);}
if(*num==du)
{
if(key==1)
*num=23;
else if(key==2)
*num=59;
else if(key==3)
*num=99;
else if(key==4)
*num=12;
else if(key==5)
*num=31;
else if(key==6)
*num=7;
}
else
*num=*num-1;
}
}
}
}
void keyjc()
{
uint i,j;
if(key1==0)
delayms(10);
if(key1==0)
{
key++;
if(key>=7)
{
key=0;
display(0);
}
while(!key1);
if(key==1)
{
for(i=0;i<25;i++)
{
for(j=0;j<25;j++)
display(1);
for(j=0;j<25;j++)
display(0);
if((key2==0)||(key3==0))
{
delayms(10);
if((key2==0)||(key3==0))
{
i=0;
keyf(&H,23,0);
}
}
if(key1==0)
{
delayms(10);
if(key1==0)
{
key=2;
while(!key1);
break;
}
}
}
}
if(key==2)
{
for(i=0;i<25;i++)
{
for(j=0;j<25;j++)
display(2);
for(j=0;j<25;j++)
display(0);
if((key2==0)||(key3==0))
{
delayms(10);
if((key2==0)||(key3==0))
{
i=0;
keyf(&Mi,59,0);
}
}
if(key1==0)
{
delayms(10);
if(key1==0)
{
key=3;
while(!key1);
break;
}
}
}
}
if(key==3)
{
for(i=0;i<25;i++)
{
for(j=0;j<25;j++)
display(3);
for(j=0;j<25;j++)
display(0);
if((key2==0)||(key3==0))
{
delayms(10);
if((key2==0)||(key3==0))
{
i=0;
keyf(&Y,99,0);
}
}
if(key1==0)
{
delayms(10);
if(key1==0)
{
key=4;
while(!key1);
break;
}
}
}
}
if(key==4)
{
for(i=0;i<25;i++)
{
for(j=0;j<25;j++)
display(4);
for(j=0;j<25;j++)
display(0);
if((key2==0)||(key3==0))
{
delayms(10);
if((key2==0)||(key3==0))
{
i=0;
keyf(&Mo,12,1);
}
}
if(key1==0)
{
delayms(10);
if(key1==0)
{
key=5;
while(!key1);
break;
}
}
}
}
if(key==5)
{
for(i=0;i<25;i++)
{
for(j=0;j<25;j++)
display(5);
for(j=0;j<25;j++)
display(0);
if((key2==0)||(key3==0))
{
delayms(10);
if((key2==0)||(key3==0))
{
i=0;
keyf(&D,31,1);
}
}
if(key1==0)
{
delayms(10);
if(key1==0)
{
key=6;
while(!key1);
break;
}
}
}
}
if(key==6)
{
for(i=0;i<25;i++)
{
for(j=0;j<25;j++)
display(6);
for(j=0;j<25;j++)
display(0);
if((key2==0)||(key3==0))
{
delayms(10);
if((key2==0)||(key3==0))
{
i=0;
keyf(&W,7,1);
}
}
if(key1==0)
{
delayms(10);
if(key1==0)
{
key=0;
while(!key1);
break;
}
}
}
}
init[0]=tobcd(S);
init[1]=tobcd(Mi);
init[2]=tobcd(H);
init[3]=tobcd(D);
init[4]=tobcd(Mo);
init[5]=tobcd(W);
init[6]=tobcd(Y);
DS1302_SetTime(init);
key=0;
}
}
void main()
{
init1602();
DS1302_Initial(); //初始化DS1302
P4SW=0x70;
while (1)
{
delayms(10);
DS1302_GetTime(now);//读取当前时间
Y=bcdto(now[6]);
Mo=bcdto(now[4]);
D=bcdto(now[3]);
W=bcdto(now[5]);
if(W==7)
W=8;
H=bcdto(now[2]);
Mi=bcdto(now[1]);
S=bcdto(now[0]);
display(0);
keyjc();
}
}
/**************************************
延时X微秒(STC12C5A60S2@12M)
不同的工作环境,需要调整此函数
此延时函数是使用1T的指令周期进行计算,与传统的12T的MCU不同
**************************************/
void Delay()
{
_nop_();
_nop_();
}
/**************************************
从DS1302读1字节数据
**************************************/
uchar DS1302_ReadByte()
{
uchar i;
uchar dat = 0;
for (i=0; i<8; i++) //8位计数器
{
SCLK = 0; //时钟线拉低
Delay(); //延时等待
dat >>= 1; //数据右移一位
if (IO) dat |= 0x80; //读取数据
SCLK = 1; //时钟线拉高
Delay(); //延时等待
}
return dat;
}
/**************************************
向DS1302写1字节数据
**************************************/
void DS1302_WriteByte(uchar dat)
{
char i;
for (i=0; i<8; i++) //8位计数器
{
SCLK = 0; //时钟线拉低
Delay(); //延时等待
dat >>= 1; //移出数据
IO = CY; //送出到端口
SCLK = 1; //时钟线拉高
Delay(); //延时等待
}
}
/**************************************
读DS1302某地址的的数据
**************************************/
uchar DS1302_ReadData(uchar addr)
{
uchar dat;
RS = 0;
Delay();
SCLK = 0;
Delay();
RS = 1;
Delay();
DS1302_WriteByte(addr); //写地址
dat = DS1302_ReadByte(); //读数据
SCLK = 1;
RS = 0;
return dat;
}
/**************************************
往DS1302的某个地址写入数据
**************************************/
void DS1302_WriteData(uchar addr, uchar dat)
{
RS = 0;
Delay();
SCLK = 0;
Delay();
RS = 1;
Delay();
DS1302_WriteByte(addr); //写地址
DS1302_WriteByte(dat); //写数据
SCLK = 1;
RS = 0;
}
/**************************************
写入初始时间
**************************************/
void DS1302_SetTime(uchar *p)
{
uchar addr = 0x80;
uchar n = 7;
DS1302_WriteData(0x8e, 0x00); //允许写操作
while (n--)
{
DS1302_WriteData(addr, *p++);
addr += 2;
}
DS1302_WriteData(0x8e, 0x80); //写保护
}
/**************************************
读取当前时间
**************************************/
void DS1302_GetTime(uchar *p)
{
uchar addr = 0x81;
uchar n = 7;
while (n--)
{
*p++ = DS1302_ReadData(addr);
addr += 2;
}
}
/**************************************
初始化DS1302
**************************************/
void DS1302_Initial()
{
RS = 0;
SCLK = 0;
DS1302_WriteData(0x8e, 0x00); //允许写操作
DS1302_WriteData(0x80, 0x00); //时钟启动
DS1302_WriteData(0x90, 0xaa); //一个二极管+8K电阻充电
DS1302_WriteData(0x8e, 0x80); //写保护
}