找回密码
 注册会员
更新自动建库工具PCB Footprint Expert 2024.04 Pro / Library Expert 破解版

麻烦 大家帮我看看这个程序的按键部分那里出了问题,谢谢!

[复制链接]
admin 发表于 2012-9-2 10:19:10 | 显示全部楼层 |阅读模式

本文包含原理图、PCB、源代码、封装库、中英文PDF等资源

您需要 登录 才可以下载或查看,没有账号?注册会员

×
//程序的功能是可以修改DS1302的时间,并且在LCD上显示
#include<reg52.h> //包含单片机寄存器的头文件
#define uchar unsigned char
uchar second,minute,hour,day,month,year,week,flag=0,ReadValue;
sbit dula=P2^0;
sbit wela=P2^1;
sbit SCLK=P0^0; //位定义1302芯片的接口,时钟输出端口定义在P0.0引脚
sbit DATA=P0^1; //位定义1302芯片的接口,数据输出端定义在P0.1引脚
sbit RST=P0^2;
sbit function=P3^3; //功能键
sbit add=P3^2; 增加键
sbit reduce=P3^1; //减少键
uchar code table_week1[]="Mon ";
uchar code table_week2[]="Tues " ;
uchar code table_week3[]="Wed " ;
uchar code table_week4[]="Thurs" ;
uchar code table_week5[]="Fir " ;
uchar code table_week6[]="Sat " ;
uchar code table_week7[]="Sun " ;
void delay(uchar z)
{
uchar x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/*****************************************************
函数功能:延时若干微秒
入口参数:n
***************************************************/
void delaynus(unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++);
}
/*****************************************************
函数功能:向1302写一个字节数据
入口参数:x
***************************************************/
void Write1302(unsigned char dat)
{
unsigned char i;
SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备
delaynus(2); //稍微等待,使硬件做好准备
for(i=0;i<8;i++) //连续写8个二进制位数据
{
DATA=dat&0x01; //取出dat的第0位数据写入1302 低位在前,高位在后
delaynus(2); //稍微等待,使硬件做好准备
SCLK=1; //上升沿写入数据
delaynus(2); //稍微等待,使硬件做好准备
SCLK=0; //重新拉低SCLK,形成脉冲
dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位
}

}
/*****************************************************
函数功能:根据命令字,向1302写一个字节数据
入口参数:Cmd,储存命令字;dat,储存待写的数据
***************************************************/
void WriteSet1302(unsigned char Cmd,unsigned char dat)
{
RST=0; //禁止数据传递
SCLK=0; //确保写数居前SCLK被拉低
RST=1; //启动数据传输
delaynus(2); //稍微等待,使硬件做好准备
Write1302(Cmd); //写入命令字
Write1302(dat); //写数据
SCLK=1; //将时钟电平置于高电平状态
RST=0; //禁止数据传递
}
/*****************************************************
函数功能:从1302读一个字节数据
入口参数:x
***************************************************/
unsigned char Read1302(void)
{
unsigned char i,dat;
delaynus(2); //稍微等待,使硬件做好准备
for(i=0;i<8;i++) //连续读8个二进制位数据
{ dat>>=1;
if(DATA==1) //如果读出的数据是1
dat|=0x80; //将1取出,写在dat的最高位
SCLK=1; //将SCLK置于高电平,为下降沿读出
delaynus(2); //稍微等待
SCLK=0; //拉低SCLK,形成脉冲下降沿
delaynus(2); //稍微等待
}
return dat; //将读出的数据返回
}
/*****************************************************
函数功能:根据命令字,从1302读取一个字节数据
入口参数:Cmd
***************************************************/
unsigned char ReadSet1302(unsigned char Cmd)
{
unsigned char dat;
RST=0; //拉低RST
SCLK=0; //确保写数居前SCLK被拉低
RST=1; //启动数据传输
Write1302(Cmd); //写入命令字
dat=Read1302(); //读出数据
SCLK=1; //将时钟电平置于已知状态
RST=0; //禁止数据传递
return dat; //将读出的数据返回
}
/*****************************************************
函数功能: 1302进行初始化设置
***************************************************/
Set_DS1302(uchar second,uchar minute,uchar hour,uchar day,uchar month,uchar year,uchar week)
{

WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令
WriteSet1302(0x80,((second/10)<<4|(second%10))); //根据写秒寄存器命令字,写入秒的初始值
WriteSet1302(0x82,((minute/10)<<4|(minute%10))); //根据写分寄存器命令字,写入分的初始值
WriteSet1302(0x84,((hour/10)<<4|(hour%10))); //根据写小时寄存器命令字,写入小时的初始值
WriteSet1302(0x86,((day/10)<<4|(day%10))); //根据写日寄存器命令字,写入日的初始值
WriteSet1302(0x88,((month/10)<<4|(month%10))); //根据写月寄存器命令字,写入月的初始值
WriteSet1302(0x8c,((year/10)<<4|(year%10))); //根据写年寄存器命令字,写入年的初始值
WriteSet1302(0x8a,((week/10)<<4|(week%10))); //根据写星期寄存器命令字,写入星期的初始值
WriteSet1302(0x90,0xa5); //打开充电功能 选择2K电阻充电方式
WriteSet1302(0x8E,0x80); //根据写状态寄存器命令字,写入保护指令

}
/* Set_ds1302change(uchar add,uchar time )
{
WriteSet1302(0x8E,0x00);
WriteSet1302(add,((time/10)<<4|(time%10)));
WriteSet1302(0x8E,0x80);
} */
/*******************************************************************************
以下是对液晶模块的操作程序
*******************************************************************************/
sbit lcdrs=P2^4; //寄存器选择位,将RS位定义为P2.0引脚
sbit RW=P2^3; //读写选择位,将RW位定义为P2.1引脚
sbit lcden=P2^2; //使能信号位,将E位定义为P2.2引脚
void write_com(uchar com)
{
lcdrs=0;
RW=0;
P1=com;
lcden=1;
delaynus(100);
lcden=0;
delaynus(100);
}
void write_date(uchar date)
{
lcdrs=1;
RW=0;
P1=date;
lcden=1;
delaynus(100);
lcden=0;
delaynus(100);
}
void write_sfm(uchar add,uchar date)
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x40+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
void write_sfm_nyrw(uchar add,uchar date)
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
void init()
{

dula=0;
wela=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
write_com(0x80+0x01); //写Date的显示地址,将在第1行第2列开始显示

write_com(0x80+0x03); //写年月分隔符的显示地址, 显示在第1行第9列
write_date('-'); //将字符常量写入LCD
write_com(0x80+0x06); //写月日分隔符的显示地址, 显示在第1行第12列
write_date('-'); //将字符常量写入LCD

write_com(0x80+0x46); //写小时与分钟分隔符的显示地址, 显示在第2行第6列
write_date(':'); //将字符常量写入LCD
write_com(0x80+0x49); //写分钟与秒分隔符的显示地址, 显示在第2行第9列
write_date(':'); //将字符常量写入LCD
WriteSet1302(0x90,0xa5);



}
/*****************************************************
函数功能:星期显示子函数
***************************************************/
Display_week(uchar week_num)
{
uchar num;
write_com(0x80+0x0a);
if(week_num==1)
{
for(num=0;num<5;num++)
{
write_date(table_week1[num]);
delay(50);
}
}
if(week_num==2)
{
for(num=0;num<5;num++)
{
write_date(table_week2[num]);
delaynus(20);
}
}
if(week_num==3)
{
for(num=0;num<5;num++)
{
write_date(table_week3[num]);
delaynus(20);
}
}
if(week_num==4)
{
for(num=0;num<5;num++)
{
write_date(table_week4[num]);
delaynus(20);
}
}
if(week_num==5)
{
for(num=0;num<5;num++)
{
write_date(table_week5[num]);
delaynus(20);
}
}
if(week_num==6)
{
for(num=0;num<5;num++)
{
write_date(table_week6[num]);
delaynus(20);
}
}
if(week_num==7)
{
for(num=0;num<5;num++)
{
write_date(table_week7[num]);
delaynus(20);
}
}
}
/*****************************************************
函数功能:键盘扫描子函数
***************************************************/
void keyscan(void )
{
uchar func_num;
P3=0xff;
//功能选择键,按下键时,所选位置光标闪烁
if(function==0)
{
delay(50);
if(function==0)
{
func_num++;
flag=1;


// WriteSet1302(0x81,0x80);//时钟暂停
/* ReadValue= ReadSet1302(0x8b); //从星期寄存器读
week=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
delaynus(10);
ReadValue = ReadSet1302(0x87); //从日寄存器读
day=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
delaynus(10);
ReadValue = ReadSet1302(0x89); //从月寄存器读
month=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
delaynus(10);
ReadValue = ReadSet1302(0x8D); //从年寄存器读

year=((ReadValue&0xf0)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
delaynus(10); */
while(!function);

if(func_num==1)
{
write_com(0x80+0x40+10);
write_com(0x0f);
}
if(func_num==2)
{


write_com(0x80+0x40+7);
write_com(0x0f);

}
if(func_num==3)
{


write_com(0x80+0x40+4);
write_com(0x0f);

}
if(func_num==4)
{

write_com(0x80+0x0a);
write_com(0x0f);

}
if(func_num==5)
{

write_com(0x80+0x07);
write_com(0x0f);

}
if(func_num==6)
{
 楼主| admin 发表于 2012-9-2 10:19:15 | 显示全部楼层
write_com(0x80+0x04);
write_com(0x0f);

}
if(func_num==7)
{

write_com(0x80+0x01);
write_com(0x0f);

}





//判断增加键是否按下
if(add==0&&func_num!=0)
{
delaynus(50);
if(add==0&&func_num!=0)
{
while(!add);
if(add==0&&func_num!=0)
{

WriteSet1302(0x81,0x80);//时钟暂停
if(func_num==1)
{

ReadValue = ReadSet1302(0x81); //从秒寄存器读数据
second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//将读出数据转化
delaynus(10);
second++;
if(second==60)
second=0;
delaynus(10);
write_sfm(10,second);
write_com(0x80+0x40+10);
}
if(func_num==2)
{
ReadValue = ReadSet1302(0x83); //从分寄存器读
minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
delaynus(10);
minute++;
if(minute==60)
minute=0;
delaynus(10);
write_sfm(7,minute);
write_com(0x80+0x40+7);
}
if(func_num==3)
{
ReadValue = ReadSet1302(0x85); //从时寄存器读
hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
delaynus(10);
hour++;
if(hour==24)
hour=0;
delaynus(10);
write_sfm(4,hour);
write_com(0x80+0x40+4);
}

/*if(func_num==4)
{
week++;
if(week==7)
week=0;
Display_week(week);
write_com(0x80+0x0a);
}
if(func_num==5)
{
day++;
if(day==31)
day=0;
write_sfm_nyrw(0x07,day);
write_com(0x80+0x07);
}
if(func_num==6)
{
month++;
if(month==12)
month=0;
write_sfm_nyrw(4,month);
write_com(0x80+0x04);
}
if(func_num==7)
{

year++;
if(year==99)
year=0;

write_sfm_nyrw(1,month);
write_com(0x80+0x01);
} */

}
}

}
if(func_num==8)
{
func_num=0;
write_com(0x0c);
WriteSet1302(0x81,0x00);//时钟开启
Set_DS1302(second,minute,hour,day,month,year,week);
write_sfm(10,second); //显示秒
write_sfm(7,minute); //显示分
write_sfm(4,hour); //显示小时
write_sfm_nyrw(0x07,day); //显示日
write_sfm_nyrw(0x04,month); //显示月
write_sfm_nyrw(1,year); //显示年
Display_week(week);
flag=0;
}
}

}
}
/*void keyscan(void )
{
uchar func_num=0;
P3=0xff;
//功能选择键,按下键时,所选位置光标闪烁
if(function==0)
{
delaynus(20);
if(function==0)
{
while(!function);
WriteSet1302(0x81,0x80);//时钟暂停
func_num++;
flag=1;
if(func_num==1)
{
write_com(0x80+0x40+10);
write_com(0x0f);
}
if(func_num==2)
{

write_com(0x80+0x40+7);
write_com(0x0f);

}
if(func_num==3)
{

write_com(0x80+0x40+4);
write_com(0x0f);

}
if(func_num==4)
{
write_com(0x80+0x07);
write_com(0x0f);

}
if(func_num==5)
{

write_com(0x80+0x04);
write_com(0x0f);

}
if(func_num==6)
{

write_com(0x80+0x04);
write_com(0x0f);

}
if(func_num==7)
{

write_com(0x80+0x04);
write_com(0x0f);

}
if(func_num==8)
{
func_num=0;
flag=0;
write_com(0x0c);
WriteSet1302(0x81,0x00);//时钟开启

ReadValue = ReadSet1302(0x81); //从秒寄存器读数据
second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//将读出数据转化
ReadValue = ReadSet1302(0x83); //从分寄存器读
minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化

ReadValue = ReadSet1302(0x85); //从时寄存器读
hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化

ReadValue = ReadSet1302(0x87); //从日寄存器读
day=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化

ReadValue = ReadSet1302(0x89); //从月寄存器读
month=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化

ReadValue = ReadSet1302(0x8D); //从年寄存器读
year=((ReadValue&0xf0)>>4)*10 + (ReadValue&0x0F); //将读出数据转化

ReadValue= ReadSet1302(0x8b); //从星期寄存器读
week=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
Set_DS1302(second,minute,hour,day,month,year,week);
write_sfm(10,second); //显示秒
write_sfm(7,minute); //显示分
write_sfm(4,hour); //显示小时
write_sfm_nyrw(0x07,day); //显示日
write_sfm_nyrw(0x04,month); //显示月
write_sfm_nyrw(1,year); //显示年
Display_week(week);

}

}
//判断增加键是否按下(判断增加的这部分没反应)
if(func_num!=0)
{
if(add==0)
{
delay(10);
if(add==0)
{
while(!add);

if(func_num==1)
{

second++;
if(second==60)
second=0;
write_sfm(10,second);
}
if(func_num==2)
{
minute++;
if(minute==60)
minute=0;
write_sfm(7,minute);
}
if(func_num==3)
{
hour++;
if(hour==24)
hour=0;
write_sfm(4,hour);
}

if(func_num==4)
{
day++;
if(day==31)
day=0;
write_sfm_nyrw(0x07,day);
}
if(func_num==5)
{
month++;
if(month==31)
month=0;
write_sfm_nyrw(0x04,month);
}
if(func_num==6)
{
year++;
if(year==99)
year=0;
write_sfm_nyrw(1,year);
}
if(func_num==7)
{

week++;
if(week==7)
week=0;
Display_week(week);
}

}
}

}


}

}

*/
/*****************************************************
函数功能:主函数
***************************************************/
void main(void)
{

init(); //将液晶初始化
Set_DS1302(56,59,23,27,3,11,7);

while(1)
{

keyscan();
if(flag==0)
{
ReadValue = ReadSet1302(0x81); //从秒寄存器读数据
second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//将读出数据转化
write_sfm(10,second); //显示秒

ReadValue = ReadSet1302(0x83); //从分寄存器读
minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
write_sfm(7,minute); //显示分

ReadValue = ReadSet1302(0x85); //从时寄存器读
hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
write_sfm(4,hour); //显示小时

ReadValue = ReadSet1302(0x87); //从日寄存器读
day=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
write_sfm_nyrw(0x07,day); //显示日

ReadValue = ReadSet1302(0x89); //从月寄存器读
month=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
write_sfm_nyrw(0x04,month); //显示月

ReadValue = ReadSet1302(0x8D); //从年寄存器读
year=((ReadValue&0xf0)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
write_sfm_nyrw(1,year); //显示年

ReadValue= ReadSet1302(0x8b); //从星期寄存器读
week=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
Display_week(week);
}
}
}
*滑块验证:
您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

QQ|手机版|MCU资讯论坛 ( 京ICP备18035221号-2 )|网站地图

GMT+8, 2024-11-24 16:53 , Processed in 0.056049 second(s), 9 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表