关于DS12RC887读数据问题
时间:10-02
整理:3721RD
点击:
做了个DS12RC887的时钟 程序方面还是有点问题。就是我的程序从头到尾都没有把二进制的数据转换为十进制。但是数码管还是显示正常。这个是为什么。就是从DS12RC887里读数据口读回来就直接提取十位 个位 然后找到显示数组。直接显示。
程序是这样的
#include <reg52.h>//52单片机头文件
#define uint unsigned int//宏定义
#define uchar unsigned char//宏定义
uchar shiw,wan,qian,bai,shi,ge,s1num;
//设置几个关于显示的变量
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0};//段选代码
uchar shige,fen,miao;//时间变量 时, 分, 秒
bit flag;//标志位
//DS12CR887的四个位声明
sbit dscs=P1^0;//片选信号
sbit dsas=P1^1;//地址选通输入
sbit dsrw=P1^2;//读/写输入
sbit dsds=P1^3;//数据选通或读输入
sbit s1=P3^4;//功能键
sbit s2=P3^5;//加
sbit s3=P3^6;//减
sbit dula=P1^4;
sbit wela=P1^5;
/*函数1,延时函数*/
void delay(uint z)//延时子函数1MS
{
uint x,y;
for(x=z;x>0;x--)
for(y=114;y>0;y--);
}
//函数2从DS12DS12RC887中读取数据
uchar read_ds(uchar add)//数据读取
{
uchar date;
dsas=1;
dsds=1;
dsrw=1;
dscs=0;
P0=add;
dsas=0;
dsds=0;
P0=0xff;//读取P0口先给P0口全赋个一
date=P0;
dsds=1;
dsas=1;
dscs=1;
return date;
}
//函数3写数据进DS12RC887,地址与数据
void write_ds(uchar add,uchar date)//DS12CR887数据写入
{
dsas=1;
dsds=1;
dsrw=1;
dscs=0;
P0=add;
dsas=0;
dsrw=0;
P0=date;
dsrw=1;
dsas=1;
dscs=1;
}
//函数4数码管显示函数
void display(uchar shiw,uchar wan,uchar qian,uchar bai,uchar shi,uchar ge)//6位显示子函数
{
dula=1; //开段选
P2=table[shiw]; //送时的十位
dula=0; //关段选
P2=0xff; //消隐
wela=1; //开位选
P2=0xfe; //选通时的十位
wela=0; //关位选
P2=0xff; //消隐
delay(2);
dula=1; //开段选
P2=table[wan]; //送时的个位
dula=0; //关段选
P2=0xff; //消隐
wela=1; //开位选
P2=0xfd; //选通时的个位
wela=0; //关位选
P2=0xff; //消隐
delay(2);
dula=1; //开段选
P2=table[qian]; //送分的十位
dula=0; //关段选
P2=0xff; //消隐
wela=1; //开位选
P2=0xfb; //选通分的十位
wela=0; //关位选
P2=0xff; //消隐
delay(2);
dula=1; //开段选
P2=table[bai]; //送分的个位
dula=0; //关段选
P2=0xff; //消隐
wela=1; //开位选
P2=0xf7; //选通分的个位
wela=0; //关位选
P2=0xff; //消隐
delay(2);
dula=1; //开段选
P2=table[shi]; //送秒的十位
dula=0; //关段选
P2=0xff; //消隐
wela=1; //开位选
P2=0xef; //选通秒的十位
wela=0; //关位选
P2=0xff; //消隐
delay(2);
dula=1; //开段选
P2=table[ge]; //送秒的个位
dula=0; //关段选
P2=0xff; //消隐
wela=1; //开位选
P2=0xdf; //选通秒的个位
wela=0; //关位选
P2=0xff; //消隐
delay(2);
}
//函数5功能键函数,停止显示和进入时间的调节
void gnj()//功能键子函数
{
if(s1==0)//功能键
{
delay(5);//消抖
if(s1==0)//确认功能键按下
{
s1num++;//功能键按下次数加1
flag=1; //flag=1将停止显示数据的刷新
while(!s1);//松手检测
if(s1num==1)//如果按下1次,秒不动作
{
}
if(s1num==2)//如果按下2次,分不动作
{
}
if(s1num==3)//如果按下3次,时不动作
{
}
if(s1num==4)//如果按下4次,正常显示
{
s1num=0;//将s1num清零
write_ds(4,shige);//写时数据
write_ds(2,fen);//写分数据
write_ds(0,miao);//写秒数据
flag=0;//把调节好的数据保存进DS12RC887中,并且恢复显示
}
}
}
}
//函数6,加键函数
void jia()//加子函数
{
if(s2==0)//加键
{
delay(1);//消抖
if(s2==0)//确定S2为0
{
while(!s2);//松手检测
if(s1num==1)//在S1按下一次时
{
miao++;//秒加1
if(miao==60)//秒加到60
miao=0;//将秒清零
display(shiw,wan,qian,bai,shi,ge);//调用数码管显示子函数
}
if(s1num==2)//在S1按下二次时
{
fen++;//分加1
if(fen==60)//分加到60
fen=0;//将分清零
display(shiw,wan,qian,bai,shi,ge);//调用数码管显示子函数
}
if(s1num==3)//在S1按下三次时
{
shige++;//时加1
if(shige==24)//时加到24
shige=0;//时清零
display(shiw,wan,qian,bai,shi,ge);//调用数码管显示子函数
}
}
}
}
//函数7,减函数调节
void jian()//减子函数
{
if(s3==0)//减键
{
delay(1);//消抖
if(s3==0)//确定S3按下
{
while(!s3);//松手检测
if(s1num==1)//在S1按下一次时
{
miao--;//秒减一
if(miao==-1)//秒小于0
miao=59;//秒重新赋值为59
display(shiw,wan,qian,bai,shi,ge);//调用数码管显示子函数
}
if(s1num==2)//在S1按下二次时
{
fen--;//分减一
if(fen==-1)//分小于0
fen=59;//分重新赋值为59
display(shiw,wan,qian,bai,shi,ge);//调用数码管显示子函数
}
if(s1num==3)//在S1按下三次时
{
shige--;//时减一
if(shige==-1)//时小于0
shige=23;//时重新赋值23
display(shiw,wan,qian,bai,shi,ge);//调用数码管显示子函数
}
}
}
}
//函数8,按键扫描函数
void keyscan()//按键输入函数
{
gnj();//功能键子函数
if(s1num!=0)///判断S1键是否按下
{
jia();//加子函数
jian();//减子函数
}
}
//函数9,调节时间时数码管闪烁函数
void sansuo()
{
uchar num,num1;
if(s1num==1)//如果按下1次,秒
{
for(num=25;num>0;num--)
{
display(shiw,wan,qian,bai,11,11);
jia();
jian();//在闪烁同时检测按键,提高扫描率
gnj();
}
for(num1=25;num1>0;num1--)//如果按下1次,秒
{
display(shiw,wan,qian,bai,shi,ge);
jia();
jian();//在闪烁同时检测按键,提高扫描率
gnj();
}
}
if(s1num==2)//如果按下1次,秒
{
for(num=25;num>0;num--)
{
display(shiw,wan,11,11,shi,ge);
jia();
jian();//在闪烁同时检测按键,提高扫描率
gnj();
}
for(num1=25;num1>0;num1--)//如果按下1次,秒
{
display(shiw,wan,qian,bai,shi,ge);
jia();
jian();//在闪烁同时检测按键,提高扫描率
gnj();
}
}
if(s1num==3)//如果按下1次,秒
{
for(num=25;num>0;num--)
{
display(11,11,qian,bai,shi,ge);
jia();
jian();//在闪烁同时检测按键,提高扫描率
gnj();
}
for(num1=25;num1>0;num1--)//如果按下1次,秒
{
display(shiw,wan,qian,bai,shi,ge);
jia();
jian();//在闪烁同时检测按键,提高扫描率
gnj();
}
}
}
void main()//主函数
{
write_ds(0x0B,0x06);//二进制格式,24小时制
write_ds(0x0A,0x20); //开启内部振荡
wela=1; //开位选
P1=0x00;
wela=0; //关位选
while(1)//大循环
{
keyscan();//键盘扫描
if(flag==0)//在S1没有按下时,flag为0
{
shige=read_ds(4); //读取时
fen=read_ds(2);//读取分
miao=read_ds(0);//读取秒
}
sansuo();
shiw=shige/10;//小时的十位
wan=shige%10;//小时的个位
qian=fen/10;//分钟的十位
bai=fen%10;//分钟的个位
shi=miao/10;//秒钟的十位
ge=miao%10;//秒钟的个位
display(shiw,wan,qian,bai,shi,ge);//调用显示函数
}
}
程序是这样的
#include <reg52.h>//52单片机头文件
#define uint unsigned int//宏定义
#define uchar unsigned char//宏定义
uchar shiw,wan,qian,bai,shi,ge,s1num;
//设置几个关于显示的变量
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0};//段选代码
uchar shige,fen,miao;//时间变量 时, 分, 秒
bit flag;//标志位
//DS12CR887的四个位声明
sbit dscs=P1^0;//片选信号
sbit dsas=P1^1;//地址选通输入
sbit dsrw=P1^2;//读/写输入
sbit dsds=P1^3;//数据选通或读输入
sbit s1=P3^4;//功能键
sbit s2=P3^5;//加
sbit s3=P3^6;//减
sbit dula=P1^4;
sbit wela=P1^5;
/*函数1,延时函数*/
void delay(uint z)//延时子函数1MS
{
uint x,y;
for(x=z;x>0;x--)
for(y=114;y>0;y--);
}
//函数2从DS12DS12RC887中读取数据
uchar read_ds(uchar add)//数据读取
{
uchar date;
dsas=1;
dsds=1;
dsrw=1;
dscs=0;
P0=add;
dsas=0;
dsds=0;
P0=0xff;//读取P0口先给P0口全赋个一
date=P0;
dsds=1;
dsas=1;
dscs=1;
return date;
}
//函数3写数据进DS12RC887,地址与数据
void write_ds(uchar add,uchar date)//DS12CR887数据写入
{
dsas=1;
dsds=1;
dsrw=1;
dscs=0;
P0=add;
dsas=0;
dsrw=0;
P0=date;
dsrw=1;
dsas=1;
dscs=1;
}
//函数4数码管显示函数
void display(uchar shiw,uchar wan,uchar qian,uchar bai,uchar shi,uchar ge)//6位显示子函数
{
dula=1; //开段选
P2=table[shiw]; //送时的十位
dula=0; //关段选
P2=0xff; //消隐
wela=1; //开位选
P2=0xfe; //选通时的十位
wela=0; //关位选
P2=0xff; //消隐
delay(2);
dula=1; //开段选
P2=table[wan]; //送时的个位
dula=0; //关段选
P2=0xff; //消隐
wela=1; //开位选
P2=0xfd; //选通时的个位
wela=0; //关位选
P2=0xff; //消隐
delay(2);
dula=1; //开段选
P2=table[qian]; //送分的十位
dula=0; //关段选
P2=0xff; //消隐
wela=1; //开位选
P2=0xfb; //选通分的十位
wela=0; //关位选
P2=0xff; //消隐
delay(2);
dula=1; //开段选
P2=table[bai]; //送分的个位
dula=0; //关段选
P2=0xff; //消隐
wela=1; //开位选
P2=0xf7; //选通分的个位
wela=0; //关位选
P2=0xff; //消隐
delay(2);
dula=1; //开段选
P2=table[shi]; //送秒的十位
dula=0; //关段选
P2=0xff; //消隐
wela=1; //开位选
P2=0xef; //选通秒的十位
wela=0; //关位选
P2=0xff; //消隐
delay(2);
dula=1; //开段选
P2=table[ge]; //送秒的个位
dula=0; //关段选
P2=0xff; //消隐
wela=1; //开位选
P2=0xdf; //选通秒的个位
wela=0; //关位选
P2=0xff; //消隐
delay(2);
}
//函数5功能键函数,停止显示和进入时间的调节
void gnj()//功能键子函数
{
if(s1==0)//功能键
{
delay(5);//消抖
if(s1==0)//确认功能键按下
{
s1num++;//功能键按下次数加1
flag=1; //flag=1将停止显示数据的刷新
while(!s1);//松手检测
if(s1num==1)//如果按下1次,秒不动作
{
}
if(s1num==2)//如果按下2次,分不动作
{
}
if(s1num==3)//如果按下3次,时不动作
{
}
if(s1num==4)//如果按下4次,正常显示
{
s1num=0;//将s1num清零
write_ds(4,shige);//写时数据
write_ds(2,fen);//写分数据
write_ds(0,miao);//写秒数据
flag=0;//把调节好的数据保存进DS12RC887中,并且恢复显示
}
}
}
}
//函数6,加键函数
void jia()//加子函数
{
if(s2==0)//加键
{
delay(1);//消抖
if(s2==0)//确定S2为0
{
while(!s2);//松手检测
if(s1num==1)//在S1按下一次时
{
miao++;//秒加1
if(miao==60)//秒加到60
miao=0;//将秒清零
display(shiw,wan,qian,bai,shi,ge);//调用数码管显示子函数
}
if(s1num==2)//在S1按下二次时
{
fen++;//分加1
if(fen==60)//分加到60
fen=0;//将分清零
display(shiw,wan,qian,bai,shi,ge);//调用数码管显示子函数
}
if(s1num==3)//在S1按下三次时
{
shige++;//时加1
if(shige==24)//时加到24
shige=0;//时清零
display(shiw,wan,qian,bai,shi,ge);//调用数码管显示子函数
}
}
}
}
//函数7,减函数调节
void jian()//减子函数
{
if(s3==0)//减键
{
delay(1);//消抖
if(s3==0)//确定S3按下
{
while(!s3);//松手检测
if(s1num==1)//在S1按下一次时
{
miao--;//秒减一
if(miao==-1)//秒小于0
miao=59;//秒重新赋值为59
display(shiw,wan,qian,bai,shi,ge);//调用数码管显示子函数
}
if(s1num==2)//在S1按下二次时
{
fen--;//分减一
if(fen==-1)//分小于0
fen=59;//分重新赋值为59
display(shiw,wan,qian,bai,shi,ge);//调用数码管显示子函数
}
if(s1num==3)//在S1按下三次时
{
shige--;//时减一
if(shige==-1)//时小于0
shige=23;//时重新赋值23
display(shiw,wan,qian,bai,shi,ge);//调用数码管显示子函数
}
}
}
}
//函数8,按键扫描函数
void keyscan()//按键输入函数
{
gnj();//功能键子函数
if(s1num!=0)///判断S1键是否按下
{
jia();//加子函数
jian();//减子函数
}
}
//函数9,调节时间时数码管闪烁函数
void sansuo()
{
uchar num,num1;
if(s1num==1)//如果按下1次,秒
{
for(num=25;num>0;num--)
{
display(shiw,wan,qian,bai,11,11);
jia();
jian();//在闪烁同时检测按键,提高扫描率
gnj();
}
for(num1=25;num1>0;num1--)//如果按下1次,秒
{
display(shiw,wan,qian,bai,shi,ge);
jia();
jian();//在闪烁同时检测按键,提高扫描率
gnj();
}
}
if(s1num==2)//如果按下1次,秒
{
for(num=25;num>0;num--)
{
display(shiw,wan,11,11,shi,ge);
jia();
jian();//在闪烁同时检测按键,提高扫描率
gnj();
}
for(num1=25;num1>0;num1--)//如果按下1次,秒
{
display(shiw,wan,qian,bai,shi,ge);
jia();
jian();//在闪烁同时检测按键,提高扫描率
gnj();
}
}
if(s1num==3)//如果按下1次,秒
{
for(num=25;num>0;num--)
{
display(11,11,qian,bai,shi,ge);
jia();
jian();//在闪烁同时检测按键,提高扫描率
gnj();
}
for(num1=25;num1>0;num1--)//如果按下1次,秒
{
display(shiw,wan,qian,bai,shi,ge);
jia();
jian();//在闪烁同时检测按键,提高扫描率
gnj();
}
}
}
void main()//主函数
{
write_ds(0x0B,0x06);//二进制格式,24小时制
write_ds(0x0A,0x20); //开启内部振荡
wela=1; //开位选
P1=0x00;
wela=0; //关位选
while(1)//大循环
{
keyscan();//键盘扫描
if(flag==0)//在S1没有按下时,flag为0
{
shige=read_ds(4); //读取时
fen=read_ds(2);//读取分
miao=read_ds(0);//读取秒
}
sansuo();
shiw=shige/10;//小时的十位
wan=shige%10;//小时的个位
qian=fen/10;//分钟的十位
bai=fen%10;//分钟的个位
shi=miao/10;//秒钟的十位
ge=miao%10;//秒钟的个位
display(shiw,wan,qian,bai,shi,ge);//调用显示函数
}
}
为什么 难道DS12RC887读回来的就是个十进制的?请大神们为我解解这道题。快被折磨奔溃了。
时钟已经放在这里几天了 完全正常 好奇怪
:}
fffghgfhfgfhgghfgddff
我是新手,但是我觉得是这样的
读回来的时分秒是十六进制存储的。然后就没有然后了。
比如读回来时是16秒数据就是0x10......
再然后。就没然后了啊 。
但是程序从头到尾都没有把十六进制转换为十进制的函数。你不觉得奇怪吗?
shi=miao/10;//秒钟的十位
ge=miao%10;//秒钟的个位
这段不就是把16进制的化成10进制的么,因为要分成两部分显示所以就这样算了。
这个是分离十位和个位的数字。。不是转化为十进制
那你说读出来的 miao 这个变量是十六进制的还是十进制的?
理论上是八位的2进制。实际却变成十进制。这是我不明白的地方
uchar read_ds(uchar add)//数据读取
这个函数的返回值类型是unsigned char ,如果读出来的是八个1,返回值就是0xff ,数据的处理是用0xff算的
我发现这个事我说不明白,我的理解就是这样。
bcd码