OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 18365|回复: 6

ds1302做个可调时钟,始终不能调时间

[复制链接]

79

主题

127

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
465
金钱
465
注册时间
2013-2-19
在线时间
1 小时
发表于 2013-8-23 18:18:50 | 显示全部楼层 |阅读模式
 做个ds1302的可调时钟,两个键。一个负责调整该调时,分,秒等,另一个按键负责加。
//选择设置那个项目1,2,3,4,5,6对应秒,分,时;日,月,年
void ProChs(void)
{
  if(keyNum == 1)
{
  keyNum = 0;
  func++;
  if(func > 1)
  led0 = 0;
  if(func > 6)
   func = 0;
}
}

data[]是个全局变量
void AdjusProject(void)
{
u8 low = 0;
u8 hgt = 0;  //BCD 码最低位加到9后就会进位,我用16进制的话要加到15才进位,所以这里设置BCD高位和低位
switch(func)
{
  case 1://这是秒钟设置
  {
   low = (data[0] & 0x0f);
   hgt = (data[0] >> 4);    //BCD 处理
   if(keyNum == 2)//加键按下
   {
    keyNum = 0;
    hgt += 1;//实际上每次调10秒
    if(hgt > 5)
    {
     hgt = 0;
     low = 0;
     data[0] = 0;
    }
    data[0] = hgt << 4 + low;
     disp();  //显示数据这里实际上仅仅是刷新屏幕,并没有操作芯片
    WriteData();//把调整完的数据写进芯片  
   }

  }break;
  case 2://这是分钟设置
  {
   low = (data[1] & 0x0f);
   hgt = (data[1] >> 4);
   if(keyNum == 2)//加键按下
   {
    keyNum = 0;
    low++;
    LcdShowNum(low,0xc8); //这句是想测试low到底有没有增加
    if(low > 9)
    {
     low = 0;
     hgt++;
     if(hgt > 5)
     {
      hgt = 0;
     }
    }
    data[1] = hgt << 4 + low;
     disp();  //显示数据这里实际上仅仅是刷新屏幕,并没有操作芯片
       WriteData();//把调整完的数据写进芯片
      
   }
  }break;
  case 3://这是时设置
  {
   low = (data[2] & 0x0f);
   hgt = (data[2] >> 4);
   if(keyNum == 2)//加键按下
   {
    keyNum = 0;
    low++;
    if(low > 9)
    {
     low = 0;
     hgt++;
     if(hgt > 2)
     {
      hgt = 0;
     }
    }
    data[2] = hgt << 4 + low ;
     disp();  //显示数据这里实际上仅仅是刷新屏幕,并没有操作芯片
    WriteData(); //把调整完的数据写进芯片     
   }
  }break;
  default:break;
}
}


主函数中
while(1)
{
  roChs(); //调整
     ReadData();
    AdjusProject();
     disp();
}
问题:首先请大家看看我的这个思路是否有问题?先通过功能键选择要调那个项目,然后到那个项目下按加键调节
2,为什么在走到分设置时,按加键,始终不能加?
3,为什么每次进入调时间的时候,该调的项就显示为0,我先读的初始化中数据啊,一按下加键,至少是在原来初始化数据的基础上变化吧为什么直接跳到0?
4,当时,分的数据跳到0后,再怎么按键数据都不会变化?

ds1302,按键检测,lcd这些基本的程序都没有问题的。主要是不是我上面的逻辑有错误?谢谢
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

38

主题

2061

帖子

6

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3273
金钱
3273
注册时间
2012-1-16
在线时间
37 小时
发表于 2013-8-23 18:42:19 | 显示全部楼层
把disp();贴出来看看、、、
站在巨人的肩膀上不断的前进。。。
回复 支持 反对

使用道具 举报

79

主题

127

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
465
金钱
465
注册时间
2013-2-19
在线时间
1 小时
 楼主| 发表于 2013-8-24 08:46:53 | 显示全部楼层
回复【2楼】xiaoyan:
把disp();贴出来看看、、、
---------------------------------
void disp(void)
{
  u8 sec = 0;
u8 min = 0;
u8 hur = 0;
u8 day = 0;
u8 mon = 0;
u16 year = 0;


sec = ((data[0] & 0x70)>>4)*10 + (data[0] & 0xf); //转换成十进制数


min = ((data[1] & 0x70)>>4)*10 + (data[1] & 0xf);


hur = ((data[2] & 0x70) >> 4)*10 +(data[2] & 0x0f);   


day = (data[3]>>4)*10 + (data[3] & 0xf);


mon = (data[4]>>4)*10 + (data[4] & 0xf);

year = (data[5] >> 4)*10 + (data[5] & 0x0f);
year += 2000;

LcdShowNum(sec,0xc6);
LcdShowNum(min,0xc3);
LcdShowNum(hur,0xc0);
LcdShowNum(day,0x88);
LcdShowNum(mon,0x85);
LcdShowNum(year,0x80);
}
回复 支持 反对

使用道具 举报

38

主题

2061

帖子

6

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3273
金钱
3273
注册时间
2012-1-16
在线时间
37 小时
发表于 2013-8-24 09:30:14 | 显示全部楼层
这一下子我也瞧不出来,keyNum的值在哪改变的?
站在巨人的肩膀上不断的前进。。。
回复 支持 反对

使用道具 举报

1

主题

6

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2013-5-16
在线时间
6 小时
发表于 2013-8-24 14:35:17 | 显示全部楼层
程序非调表状态运行时,从DS1302中读出时间,根据你的思路应该先放到data数组中,然后再通过处理data数组进行LCD的显示。在调表时,应该先将data数组中对应的时间值付给low和hgt,然后每次按下“+”时,low增1,进位或到达顶值时对hgt处理。

我觉得DS1302在退出整个调表程序以后 然后在Burst Mode下一次写入8个字节,当然你可以每次更改后马上写入更改值。需要提醒一下,DS1302的写保护还是很有用的 在不用时最好写禁止,调表时再允许写。
回复 支持 反对

使用道具 举报

1

主题

31

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
212
金钱
212
注册时间
2015-10-4
在线时间
35 小时
发表于 2016-9-23 21:55:28 | 显示全部楼层
学习学习!
回复 支持 反对

使用道具 举报

2

主题

10

帖子

0

精华

初级会员

Rank: 2

积分
58
金钱
58
注册时间
2016-10-27
在线时间
10 小时
发表于 2016-11-21 12:40:57 | 显示全部楼层
楼主搞定了吗?求学习。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-25 05:04

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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