0
求助,虽然能正常显示时分秒年月日,但调节时间这块老不成功,已经调了很久,一直不知道是为什么,现在把代码贴出来求高手指点,有仿真原理图
/********H文件****************/
#ifndef _123_H__
#define __123_H__
#include
#define uchar unsigned char
#define uint unsigned int
***it dsclk=P3^1;//ds时钟输入端
***it dsdata=P3^2;//ds数据双向通信端
***it dsret=P3^0;//ds 复位端
uchar code tabled[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};//数码管0-9数字
uchar code tab[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0Xbf,0X7f};//数码管显示位选端
void show();
void get_time();
uchar read(uchar address);
void write(uchar address,uchar number);
void delay(uchar i);
uchar GetKey(void);
uchar Keyscan(void) ;
#endif
/********C文件****************/
#include"123.h"
uchar a,w,adjust_flag=0;
uchar buf[8];//申请数据暂存空间
uchar current_time[7];
/**************************************************************
* 名称: delay(uchar i)
* 功能: 延时
* 输出:
***************************************************************/
void delay(uchar i)
{
while(--i);
}
/**************************************************************
* 名称: read(uchar address)
* 功能: 从DS1302指定位置读数据
* 输出: address
***************************************************************/
uchar read(uchar address)
{
uchar i;
dsclk=0;
dsdata=0;
dsret=0;
dsret=1;//ret处于高电平时可对1302进行读操作
for(i=0;i<8;i++)
{
dsclk=0;//上升沿时进行写数据
dsdata=address&0x01;//数据传送都是从低位开始
address=address>>1;//右移一位
dsclk=1;//上升沿写数据
}
for(i=0;i<8;i++)
{
dsclk=0;//上升沿动作
address=address>>1;
if(dsdata)
address=address|0x80;
dsclk=1;//上升沿动作
dsclk=1;//等待
}
dsclk=1;//时钟置高
dsret=0;//片选无效
return (address);
}
/**************************************************************
* 名称: write(uchar address,uchar number)
* 功能: 向DS1302某地址写数据
* 输出:
***************************************************************/
void write(uchar address,uchar number)
{
uchar i;
dsclk=0;//清零时钟总线
dsdata=0;//清零数据总线
dsret=0;//片选端无效
dsret=1;//逻辑控制有效,可对1302操作
for(i=16;i>0;i++)
{
dsclk=0;
if(i>8)
{
dsdata=address&0x01;//低地址输入
address=address>>1;//地址数据右移一位
}
else
{
dsdata=number&0x01;//进行数据传送
number=number>>1;//数据右移一位
}
dsclk=1;
}
dsclk=1;//上升沿动作
dsret=0;//片选无效,不可进行操作
}
/**************************************************************
* 名称: show()
* 功能: 实时显示时间与日期
* 输出:
***************************************************************/
void show()
{
uchar i;
for(i=0;i<8;i++)
{
P0=~tabled[buf[i]];//P0数据输出
P2=tab[i];
delay(100);
P2=0xff;
}
}
/**************************************************************
* 名称: get_time()
* 功能: 从DS1302的相关寄存器里读出当前时间值和日期值
* 输出:
***************************************************************/
void get_time()
{
current_time[0]=read(0x81);
current_time[1]=read(0x83);
current_time[2]=read(0x85);
current_time[3]=read(0x87);
current_time[4]=read(0x89);
current_time[5]=read(0x8d);
}
/**************************************************************
* 名称: settime_ds1302(uchar add,uchar value)
* 功能: 设置时间函数
* 输出:
***************************************************************/
void settime_ds1302(uchar add,uchar value)
{//地址为80h,82h,84h,86h,88h,8ch
write(0x8e,0x00);
write(0x8e,0x00);
write(add,((value/10)<<4|(value%10)));
write(0x8e,0x80);
}
/**************************************************************
* 名称: Keyscan()
* 功能: P1外接4×4按键, 按照扫描法读出键值
* 输出: 按键值0~15/如无键按下, 返回16
***************************************************************/
uchar Keyscan(void)
{
uchar i, j, temp, key_Buffer[4] = {0xef,0xdf,0xbf,0x7f};
for(j = 0; j < 4; j++) //循环四次
{
P1 = key_Buffer[j]; //在P3高四位分别输出一个低电平
temp = 0x01; //计划先判断P3.0位
for(i = 0; i < 4; i++)//循环四次
{
if(!(P1 & temp)) //从P3低四位,截取1位
return (i + j * 4); //返回取得的按键值
temp <<= 1; //判断的位,左移一位
}
}
return 16; //判断结束,没有键按下,返回16
}
/**************************************************************
* 名称: GetKey()
* 功能: 读出按键、消抖、等待按键释放
* 输出: 按键值0~15/如无键按下, 返回16
***************************************************************/
uchar GetKey()
{
uchar Key_Temp1, Key_Temp2; //两次读出的键值
P1 = 0xff;
Key_Temp1 = Keyscan(); //先读入按键
if(Key_Temp1 == 16) return 16; //没有键按下,返回16
show(); //用显示代替延时
Key_Temp2 = Keyscan(); //再读一次按键
if(Key_Temp1 != Key_Temp2) return 16; //不同,返回16
while(Keyscan() < 16) //等待按键释放
show(); //等待期间显示
return Key_Temp1;
}
void main()
{
uchar Key_Value;
while(1)
{
if(adjust_flag==0)get_time();
buf[0]=current_time[2]/16;//小时数据转换成十进制
buf[1]=current_time[2]%16;//小时数据转换成十进制
buf[2]=0x0A;//小时与分之间的横线
buf[3]=current_time[1]/16;//分数据转换成十进制
buf[4]=current_time[1]%16;//分数据转换成十进制
buf[5]=0x0A;//分与秒之间的横线
buf[6]=current_time[0]/16;//秒数据转换成十进制
buf[7]=current_time[0]%16;//秒数据转换成十进制
show();//将时间通过数码管进行显示
if(GetKey()==10)
{
adjust_flag=1;
while(adjust_flag==1)
{
Key_Value=GetKey();
w++;
if(Key_Value<10)
{
current_time[0]%=10;
current_time[0]=current_time[0]*10+Key_Value;
}
buf[6]=current_time[0]/16;//秒数据转换成十进制
buf[7]=current_time[0]%16;//秒数据转换成十进制
show();
if(Key_Value==10)
{
settime_ds1302(0x80,current_time[0]);
settime_ds1302(0x82,current_time[1]);
settime_ds1302(0x84,current_time[2]);
adjust_flag=0;
}
}
}
}
}
|
|