求大神!哪里有DS1302的时钟程序????给悬赏!!!最好用keil写的!!!!
答案:1 悬赏:10 手机版
解决时间 2021-03-23 11:12
- 提问者网友:佞臣
- 2021-03-22 18:08
求大神!哪里有DS1302的时钟程序????给悬赏!!!最好用keil写的!!!!
最佳答案
- 五星知识达人网友:像个废品
- 2021-03-22 18:19
1302+1602 万年历
#include
#include
#define uchar unsigned char
#define uint unsigned int
uchar idata lcd1[]={"2011年04月10日$$"}; //LCD112864第一行初始化
uchar idata lcd2[]={"【20时59分50秒】"}; //LCD12864第二行初始化
uchar idata lcd3[]={"【星期7 25.3度】"}; //LCD12864第三行初始化
uchar idata lcd4[]={"【xx☆xxnmxx】"}; //LCD12864第四行初始化
uchar code ds_18b20[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};//18b20只取一位小数部分,带4舍5入
uint time;
uchar time_dat[7]={11,7,4,10,23,59,50}; //1302年,星期,月,日,时,分,秒初始化
uchar write_adr[]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};//写年,星期,月,日,时,分,秒寄存器地址
uchar read_adr[]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81}; //读年,星期,月,日,时,分,秒寄存器地址
sbit sclk=P1^0; //1302时钟信号定义
sbit io=P1^1; //1302数据IO口定义
sbit ce=P1^2; //1302使能信号定义
sbit en=P1^3; //1602使能端口定义--高电平有效
sbit rw=P1^4; //1602读写端口定义--高电平为读,低电平为写
sbit rs=P1^5; //1602数据与命令端口定义--高电平为数据,低电平为地址
sbit dq=P1^6; //ds18b20端口定义
uchar tflag;
void delay_1ms()
{
uint i;
for(i=0;i<80;i++)
{
_nop_();
}
}
//18b20复位函数
uchar rst_ds18b20(void)
{
uchar flag;
dq=1; //dq先置高
for(time=0;time<6;time++); //延时一会
dq=0; //使总线为低电平
for(time=0;time<200;time++); //延时480-960us
dq=1; //dq释放
for(time=0;time<10;time++); //等待15-60us,使dq为低电平
flag=dq; //若dq为0则复位成功
for(time=0;time<200;time++); //延60-240us
return flag;
}
//18b20写数据函数
void write_ds18b20(uchar com)
{
uint i=0;
for(i=0;i<8;i++)
{
dq=1;
_nop_();
dq=0;
dq=com&0x01;
for(time=0;time<10;time++);
dq=1;
for(time=0;time<1;time++);
com>>=1;
}
for(time=0;time<4;time++);
}
//18b20读数据函数
uchar read_ds18b20(void)
{
uint i=0;
uchar temp=0;
for(i=8;i>0;i--)
{ dq=1;
_nop_();
dq=0;
_nop_();
dq=1;
for(time=0;time<2;time++);
temp>>=1;
if(dq==1)
temp|=0x80;
else
temp|=0x00;
for(time=0;time<8;time++);
}
return (temp);
}
//18b20读取温度函数
uchar set1_ds18b20()
{
uchar a,b;
rst_ds18b20(); //18b20复位
write_ds18b20(0xcc);//1个18b20跳过ROM搜索
write_ds18b20(0x44);//启动温度转换
for(time=0;time<200;time++);
rst_ds18b20(); //18b20再次复位
write_ds18b20(0xcc);//1个18b20再次跳过ROM搜索
write_ds18b20(0xbe);//再次启动温度转换
a=read_ds18b20(); //读取温度低八位
b=read_ds18b20(); //读取温度高八位
a=a&0xf0; //取低八位的高四位,低四位清零
a>>=4; //将高四位移之低四位
b<<=4; //高八位左移四位
b=b&0x70; //将第最高位和低四位清零
b+=a; //得到温度的整数部分
return (b); //返回整数部分温度值
}
uchar set2_ds18b20()
{
uchar a;
rst_ds18b20(); //18b20复位
write_ds18b20(0xcc);//1个18b20跳过ROM搜索
write_ds18b20(0x44);//启动温度转换
for(time=0;time<200;time++);
rst_ds18b20(); //18b20再次复位
write_ds18b20(0xcc);//1个18b20再次跳过ROM搜索
write_ds18b20(0xbe);//再次启动温度转换
a=read_ds18b20(); //读取温度低八位
a=a&0x0f; //取低八位的低四位,高四位清零
return (a); //返回小数部分的16进制数
}
//1302单字节写函数
void write_ds1302_byte(uchar dat)
{
uint i;
for(i=0;i<8;i++)
{
sclk=0;
io=dat&0x01;
dat=dat>>1;
sclk=1;
}
}
//1302单字节写地址,数据函数
void write_ds1302(uchar add,uchar dat)
{
ce=0;
_nop_();
sclk=0;
_nop_();
ce=1;
_nop_();
write_ds1302_byte(add);//写地址
write_ds1302_byte(dat);//写数据
ce=0;
_nop_();
io=1;
sclk=1;
}
//读取固定地址中的数据
uchar read_ds1302(uchar add)
{
uint i;
uchar temp;
ce=0;
_nop_();
sclk=0;
_nop_();
ce=1;
_nop_();
write_ds1302_byte(add);
for(i=0;i<8;i++)
{
temp=temp>>1;
sclk=0;
if(io)
temp=temp|0x80;
sclk=1;
}
ce=0;
_nop_();
sclk=0;
_nop_();
sclk=1;
io=1;
return temp;
}
//时钟设置函数
//将10进制数转化为16进制数
void set_rtc()
{
uchar i,j;
for(i=0;i<7;i++)
{
j=time_dat[i]/10; //10进制数十位
time_dat[i]=time_dat[i]%10; //10进制数十位
time_dat[i]=time_dat[i]+j*16; //16进制数
}
write_ds1302(0x8e,0x00); //禁止写保护
for(i=0;i<7;i++)
{
write_ds1302(write_adr[i],time_dat[i]); //循环7次分别写入年,星期,月,
} //日,时,分,秒的地址和数据。
write_ds1302(0x8e,0x80); //写保护
}
//读区地址中的数据函数
void read_rtc()
{
uchar i;
for(i=0;i<7;i++)
{
time_dat[i]=read_ds1302(read_adr[i]);
}
}
//将10进制数转化为字符数
void time_pro()
{
uchar aa=0,bb=0,cc=0;
cc=
aa=set1_ds18b20();
bb=set2_ds18b20();
lcd1[2]=(time_dat[0]>>4)+0x30; //年十位
lcd1[3]=(time_dat[0]&0x0f)+0x30; //年个位
lcd1[6]=(time_dat[2]>>4)+0x30; //月十位
lcd1[7]=(time_dat[2]&0x0f)+0x30; //月个位
lcd1[10]=(time_dat[3]>>4)+0x30; //日十位
lcd1[11]=(time_dat[3]&0x0f)+0x30; //日个位
lcd3[6]=(time_dat[1]&0x0f)+0x30; //星期
lcd2[2]=(time_dat[4]>>4)+0x30; //时十位
lcd2[3]=(time_dat[4]&0x0f)+0x30; //时个位
lcd2[6]=(time_dat[5]>>4)+0x30; //分十位
lcd2[7]=(time_dat[5]&0x0f)+0x30; //分个位
lcd2[10]=(time_dat[6]>>4)+0x30; //秒十位
lcd2[11]=(time_dat[6]&0x0f)+0x30; //秒个位
//lcd3[9]=(aa/100)+0x30; //温度百位
lcd3[8]=(aa%100/10)+0x30; //温度十位
lcd3[9]=(aa%100%10)+0x30; //温度个位
lcd3[11]=(ds_18b20[bb])+0x30; //温度小数部分
}
//12864忙信号检测
void check_busy()
{
uchar temp=0;
rs=0;
rw=1;
do
{
en=1;
_nop_();
temp=P2;
en=0;
}
while(temp&0x80);
}
//12864写指令函数
void write_command(uchar cmd)
{
check_busy();
rw=0;
rs=0;
en=0;
P2=cmd;
delay_1ms();
en=1;
delay_1ms();
en=0;
}
//写数据函数
void write_dat(uchar dat)
{
check_busy();
rs=1;
rw=0;
en=0;
P2=dat;
delay_1ms();
en=1;
delay_1ms();
en=0;
}
//12864显示函数
void display(uchar aa,uchar *add)
{
int a;
write_command(aa);//第一行
for(a=0;a<16;a++)
{
write_dat(*add);
add++;
delay_1ms();
}
}
void init_lcd()
{
write_command(0x30);//功能设定,基本指令集
delay_1ms();
write_command(0x02);//地址归为
delay_1ms();
write_command(0x0c);//显示状态开关,整体显示,游标关闭
delay_1ms();
write_command(0x01);//清除显示
delay_1ms();
write_command(0x06);//游标右移
delay_1ms();
write_command(0x80);//设置显示的起始位子
}
void main()
{
init_lcd();
set_rtc(); //1302时钟设置
while(1)
{
time_pro();
read_rtc(); //读取设置的时钟
display(0x80,lcd1);
display(0x90,lcd2);
display(0x88,lcd3);
display(0x98,lcd4);
}
}
#include
#include
#define uchar unsigned char
#define uint unsigned int
uchar idata lcd1[]={"2011年04月10日$$"}; //LCD112864第一行初始化
uchar idata lcd2[]={"【20时59分50秒】"}; //LCD12864第二行初始化
uchar idata lcd3[]={"【星期7 25.3度】"}; //LCD12864第三行初始化
uchar idata lcd4[]={"【xx☆xxnmxx】"}; //LCD12864第四行初始化
uchar code ds_18b20[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};//18b20只取一位小数部分,带4舍5入
uint time;
uchar time_dat[7]={11,7,4,10,23,59,50}; //1302年,星期,月,日,时,分,秒初始化
uchar write_adr[]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};//写年,星期,月,日,时,分,秒寄存器地址
uchar read_adr[]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81}; //读年,星期,月,日,时,分,秒寄存器地址
sbit sclk=P1^0; //1302时钟信号定义
sbit io=P1^1; //1302数据IO口定义
sbit ce=P1^2; //1302使能信号定义
sbit en=P1^3; //1602使能端口定义--高电平有效
sbit rw=P1^4; //1602读写端口定义--高电平为读,低电平为写
sbit rs=P1^5; //1602数据与命令端口定义--高电平为数据,低电平为地址
sbit dq=P1^6; //ds18b20端口定义
uchar tflag;
void delay_1ms()
{
uint i;
for(i=0;i<80;i++)
{
_nop_();
}
}
//18b20复位函数
uchar rst_ds18b20(void)
{
uchar flag;
dq=1; //dq先置高
for(time=0;time<6;time++); //延时一会
dq=0; //使总线为低电平
for(time=0;time<200;time++); //延时480-960us
dq=1; //dq释放
for(time=0;time<10;time++); //等待15-60us,使dq为低电平
flag=dq; //若dq为0则复位成功
for(time=0;time<200;time++); //延60-240us
return flag;
}
//18b20写数据函数
void write_ds18b20(uchar com)
{
uint i=0;
for(i=0;i<8;i++)
{
dq=1;
_nop_();
dq=0;
dq=com&0x01;
for(time=0;time<10;time++);
dq=1;
for(time=0;time<1;time++);
com>>=1;
}
for(time=0;time<4;time++);
}
//18b20读数据函数
uchar read_ds18b20(void)
{
uint i=0;
uchar temp=0;
for(i=8;i>0;i--)
{ dq=1;
_nop_();
dq=0;
_nop_();
dq=1;
for(time=0;time<2;time++);
temp>>=1;
if(dq==1)
temp|=0x80;
else
temp|=0x00;
for(time=0;time<8;time++);
}
return (temp);
}
//18b20读取温度函数
uchar set1_ds18b20()
{
uchar a,b;
rst_ds18b20(); //18b20复位
write_ds18b20(0xcc);//1个18b20跳过ROM搜索
write_ds18b20(0x44);//启动温度转换
for(time=0;time<200;time++);
rst_ds18b20(); //18b20再次复位
write_ds18b20(0xcc);//1个18b20再次跳过ROM搜索
write_ds18b20(0xbe);//再次启动温度转换
a=read_ds18b20(); //读取温度低八位
b=read_ds18b20(); //读取温度高八位
a=a&0xf0; //取低八位的高四位,低四位清零
a>>=4; //将高四位移之低四位
b<<=4; //高八位左移四位
b=b&0x70; //将第最高位和低四位清零
b+=a; //得到温度的整数部分
return (b); //返回整数部分温度值
}
uchar set2_ds18b20()
{
uchar a;
rst_ds18b20(); //18b20复位
write_ds18b20(0xcc);//1个18b20跳过ROM搜索
write_ds18b20(0x44);//启动温度转换
for(time=0;time<200;time++);
rst_ds18b20(); //18b20再次复位
write_ds18b20(0xcc);//1个18b20再次跳过ROM搜索
write_ds18b20(0xbe);//再次启动温度转换
a=read_ds18b20(); //读取温度低八位
a=a&0x0f; //取低八位的低四位,高四位清零
return (a); //返回小数部分的16进制数
}
//1302单字节写函数
void write_ds1302_byte(uchar dat)
{
uint i;
for(i=0;i<8;i++)
{
sclk=0;
io=dat&0x01;
dat=dat>>1;
sclk=1;
}
}
//1302单字节写地址,数据函数
void write_ds1302(uchar add,uchar dat)
{
ce=0;
_nop_();
sclk=0;
_nop_();
ce=1;
_nop_();
write_ds1302_byte(add);//写地址
write_ds1302_byte(dat);//写数据
ce=0;
_nop_();
io=1;
sclk=1;
}
//读取固定地址中的数据
uchar read_ds1302(uchar add)
{
uint i;
uchar temp;
ce=0;
_nop_();
sclk=0;
_nop_();
ce=1;
_nop_();
write_ds1302_byte(add);
for(i=0;i<8;i++)
{
temp=temp>>1;
sclk=0;
if(io)
temp=temp|0x80;
sclk=1;
}
ce=0;
_nop_();
sclk=0;
_nop_();
sclk=1;
io=1;
return temp;
}
//时钟设置函数
//将10进制数转化为16进制数
void set_rtc()
{
uchar i,j;
for(i=0;i<7;i++)
{
j=time_dat[i]/10; //10进制数十位
time_dat[i]=time_dat[i]%10; //10进制数十位
time_dat[i]=time_dat[i]+j*16; //16进制数
}
write_ds1302(0x8e,0x00); //禁止写保护
for(i=0;i<7;i++)
{
write_ds1302(write_adr[i],time_dat[i]); //循环7次分别写入年,星期,月,
} //日,时,分,秒的地址和数据。
write_ds1302(0x8e,0x80); //写保护
}
//读区地址中的数据函数
void read_rtc()
{
uchar i;
for(i=0;i<7;i++)
{
time_dat[i]=read_ds1302(read_adr[i]);
}
}
//将10进制数转化为字符数
void time_pro()
{
uchar aa=0,bb=0,cc=0;
cc=
aa=set1_ds18b20();
bb=set2_ds18b20();
lcd1[2]=(time_dat[0]>>4)+0x30; //年十位
lcd1[3]=(time_dat[0]&0x0f)+0x30; //年个位
lcd1[6]=(time_dat[2]>>4)+0x30; //月十位
lcd1[7]=(time_dat[2]&0x0f)+0x30; //月个位
lcd1[10]=(time_dat[3]>>4)+0x30; //日十位
lcd1[11]=(time_dat[3]&0x0f)+0x30; //日个位
lcd3[6]=(time_dat[1]&0x0f)+0x30; //星期
lcd2[2]=(time_dat[4]>>4)+0x30; //时十位
lcd2[3]=(time_dat[4]&0x0f)+0x30; //时个位
lcd2[6]=(time_dat[5]>>4)+0x30; //分十位
lcd2[7]=(time_dat[5]&0x0f)+0x30; //分个位
lcd2[10]=(time_dat[6]>>4)+0x30; //秒十位
lcd2[11]=(time_dat[6]&0x0f)+0x30; //秒个位
//lcd3[9]=(aa/100)+0x30; //温度百位
lcd3[8]=(aa%100/10)+0x30; //温度十位
lcd3[9]=(aa%100%10)+0x30; //温度个位
lcd3[11]=(ds_18b20[bb])+0x30; //温度小数部分
}
//12864忙信号检测
void check_busy()
{
uchar temp=0;
rs=0;
rw=1;
do
{
en=1;
_nop_();
temp=P2;
en=0;
}
while(temp&0x80);
}
//12864写指令函数
void write_command(uchar cmd)
{
check_busy();
rw=0;
rs=0;
en=0;
P2=cmd;
delay_1ms();
en=1;
delay_1ms();
en=0;
}
//写数据函数
void write_dat(uchar dat)
{
check_busy();
rs=1;
rw=0;
en=0;
P2=dat;
delay_1ms();
en=1;
delay_1ms();
en=0;
}
//12864显示函数
void display(uchar aa,uchar *add)
{
int a;
write_command(aa);//第一行
for(a=0;a<16;a++)
{
write_dat(*add);
add++;
delay_1ms();
}
}
void init_lcd()
{
write_command(0x30);//功能设定,基本指令集
delay_1ms();
write_command(0x02);//地址归为
delay_1ms();
write_command(0x0c);//显示状态开关,整体显示,游标关闭
delay_1ms();
write_command(0x01);//清除显示
delay_1ms();
write_command(0x06);//游标右移
delay_1ms();
write_command(0x80);//设置显示的起始位子
}
void main()
{
init_lcd();
set_rtc(); //1302时钟设置
while(1)
{
time_pro();
read_rtc(); //读取设置的时钟
display(0x80,lcd1);
display(0x90,lcd2);
display(0x88,lcd3);
display(0x98,lcd4);
}
}
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯