单片机 DS1302 痛苦的调试过程,把我的经验教训分享给大家,希望能给后来者一点帮助

转载 2012年03月27日 16:37:27

原文地址::http://topic.csdn.net/u/20100904/08/736d7397-0ea6-4e12-a859-c1c4775b1ac6.html

 

 

这个是我现在用的程序,还没加闹钟,想加的话也容易,程序有点儿冗余,可能是我的函数写的不够好,不过不管怎么说总算是能用啦,而且我想的功能已经全部实现了,所以拿出来晒晒,希望对还在郁闷的有些帮助,呵呵
我写的过程中遇到的问题:
1,每次写两个字节之后都要把RST=0,SCLK=0,RST=1重写一遍的,我原来的时候没有注意到,详细的请看程序里面就可以看得出来
2,年的位置和周的位置不要搞反了,我就是搞反了,就这个问题就想了几天想不明白,写进去的数和显示出来的数不一样啊,我那个郁闷啊,后来在看技术手册的时候终于看到了,所以大家在写程序的时候一定要好好看技术手册,认真的看,一遍遍的看
3,每次修改一次时间都要从1302里面写一次,这个可能是我的程序的原因,在最后的时候写不行,不知道是为什么,有哪位知道也可以告诉我,随时欢迎
4,不知道为什么我用的板子上写保护不管用,就是说不管我写不写保护都可以,甚至我在写数据之前打开写保护,还可以写进去数据,这个问题我也很是郁闷,大家有哪位能在程序里看出些端倪的也可以随时告诉我,谢谢
下面是代码:
//
//
//1为功能键,2为增加时间键,3为减少时间键
#include<reg52.h>
#include<yj1602.h>
#include<jp.h>

#define uchar unsigned char

sbit sclk=P1^5;
sbit io=P1^6;
sbit rst=P1^7;

uchar time[]={0x00,0x42,0x08,0x04,0x09,0x06,0x10};
uchar timetmp[7];
uchar MAX[]={59,59,23,31,12,7,99};
uchar MINX[]={0,0,0,1,1,1,1};
uint readdata[7];
uchar sec,min,hour,day,month,week,year;
uchar keynum,ss;

void write(uchar date) //写一个字节
{
uchar i;
for(i=0;i<8;i++)
{
io=date&0x01;
sclk=1;sclk=0;
date=date>>1;
}
}
uchar read() //读一个字节
{
uchar shuju,i;
for(i=0;i<8;i++)
{
shuju=shuju>>1;
sclk=0;
if(io)
shuju=shuju|0x80;
sclk=1;
}
return shuju;
}
void writebyte(uchar add,date) //写时间的一个单位(分/秒/时/年/月/日/周)
{
rst=0;sclk=0;rst=1;
write(0x8e);
write(0x00);
rst=0;sclk=0;rst=1;
write(add);
write(date);
rst=0;sclk=0;rst=1;
write(0x8e);
write(0x80);
rst=0;sclk=1;
}
void writetime() //初始化时间
{
uchar i,j=0x80;
for(i=0;i<7;i++)
{
writebyte(j,time[i]);
j+=2;
}
}
uchar readbyte(add) //读一个单位时间(分/秒/时/年/月/日/周)
{
uchar date;
rst=0;sclk=0;rst=1;
write(add);
date=read();
rst=0;sclk=1;
return date;
}
void readtime() //读取时间
{
uchar i,j=0x81;
for(i=0;i<7;i++)
{
readdata[i]=readbyte(j);
j+=2;
}
}
void process() //数制转换
{ uchar i;
for(i=0;i<7;i++)
{
readdata[i]=(readdata[i]>>4)*10+(readdata[i]&0x0f);
}
}

void display() //显示函数
{
display_1602N(0,1,2);
display_1602N(1,1,0);
display_1602N(2,1,year/10);
display_1602N(3,1,year%10);
display_1602S(4,1,"-"); 
display_1602N(5,1,month/10);
display_1602N(6,1,month%10);
display_1602S(7,1,"-"); 
display_1602N(8,1,day/10);
display_1602N(9,1,day%10);
display_1602S(11,1,"WEEK");
display_1602N(15,1,week);
display_1602S(1,2,"TIME");
display_1602S(5,2,":");
display_1602N(6,2,hour/10);
display_1602N(7,2,hour%10);
display_1602S(8,2,":");
display_1602N(9,2,min/10);
display_1602N(10,2,min%10);
display_1602S(11,2,":");
display_1602N(12,2,sec/10);
display_1602N(13,2,sec%10);
}
void timeout() //提取时间
{
sec=readdata[0];
min=readdata[1];
hour=readdata[2];
day=readdata[3];
month=readdata[4];
week=readdata[5];
year=readdata[6];
}
void shanshuo2(uchar add,time) //1602第二行闪烁函数
{
write_com(0x80+0x40+add);
write_date(0x10);
write_com(0x80+0x40+add-1);
write_date(0x10);
delay(100);
display_1602N(add,2,time%10);
display_1602N(add-1,2,time/10);
delay(100);
}
void shanshuo1(uchar add,time) //1602第一行闪烁函数
{
write_com(0x80+add); //当前位什么也不显
write_date(0x10);
write_com(0x80+add-1);
write_date(0x10);
delay(100); //延时
display_1602N(add,1,time%10); //显示时间
display_1602N(add-1,1,time/10);
delay(100); //延时
}
void zj(uchar num) //增减函数
{
switch(keynum)
{
case 1:ss++;break; //如果是1,则进入下一位的调整
case 2:{ //如果是2,则当前闪烁的位加1
timetmp[num]++;
if(timetmp[num]>MAX[num]) //如何超过了闪烁位的最大值,返回最小值
timetmp[num]=MINX[num];
}break;
case 3:{ //如果是3,则当前闪烁的位减1
timetmp[num]--;
if(timetmp[num]<MINX[num]) //如何超过了闪烁位的最小值,返回最大值
timetmp[num]=MAX[num];
}break;
default:break;
}
}
void jpaction() //调时操作
{
while(ss<7)
{  

while(ss==0) //调秒
{
key=0;
timetmp[0]=readbyte(0x81)/16*10+readbyte(0x81)%16; //从1302中取出时间
shanshuo2(13,timetmp[0]); //显示时间并闪烁
keynum=jiance(); //按键检测
zj(0); //对时间进行操作
writebyte(0x80,timetmp[0]/10*16+timetmp[0]%10); //把调整过的时间写到1302中
}  
while(ss==1) //调分
{
key=0;
timetmp[1]=readbyte(0x83)/16*10+readbyte(0x83)%16; //同上
shanshuo2(10,timetmp[1]);
keynum=jiance();
zj(1);
writebyte(0x82,timetmp[1]/10*16+timetmp[1]%10);
}

while(ss==2) //调时
{
key=0;
timetmp[2]=readbyte(0x85)/16*10+readbyte(0x85)%16; //同上
shanshuo2(7,timetmp[2]);
keynum=jiance();
zj(2);
writebyte(0x84,timetmp[2]/10*16+timetmp[2]%10);
}
while(ss==3) //调日
{
key=0;
timetmp[3]=readbyte(0x87)/16*10+readbyte(0x87)%16; //同上
shanshuo1(9,timetmp[3]);
keynum=jiance();
zj(3);
writebyte(0x86,timetmp[3]/10*16+timetmp[3]%10);
}
while(ss==4) //调月
{
key=0;
timetmp[4]=readbyte(0x89)/16*10+readbyte(0x89)%16;
shanshuo1(6,timetmp[4]);
keynum=jiance();
zj(4);
writebyte(0x88,timetmp[4]/10*16+timetmp[4]%10);
}
while(ss==5) //调周
{
key=0;
timetmp[5]=readbyte(0x8b)/16*10+readbyte(0x8b)%16; //同上
shanshuo1(15,timetmp[5]);
keynum=jiance();
zj(5);
writebyte(0x8a,timetmp[5]/10*16+timetmp[5]%10);
}
while(ss==6) //调年
{
key=0;
timetmp[6]=readbyte(0x8d)/16*10+readbyte(0x8d)%16; //同上
shanshuo1(3,timetmp[6]);
keynum=jiance();
zj(6);
writebyte(0x8c,timetmp[6]/10*16+timetmp[6]%10);
}  
}
}  
 
void main()
{
init_1602(); //初始化1602
writetime(); //首次上电,往1302里面写时间
while(1)
{
readtime(); //从1302中读时间
process(); //把取出的时间(BCD码)转化为十进制
timeout(); //把时间从数组中提取出来
display(); //在1302上显示时间
keynum=jiance(); //检测按键是不是要调整时间
if(keynum==1)
{
ss=0;
jpaction(); //相应调时操作
writebyte(0x80,timetmp[0]/10*16+timetmp[0]%10); //重写秒,把秒写回到调之前的位置
ss=0;
key=0;
}  

  }

}

51单片机DS1302时钟芯片简单程序

#include  #include  #define uchar unsigned char  #define uint unsigned int data_7seg[10]={0xc0,0...
  • qq_36559546
  • qq_36559546
  • 2017年04月18日 20:26
  • 640

51单片机DS1302实时时钟驱动程序

低功耗实时时钟芯片,它可以对年、月、日、周、时、分、秒进行计时,且具有闰年补偿等多种功能。 主要特点是采用串行数据传输,可为掉电保护电源提供可编程的充电功能,并且可以关闭充电功能。...
  • u013151320
  • u013151320
  • 2015年12月12日 11:24
  • 3645

单片机==ds1302_时间日期周几(30)

#include #include "delay.h"#define ds1302_sec_add 0x80 //??¨ºy?Y¦Ì??¡¤ #define ds13...
  • weirdosick
  • weirdosick
  • 2016年10月19日 13:03
  • 549

stc15f204单片机使用ds1302调试

使用stc单片机的准IO口模式,驱动能力太岳
  • zhi379
  • zhi379
  • 2014年05月23日 17:12
  • 1072

DS1302时钟数码管显示

#include #include "ds1302.h" #define KeyPort P3 //定义按键端口 #define DataPort P0 //定义数据端口 程序中遇到DataPo...
  • huangchun96
  • huangchun96
  • 2017年02月09日 16:24
  • 487

51单片机对DS1302突发模式的读写

#include #include #include "DS1302.h"//DS1302管脚 sbit SCLK = P3^6; //时钟 sbit CE = P3^5; ...
  • whileil
  • whileil
  • 2015年04月07日 21:54
  • 1110

基于STM32的DS1302时钟芯片驱动

/***************************************************************************************************...
  • li_qcxy
  • li_qcxy
  • 2017年01月12日 23:38
  • 2005

20141108 【 单片机——万年历DS1302——中断 】 用DS1302模块 & 数码管显示万年历

不得不说, #include #include #define uint unsigned int ...
  • wilson1068
  • wilson1068
  • 2014年11月08日 21:07
  • 931

15.6 DS1302通信时序介绍

DS1302 我们前边也有提起过,是三根线,分别是 CE、I/O 和 SCLK,其中 CE 是使能线,SCLK 是时钟线,I/O 是数据线。前边我们介绍过了 SPI 通信,同学们发现没发现,这个 DS...
  • softn
  • softn
  • 2016年07月09日 07:11
  • 2027

谈一谈单片机开发的几种调试方案

原文地址:http://nicekwell.net/blog/20170411/tan-%5B%3F%5D-tan-dan-pian-ji-kai-fa-de-ji-chong-diao-shi-fa...
  • nicekwell
  • nicekwell
  • 2017年04月12日 01:58
  • 1191
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:单片机 DS1302 痛苦的调试过程,把我的经验教训分享给大家,希望能给后来者一点帮助
举报原因:
原因补充:

(最多只允许输入30个字)