专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
AVR上的DS1302程序读出来在液晶上显示错误
2019-03-24 18:19
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
51单片机
1458
7
952
为什么我的AVR上的DS1302程序读出来在液晶上显示全部都是55555 此帖出自
小平头技术问答
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
7条回答
youluo
1楼-- · 2019-03-25 03:35
精彩回答 2 元偷偷看……
加载中...
南方孩子
2楼-- · 2019-03-25 07:23
void display()
{
c=DS1302Read(DS1302_HOUR_READ);
write_data(table[c/10]);
delayus(5);
write_data(table[c%10]);
write_data(' ');
delayus(5);
while(1);
c=DS1302Read(DS1302_MINUTE_READ);
write_data(table[c/10]);
delayus(5);
write_data(table[c%10]);
write_data(' ');
delayus(5);
c=DS1302Read(DS1302_SECOND_READ);
write_data(table[c/10]);
delayus(5);
write_data(table[c%10]);
write_data(' ');
delayus(5);
write_com(0x80+0x40);
c=DS1302Read(DS1302_DAY_READ);
write_data(table[c/10]);
delayus(5);
write_data(table[c%10]);
write_data(' ');
delayus(5);
c=DS1302Read(DS1302_MONTH_READ);
write_data(table[c/10]);
delayus(5);
write_data(table[c%10]);
write_data(' ');
delayus(5);
c=DS1302Read(DS1302_YEAR_READ);
write_data(table[c/10]);
delayus(5);
write_data(table[c%10]);
write_data(' ');
delayus(5);
write_com(0x01);
delayus(5);
}
加载中...
南方孩子
3楼-- · 2019-03-25 09:47
这是我的显示程序。是不是延时太短了。。急救啊 我是一名单片机菜鸟,这个已经做了好多天了
加载中...
oyueyueniao
4楼-- · 2019-03-25 12:52
精彩回答 2 元偷偷看……
加载中...
南方孩子
5楼-- · 2019-03-25 15:32
oyueyueniao 发表于 2014-4-4 20:07
第一段程序有个while(1);程序岂不是一直在这里死循环?
哦,谢谢,但是我改了还是不行,刚刚一直在想,发现是BCD码转换没有注意到。。。
uchar BcdToBin(uchar val)
{
val = (val >> 4) *10+(val &0x0f); ///将BCD码转换为10进制数
return val; ///返回10进制数
}
但是改了以后还是不行,这次不显示全是5了,液晶上显示3 1 7 。。。数字还是不对,完全不对。而且数字中间有空格,而我的程序里没有加空格。。。
#include<avr/io.h>
#include<util/delay.h>
#include<avr/interrupt.h>
#define uchar unsigned char
#define uint unsigned int
#define delayms(x) _delay_ms(x)
#define delayus(x) _delay_us(x)
#define rsddr DDRD
#define rsport PORTD
#define rspin PIND
#define rwddr DDRD
#define rwport PORTD
#define rwpin PIND
#define enddr DDRD
#define enport PORTD
#define enpin PIND
#define DS1302_SECOND_WRITE 0x80
#define DS1302_MINUTE_WRITE 0x82
#define DS1302_HOUR_WRITE 0x84
#define DS1302_DAY_WRITE 0x86
#define DS1302_MONTH_WRITE 0x88
#define DS1302_WEEK_WRITE 0x8a
#define DS1302_YEAR_WRITE 0x8c
#define DS1302_YEAR_READ 0x8d
#define DS1302_MONTH_READ 0x89
#define DS1302_DAY_READ 0x87
#define DS1302_HOUR_READ 0x85
#define DS1302_MINUTE_READ 0x83
#define DS1302_SECOND_READ 0x81
#define RST PORTB
#define SCLK PORTB
#define SDA PORTC
uchar c,shi,ge;
uchar year1=0x88;
uchar year0=0x88;
uchar month1=0x88;
uchar month0=0x88;
uchar date1=0x88;
uchar date0=0x88;
uchar day1=0x88;
uchar day0=0x88;
uchar hour1=0x88;
uchar hour0=0x88;
uchar minute1=0x88;
uchar minute0=0x88;
uchar second1=0x88;
uchar second0=0x88;
uchar table[]={'0','1','2','3','4','5','6','7','8','9','0'};
void DS1302WriteByte(uchar dat)
{
uchar i;
SCLK &=~(1<<7);//初始时钟线置为0
delayus(2);
for(i=0;i<8;i++)//开始传输8字节的数据
{
if(dat&0x01)
{
SDA|=(1<<1);
}
else
{
SDA &=~(1<<1);
}
//取最低位,注意DS1302的数据和地址都是从最低位开始传输的
delayus(2);
SCLK|=(1<<7);//时钟线拉高,制造上升沿,SDA的数据被传输
delayus(2);
SCLK &=~(1<<7);//时钟线拉低,为下一个上升沿做准备
dat>>=1;//数据右移一位,准备传输下一位数据
}
}
uchar DS1302Write(uchar cmd,uchar dat)
{
RST &=~(1<<4);//初始CE线置为0
SCLK &=~(1<<7);//初始时钟线置为0
RST|=(1<<4);//初始化CE置为1,传输开始
DS1302WriteByte(cmd);//传输命令字,要写入的时间/日历地址
DS1302WriteByte(dat);//写入要修改的时间/日期
SCLK|=(1<<7);//时钟线拉高,一个上升沿写入数据
RST &=~(1<<4);//读取结束,CE置为0,结束数据的传输
}
int DS1302ReadByte()
{
DDRC=0x00;////////IO口设为输入
PORTC=0x00;//IO脚要设为高阻状态
RST|=(1<<4);
uchar i,dat;
delayus(2);
for(i=0;i<8;i++)
{
dat>>=1;//要返回的数据右移一位
if(PINA|0x02)//当数据线为高时,证明该位数据为1
{
dat|=0x80;//要传输数据的当前值置为1,若不是,则为0
}
SCLK|=(1<<7);//拉高时钟线
delayus(2);
SCLK &=~(1<<7);//制造下降沿,时钟下降沿才能读取数据
delayus(2);
}
return dat;//返回读取出的数据
}
uchar DS1302Read(uchar cmd)
{
DDRC=0x00;
uchar dat;
RST &=~(1<<4);//初始化CE线置为0
SCLK &=~(1<<7);//初始化时钟线置为0,而且只有sclk为0时才能置rst为1
RST|=(1<<4);//初始化CE置为1,传输开始
DS1302WriteByte(cmd);//传输命令字,要读取的时间/日历地址
dat=DS1302ReadByte();//读取要得到的时间/日期
SCLK|=(1<<7);//时钟线拉高
RST &=~(1<<4);//读取结束,CE置为0,结束数据的传输
return dat;//返回得到的时间/日期
}
void initDS1302(void)
{
DDRA=0xff;
DS1302Write(0x8e,0x00);//写保护关
DS1302Write(DS1302_SECOND_WRITE,0x00);//初始化秒值为0
DS1302Write(DS1302_MINUTE_WRITE,0x20);//初始化分钟值为0
DS1302Write(DS1302_HOUR_WRITE,0x09);//初始化为24小时模式 初始化时间为9点
DS1302Write(DS1302_DAY_WRITE,0x23);//2010年1月1日 星期6 25
DS1302Write(DS1302_MONTH_WRITE,0x04);//12月
DS1302Write(DS1302_YEAR_WRITE,0x95);//10年
// DS1302Write(DS1302_WEEK_WRITE,0x00);
// DS1302Write(DS1302_SECOND_WRITE,0x06);
DS1302Write(0x90,0x01);//充电
DS1302Write(0xc0,0xf0);//初始化一次标示
DS1302Write(0x8e,0x80);//写保护开
}
////液晶显示程
void write_com(uchar com)
{
rsddr|=(1<<0);
rsport &=~(1<<0);
DDRA=0xff;//液晶端口
PORTA=com;
delayms(3);
enddr|=(1<<2);
enport|=(1<<2);
delayms(3);
enport &=~(1<<2);
}
void init()
{
rwddr|=(1<<1);
rwport &=~(1<<1);
enddr|=(1<<2);
enport &=~(1<<2);
write_com(0x38);//显示模式
write_com(0x0e);//开显示 显示光标
write_com(0x06);//当读或写一个字符后地址指针加一
write_com(0x01);//数据指针清零
write_com(0x80);//数据指针初始化
}
void write_data(uchar date)
{
rsddr|=(1<<0);
rsport|=(1<<0);
DDRA=0xff;//液晶端口
PORTA=date;//液晶端口
delayms(3);
enddr|=(1<<2);
enport|=(1<<2);
delayms(3);
enport &=~(1<<2);
}
///////液晶显示程
void display()
{
c=DS1302Read(DS1302_HOUR_READ);
hour0=c&0x0f;
hour1=(c>>4)&0x03;
delayms(10);
write_data(table[hour1]);
delayms(5);
write_data(table[hour0]);
// write_data(' ');
delayms(5);
c=DS1302Read(DS1302_MINUTE_READ);//分
minute0=c&0x0f;
minute1=(c>>4)&0x07;
delayms(10);
write_data(table[minute1]);
delayms(5);
write_data(table[minute0]);
// write_data(' ');
delayms(5);
c=DS1302Read(DS1302_SECOND_READ);//秒
second0=c&0x0f;
second1=(c>>4)&0x07;
delayms(10);
write_data(table[second1]);
delayms(5);
write_data(table[second0]);
// write_data(' ');
delayms(5);
write_com(0x80+0x40);
c=DS1302Read(DS1302_DAY_READ);//日
date0=c&0x0f;
date1=(c>>4)&0x03;//只可能是1-3
delayms(10);
write_data(table[date1]);
delayms(5);
write_data(table[date0]);
// write_data(' ');
delayms(5);
c=DS1302Read(DS1302_MONTH_READ);//月
month0=c&0x0f;//个位
month1=(c>>4)&0x01;//十位只可能是1
delayms(10);
write_data(table[month1]);
delayms(5);
write_data(table[month0]);
// write_data(' ');
delayms(5);
c=DS1302Read(DS1302_YEAR_READ);//年
year0=c&0x0f;//!!!!读到的数的前四位是十位,后四位是个位
year1=c>>4;
delayms(10);
write_data(table[year1]);
delayms(50);
write_data(table[year0]);
// write_data(' ');
delayms(5);
write_com(0x01);//清屏!!!
delayms(50);
}
int main()
{
DDRB=0xff;
rsddr|=(1<<0);
rwddr|=(1<<1);
enddr|=(1<<2);
DDRA=0xff;
init();//初始化液晶1602
sei();//开总中断
initDS1302();
while(1)
{
display();
delayms(500);
}
}
加载中...
南方孩子
6楼-- · 2019-03-25 19:52
#include<avr/io.h>
#include<util/delay.h>
#include<avr/interrupt.h>
#define uchar unsigned char
#define uint unsigned int
#define delayms(x) _delay_ms(x)
#define delayus(x) _delay_us(x)
#define rsddr DDRD
#define rsport PORTD
#define rspin PIND
#define rwddr DDRD
#define rwport PORTD
#define rwpin PIND
#define enddr DDRD
#define enport PORTD
#define enpin PIND
#define DS1302_SECOND_WRITE 0x80
#define DS1302_MINUTE_WRITE 0x82
#define DS1302_HOUR_WRITE 0x84
#define DS1302_DAY_WRITE 0x86
#define DS1302_MONTH_WRITE 0x88
#define DS1302_WEEK_WRITE 0x8a
#define DS1302_YEAR_WRITE 0x8c
#define DS1302_YEAR_READ 0x8d
#define DS1302_MONTH_READ 0x89
#define DS1302_DAY_READ 0x87
#define DS1302_HOUR_READ 0x85
#define DS1302_MINUTE_READ 0x83
#define DS1302_SECOND_READ 0x81
#define RST PORTB
#define SCLK PORTB
#define SDA PORTC
uchar c,shi,ge;
uchar year1=0x88;
uchar year0=0x88;
uchar month1=0x88;
uchar month0=0x88;
uchar date1=0x88;
uchar date0=0x88;
uchar day1=0x88;
uchar day0=0x88;
uchar hour1=0x88;
uchar hour0=0x88;
uchar minute1=0x88;
uchar minute0=0x88;
uchar second1=0x88;
uchar second0=0x88;
uchar table[]={'0','1','2','3','4','5','6','7','8','9','0'};
void DS1302WriteByte(uchar dat)
{
uchar i;
SCLK &=~(1<<7);//初始时钟线置为0
delayus(2);
for(i=0;i<8;i++)//开始传输8字节的数据
{
if(dat&0x01)
{
SDA|=(1<<1);
}
else
{
SDA &=~(1<<1);
}
//取最低位,注意DS1302的数据和地址都是从最低位开始传输的
delayus(2);
SCLK|=(1<<7);//时钟线拉高,制造上升沿,SDA的数据被传输
delayus(2);
SCLK &=~(1<<7);//时钟线拉低,为下一个上升沿做准备
dat>>=1;//数据右移一位,准备传输下一位数据
}
}
uchar DS1302Write(uchar cmd,uchar dat)
{
RST &=~(1<<4);//初始CE线置为0
SCLK &=~(1<<7);//初始时钟线置为0
RST|=(1<<4);//初始化CE置为1,传输开始
DS1302WriteByte(cmd);//传输命令字,要写入的时间/日历地址
DS1302WriteByte(dat);//写入要修改的时间/日期
SCLK|=(1<<7);//时钟线拉高,一个上升沿写入数据
RST &=~(1<<4);//读取结束,CE置为0,结束数据的传输
}
int DS1302ReadByte()
{
DDRC=0x00;////////IO口设为输入
PORTC=0x00;//IO脚要设为高阻状态
RST|=(1<<4);
uchar i,dat;
delayus(2);
for(i=0;i<8;i++)
{
dat>>=1;//要返回的数据右移一位
if(PINA|0x02)//当数据线为高时,证明该位数据为1
{
dat|=0x80;//要传输数据的当前值置为1,若不是,则为0
}
SCLK|=(1<<7);//拉高时钟线
delayus(2);
SCLK &=~(1<<7);//制造下降沿,时钟下降沿才能读取数据
delayus(2);
}
return dat;//返回读取出的数据
}
uchar DS1302Read(uchar cmd)
{
DDRC=0x00;
uchar dat;
RST &=~(1<<4);//初始化CE线置为0
SCLK &=~(1<<7);//初始化时钟线置为0,而且只有sclk为0时才能置rst为1
RST|=(1<<4);//初始化CE置为1,传输开始
DS1302WriteByte(cmd);//传输命令字,要读取的时间/日历地址
dat=DS1302ReadByte();//读取要得到的时间/日期
SCLK|=(1<<7);//时钟线拉高
RST &=~(1<<4);//读取结束,CE置为0,结束数据的传输
return dat;//返回得到的时间/日期
}
void initDS1302(void)
{
DDRA=0xff;
DS1302Write(0x8e,0x00);//写保护关
DS1302Write(DS1302_SECOND_WRITE,0x00);//初始化秒值为0
DS1302Write(DS1302_MINUTE_WRITE,0x20);//初始化分钟值为0
DS1302Write(DS1302_HOUR_WRITE,0x09);//初始化为24小时模式 初始化时间为9点
DS1302Write(DS1302_DAY_WRITE,0x23);//2010年1月1日 星期6 25
DS1302Write(DS1302_MONTH_WRITE,0x04);//12月
DS1302Write(DS1302_YEAR_WRITE,0x95);//10年
// DS1302Write(DS1302_WEEK_WRITE,0x00);
// DS1302Write(DS1302_SECOND_WRITE,0x06);
DS1302Write(0x90,0x01);//充电
DS1302Write(0xc0,0xf0);//初始化一次标示
DS1302Write(0x8e,0x80);//写保护开
}
////液晶显示程序
void write_com(uchar com)
{
rsddr|=(1<<0);
rsport &=~(1<<0);
DDRA=0xff;//液晶端口
PORTA=com;
delayms(3);
enddr|=(1<<2);
enport|=(1<<2);
delayms(3);
enport &=~(1<<2);
}
void init()
{
rwddr|=(1<<1);
rwport &=~(1<<1);
enddr|=(1<<2);
enport &=~(1<<2);
write_com(0x38);//显示模式
write_com(0x0e);//开显示 显示光标
write_com(0x06);//当读或写一个字符后地址指针加一
write_com(0x01);//数据指针清零
write_com(0x80);//数据指针初始化
}
void write_data(uchar date)
{
rsddr|=(1<<0);
rsport|=(1<<0);
DDRA=0xff;//液晶端口
PORTA=date;//液晶端口
delayms(3);
enddr|=(1<<2);
enport|=(1<<2);
delayms(3);
enport &=~(1<<2);
}
///////液晶显示程序
void display()
{
c=DS1302Read(DS1302_HOUR_READ);
hour0=c&0x0f;
hour1=(c>>4)&0x03;
delayms(10);
write_data(table[hour1]);
delayms(5);
write_data(table[hour0]);
// write_data(' ');
delayms(5);
c=DS1302Read(DS1302_MINUTE_READ);//分
minute0=c&0x0f;
minute1=(c>>4)&0x07;
delayms(10);
write_data(table[minute1]);
delayms(5);
write_data(table[minute0]);
// write_data(' ');
delayms(5);
c=DS1302Read(DS1302_SECOND_READ);//秒
second0=c&0x0f;
second1=(c>>4)&0x07;
delayms(10);
write_data(table[second1]);
delayms(5);
write_data(table[second0]);
// write_data(' ');
delayms(5);
write_com(0x80+0x40);
c=DS1302Read(DS1302_DAY_READ);//日
date0=c&0x0f;
date1=(c>>4)&0x03;//只可能是1-3
delayms(10);
write_data(table[date1]);
delayms(5);
write_data(table[date0]);
// write_data(' ');
delayms(5);
c=DS1302Read(DS1302_MONTH_READ);//月
month0=c&0x0f;//个位
month1=(c>>4)&0x01;//十位只可能是1
delayms(10);
write_data(table[month1]);
delayms(5);
write_data(table[month0]);
// write_data(' ');
delayms(5);
c=DS1302Read(DS1302_YEAR_READ);//年
year0=c&0x0f;//!!!!读到的数的前四位是十位,后四位是个位
year1=c>>4;
delayms(10);
write_data(table[year1]);
delayms(50);
write_data(table[year0]);
// write_data(' ');
delayms(5);
write_com(0x01);//清屏!!!
delayms(50);
}
int main()
{
DDRB=0xff;
rsddr|=(1<<0);
rwddr|=(1<<1);
enddr|=(1<<2);
DDRA=0xff;
init();//初始化液晶1602
sei();//开总中断
initDS1302();
while(1)
{
display();
delayms(500);
}
}
加载中...
1
2
下一页
一周热门
更多
>
相关问题
相关文章
基于51单片机的计算器设计
0个评论
51单片机300个proteus仿真实例下载
0个评论
51单片机 蜂鸣器
0个评论
51单片机驱动RC522模块
0个评论
基于51单片机的指纹密码锁
0个评论
AT89C51单片机制作简易密码锁
0个评论
51单片机汇编语言计数器
0个评论
51单片机精确延时设计
0个评论
×
关闭
采纳回答
向帮助了您的网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
关闭
您已邀请
15
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
{
c=DS1302Read(DS1302_HOUR_READ);
write_data(table[c/10]);
delayus(5);
write_data(table[c%10]);
write_data(' ');
delayus(5);
while(1);
c=DS1302Read(DS1302_MINUTE_READ);
write_data(table[c/10]);
delayus(5);
write_data(table[c%10]);
write_data(' ');
delayus(5);
c=DS1302Read(DS1302_SECOND_READ);
write_data(table[c/10]);
delayus(5);
write_data(table[c%10]);
write_data(' ');
delayus(5);
write_com(0x80+0x40);
c=DS1302Read(DS1302_DAY_READ);
write_data(table[c/10]);
delayus(5);
write_data(table[c%10]);
write_data(' ');
delayus(5);
c=DS1302Read(DS1302_MONTH_READ);
write_data(table[c/10]);
delayus(5);
write_data(table[c%10]);
write_data(' ');
delayus(5);
c=DS1302Read(DS1302_YEAR_READ);
write_data(table[c/10]);
delayus(5);
write_data(table[c%10]);
write_data(' ');
delayus(5);
write_com(0x01);
delayus(5);
}
哦,谢谢,但是我改了还是不行,刚刚一直在想,发现是BCD码转换没有注意到。。。uchar BcdToBin(uchar val)
{
val = (val >> 4) *10+(val &0x0f); ///将BCD码转换为10进制数
return val; ///返回10进制数
}
但是改了以后还是不行,这次不显示全是5了,液晶上显示3 1 7 。。。数字还是不对,完全不对。而且数字中间有空格,而我的程序里没有加空格。。。
#include<avr/io.h>
#include<util/delay.h>
#include<avr/interrupt.h>
#define uchar unsigned char
#define uint unsigned int
#define delayms(x) _delay_ms(x)
#define delayus(x) _delay_us(x)
#define rsddr DDRD
#define rsport PORTD
#define rspin PIND
#define rwddr DDRD
#define rwport PORTD
#define rwpin PIND
#define enddr DDRD
#define enport PORTD
#define enpin PIND
#define DS1302_SECOND_WRITE 0x80
#define DS1302_MINUTE_WRITE 0x82
#define DS1302_HOUR_WRITE 0x84
#define DS1302_DAY_WRITE 0x86
#define DS1302_MONTH_WRITE 0x88
#define DS1302_WEEK_WRITE 0x8a
#define DS1302_YEAR_WRITE 0x8c
#define DS1302_YEAR_READ 0x8d
#define DS1302_MONTH_READ 0x89
#define DS1302_DAY_READ 0x87
#define DS1302_HOUR_READ 0x85
#define DS1302_MINUTE_READ 0x83
#define DS1302_SECOND_READ 0x81
#define RST PORTB
#define SCLK PORTB
#define SDA PORTC
uchar c,shi,ge;
uchar year1=0x88;
uchar year0=0x88;
uchar month1=0x88;
uchar month0=0x88;
uchar date1=0x88;
uchar date0=0x88;
uchar day1=0x88;
uchar day0=0x88;
uchar hour1=0x88;
uchar hour0=0x88;
uchar minute1=0x88;
uchar minute0=0x88;
uchar second1=0x88;
uchar second0=0x88;
uchar table[]={'0','1','2','3','4','5','6','7','8','9','0'};
void DS1302WriteByte(uchar dat)
{
uchar i;
SCLK &=~(1<<7);//初始时钟线置为0
delayus(2);
for(i=0;i<8;i++)//开始传输8字节的数据
{
if(dat&0x01)
{
SDA|=(1<<1);
}
else
{
SDA &=~(1<<1);
}
//取最低位,注意DS1302的数据和地址都是从最低位开始传输的
delayus(2);
SCLK|=(1<<7);//时钟线拉高,制造上升沿,SDA的数据被传输
delayus(2);
SCLK &=~(1<<7);//时钟线拉低,为下一个上升沿做准备
dat>>=1;//数据右移一位,准备传输下一位数据
}
}
uchar DS1302Write(uchar cmd,uchar dat)
{
RST &=~(1<<4);//初始CE线置为0
SCLK &=~(1<<7);//初始时钟线置为0
RST|=(1<<4);//初始化CE置为1,传输开始
DS1302WriteByte(cmd);//传输命令字,要写入的时间/日历地址
DS1302WriteByte(dat);//写入要修改的时间/日期
SCLK|=(1<<7);//时钟线拉高,一个上升沿写入数据
RST &=~(1<<4);//读取结束,CE置为0,结束数据的传输
}
int DS1302ReadByte()
{
DDRC=0x00;////////IO口设为输入
PORTC=0x00;//IO脚要设为高阻状态
RST|=(1<<4);
uchar i,dat;
delayus(2);
for(i=0;i<8;i++)
{
dat>>=1;//要返回的数据右移一位
if(PINA|0x02)//当数据线为高时,证明该位数据为1
{
dat|=0x80;//要传输数据的当前值置为1,若不是,则为0
}
SCLK|=(1<<7);//拉高时钟线
delayus(2);
SCLK &=~(1<<7);//制造下降沿,时钟下降沿才能读取数据
delayus(2);
}
return dat;//返回读取出的数据
}
uchar DS1302Read(uchar cmd)
{
DDRC=0x00;
uchar dat;
RST &=~(1<<4);//初始化CE线置为0
SCLK &=~(1<<7);//初始化时钟线置为0,而且只有sclk为0时才能置rst为1
RST|=(1<<4);//初始化CE置为1,传输开始
DS1302WriteByte(cmd);//传输命令字,要读取的时间/日历地址
dat=DS1302ReadByte();//读取要得到的时间/日期
SCLK|=(1<<7);//时钟线拉高
RST &=~(1<<4);//读取结束,CE置为0,结束数据的传输
return dat;//返回得到的时间/日期
}
void initDS1302(void)
{
DDRA=0xff;
DS1302Write(0x8e,0x00);//写保护关
DS1302Write(DS1302_SECOND_WRITE,0x00);//初始化秒值为0
DS1302Write(DS1302_MINUTE_WRITE,0x20);//初始化分钟值为0
DS1302Write(DS1302_HOUR_WRITE,0x09);//初始化为24小时模式 初始化时间为9点
DS1302Write(DS1302_DAY_WRITE,0x23);//2010年1月1日 星期6 25
DS1302Write(DS1302_MONTH_WRITE,0x04);//12月
DS1302Write(DS1302_YEAR_WRITE,0x95);//10年
// DS1302Write(DS1302_WEEK_WRITE,0x00);
// DS1302Write(DS1302_SECOND_WRITE,0x06);
DS1302Write(0x90,0x01);//充电
DS1302Write(0xc0,0xf0);//初始化一次标示
DS1302Write(0x8e,0x80);//写保护开
}
////液晶显示程
void write_com(uchar com)
{
rsddr|=(1<<0);
rsport &=~(1<<0);
DDRA=0xff;//液晶端口
PORTA=com;
delayms(3);
enddr|=(1<<2);
enport|=(1<<2);
delayms(3);
enport &=~(1<<2);
}
void init()
{
rwddr|=(1<<1);
rwport &=~(1<<1);
enddr|=(1<<2);
enport &=~(1<<2);
write_com(0x38);//显示模式
write_com(0x0e);//开显示 显示光标
write_com(0x06);//当读或写一个字符后地址指针加一
write_com(0x01);//数据指针清零
write_com(0x80);//数据指针初始化
}
void write_data(uchar date)
{
rsddr|=(1<<0);
rsport|=(1<<0);
DDRA=0xff;//液晶端口
PORTA=date;//液晶端口
delayms(3);
enddr|=(1<<2);
enport|=(1<<2);
delayms(3);
enport &=~(1<<2);
}
///////液晶显示程
void display()
{
c=DS1302Read(DS1302_HOUR_READ);
hour0=c&0x0f;
hour1=(c>>4)&0x03;
delayms(10);
write_data(table[hour1]);
delayms(5);
write_data(table[hour0]);
// write_data(' ');
delayms(5);
c=DS1302Read(DS1302_MINUTE_READ);//分
minute0=c&0x0f;
minute1=(c>>4)&0x07;
delayms(10);
write_data(table[minute1]);
delayms(5);
write_data(table[minute0]);
// write_data(' ');
delayms(5);
c=DS1302Read(DS1302_SECOND_READ);//秒
second0=c&0x0f;
second1=(c>>4)&0x07;
delayms(10);
write_data(table[second1]);
delayms(5);
write_data(table[second0]);
// write_data(' ');
delayms(5);
write_com(0x80+0x40);
c=DS1302Read(DS1302_DAY_READ);//日
date0=c&0x0f;
date1=(c>>4)&0x03;//只可能是1-3
delayms(10);
write_data(table[date1]);
delayms(5);
write_data(table[date0]);
// write_data(' ');
delayms(5);
c=DS1302Read(DS1302_MONTH_READ);//月
month0=c&0x0f;//个位
month1=(c>>4)&0x01;//十位只可能是1
delayms(10);
write_data(table[month1]);
delayms(5);
write_data(table[month0]);
// write_data(' ');
delayms(5);
c=DS1302Read(DS1302_YEAR_READ);//年
year0=c&0x0f;//!!!!读到的数的前四位是十位,后四位是个位
year1=c>>4;
delayms(10);
write_data(table[year1]);
delayms(50);
write_data(table[year0]);
// write_data(' ');
delayms(5);
write_com(0x01);//清屏!!!
delayms(50);
}
int main()
{
DDRB=0xff;
rsddr|=(1<<0);
rwddr|=(1<<1);
enddr|=(1<<2);
DDRA=0xff;
init();//初始化液晶1602
sei();//开总中断
initDS1302();
while(1)
{
display();
delayms(500);
}
}
#include<util/delay.h>
#include<avr/interrupt.h>
#define uchar unsigned char
#define uint unsigned int
#define delayms(x) _delay_ms(x)
#define delayus(x) _delay_us(x)
#define rsddr DDRD
#define rsport PORTD
#define rspin PIND
#define rwddr DDRD
#define rwport PORTD
#define rwpin PIND
#define enddr DDRD
#define enport PORTD
#define enpin PIND
#define DS1302_SECOND_WRITE 0x80
#define DS1302_MINUTE_WRITE 0x82
#define DS1302_HOUR_WRITE 0x84
#define DS1302_DAY_WRITE 0x86
#define DS1302_MONTH_WRITE 0x88
#define DS1302_WEEK_WRITE 0x8a
#define DS1302_YEAR_WRITE 0x8c
#define DS1302_YEAR_READ 0x8d
#define DS1302_MONTH_READ 0x89
#define DS1302_DAY_READ 0x87
#define DS1302_HOUR_READ 0x85
#define DS1302_MINUTE_READ 0x83
#define DS1302_SECOND_READ 0x81
#define RST PORTB
#define SCLK PORTB
#define SDA PORTC
uchar c,shi,ge;
uchar year1=0x88;
uchar year0=0x88;
uchar month1=0x88;
uchar month0=0x88;
uchar date1=0x88;
uchar date0=0x88;
uchar day1=0x88;
uchar day0=0x88;
uchar hour1=0x88;
uchar hour0=0x88;
uchar minute1=0x88;
uchar minute0=0x88;
uchar second1=0x88;
uchar second0=0x88;
uchar table[]={'0','1','2','3','4','5','6','7','8','9','0'};
void DS1302WriteByte(uchar dat)
{
uchar i;
SCLK &=~(1<<7);//初始时钟线置为0
delayus(2);
for(i=0;i<8;i++)//开始传输8字节的数据
{
if(dat&0x01)
{
SDA|=(1<<1);
}
else
{
SDA &=~(1<<1);
}
//取最低位,注意DS1302的数据和地址都是从最低位开始传输的
delayus(2);
SCLK|=(1<<7);//时钟线拉高,制造上升沿,SDA的数据被传输
delayus(2);
SCLK &=~(1<<7);//时钟线拉低,为下一个上升沿做准备
dat>>=1;//数据右移一位,准备传输下一位数据
}
}
uchar DS1302Write(uchar cmd,uchar dat)
{
RST &=~(1<<4);//初始CE线置为0
SCLK &=~(1<<7);//初始时钟线置为0
RST|=(1<<4);//初始化CE置为1,传输开始
DS1302WriteByte(cmd);//传输命令字,要写入的时间/日历地址
DS1302WriteByte(dat);//写入要修改的时间/日期
SCLK|=(1<<7);//时钟线拉高,一个上升沿写入数据
RST &=~(1<<4);//读取结束,CE置为0,结束数据的传输
}
int DS1302ReadByte()
{
DDRC=0x00;////////IO口设为输入
PORTC=0x00;//IO脚要设为高阻状态
RST|=(1<<4);
uchar i,dat;
delayus(2);
for(i=0;i<8;i++)
{
dat>>=1;//要返回的数据右移一位
if(PINA|0x02)//当数据线为高时,证明该位数据为1
{
dat|=0x80;//要传输数据的当前值置为1,若不是,则为0
}
SCLK|=(1<<7);//拉高时钟线
delayus(2);
SCLK &=~(1<<7);//制造下降沿,时钟下降沿才能读取数据
delayus(2);
}
return dat;//返回读取出的数据
}
uchar DS1302Read(uchar cmd)
{
DDRC=0x00;
uchar dat;
RST &=~(1<<4);//初始化CE线置为0
SCLK &=~(1<<7);//初始化时钟线置为0,而且只有sclk为0时才能置rst为1
RST|=(1<<4);//初始化CE置为1,传输开始
DS1302WriteByte(cmd);//传输命令字,要读取的时间/日历地址
dat=DS1302ReadByte();//读取要得到的时间/日期
SCLK|=(1<<7);//时钟线拉高
RST &=~(1<<4);//读取结束,CE置为0,结束数据的传输
return dat;//返回得到的时间/日期
}
void initDS1302(void)
{
DDRA=0xff;
DS1302Write(0x8e,0x00);//写保护关
DS1302Write(DS1302_SECOND_WRITE,0x00);//初始化秒值为0
DS1302Write(DS1302_MINUTE_WRITE,0x20);//初始化分钟值为0
DS1302Write(DS1302_HOUR_WRITE,0x09);//初始化为24小时模式 初始化时间为9点
DS1302Write(DS1302_DAY_WRITE,0x23);//2010年1月1日 星期6 25
DS1302Write(DS1302_MONTH_WRITE,0x04);//12月
DS1302Write(DS1302_YEAR_WRITE,0x95);//10年
// DS1302Write(DS1302_WEEK_WRITE,0x00);
// DS1302Write(DS1302_SECOND_WRITE,0x06);
DS1302Write(0x90,0x01);//充电
DS1302Write(0xc0,0xf0);//初始化一次标示
DS1302Write(0x8e,0x80);//写保护开
}
////液晶显示程序
void write_com(uchar com)
{
rsddr|=(1<<0);
rsport &=~(1<<0);
DDRA=0xff;//液晶端口
PORTA=com;
delayms(3);
enddr|=(1<<2);
enport|=(1<<2);
delayms(3);
enport &=~(1<<2);
}
void init()
{
rwddr|=(1<<1);
rwport &=~(1<<1);
enddr|=(1<<2);
enport &=~(1<<2);
write_com(0x38);//显示模式
write_com(0x0e);//开显示 显示光标
write_com(0x06);//当读或写一个字符后地址指针加一
write_com(0x01);//数据指针清零
write_com(0x80);//数据指针初始化
}
void write_data(uchar date)
{
rsddr|=(1<<0);
rsport|=(1<<0);
DDRA=0xff;//液晶端口
PORTA=date;//液晶端口
delayms(3);
enddr|=(1<<2);
enport|=(1<<2);
delayms(3);
enport &=~(1<<2);
}
///////液晶显示程序
void display()
{
c=DS1302Read(DS1302_HOUR_READ);
hour0=c&0x0f;
hour1=(c>>4)&0x03;
delayms(10);
write_data(table[hour1]);
delayms(5);
write_data(table[hour0]);
// write_data(' ');
delayms(5);
c=DS1302Read(DS1302_MINUTE_READ);//分
minute0=c&0x0f;
minute1=(c>>4)&0x07;
delayms(10);
write_data(table[minute1]);
delayms(5);
write_data(table[minute0]);
// write_data(' ');
delayms(5);
c=DS1302Read(DS1302_SECOND_READ);//秒
second0=c&0x0f;
second1=(c>>4)&0x07;
delayms(10);
write_data(table[second1]);
delayms(5);
write_data(table[second0]);
// write_data(' ');
delayms(5);
write_com(0x80+0x40);
c=DS1302Read(DS1302_DAY_READ);//日
date0=c&0x0f;
date1=(c>>4)&0x03;//只可能是1-3
delayms(10);
write_data(table[date1]);
delayms(5);
write_data(table[date0]);
// write_data(' ');
delayms(5);
c=DS1302Read(DS1302_MONTH_READ);//月
month0=c&0x0f;//个位
month1=(c>>4)&0x01;//十位只可能是1
delayms(10);
write_data(table[month1]);
delayms(5);
write_data(table[month0]);
// write_data(' ');
delayms(5);
c=DS1302Read(DS1302_YEAR_READ);//年
year0=c&0x0f;//!!!!读到的数的前四位是十位,后四位是个位
year1=c>>4;
delayms(10);
write_data(table[year1]);
delayms(50);
write_data(table[year0]);
// write_data(' ');
delayms(5);
write_com(0x01);//清屏!!!
delayms(50);
}
int main()
{
DDRB=0xff;
rsddr|=(1<<0);
rwddr|=(1<<1);
enddr|=(1<<2);
DDRA=0xff;
init();//初始化液晶1602
sei();//开总中断
initDS1302();
while(1)
{
display();
delayms(500);
}
}
一周热门 更多>