求以下该图的流程图及c语言编程
发布网友
发布时间:2022-05-09 18:47
我来回答
共1个回答
热心网友
时间:2023-10-13 09:14
**************************************************
; 奥宇星单片机工作室
; http://www.aoyux.com
; Copyright 2009 aoyux McuStudio
; All rights Reserved
;作者:奥宇星 QQ:393193589
STC12C5406AD 晶振频率为11.0592MHz 指令周期:1.085069us/6
功能说明:DS1307,I2C总线的电子钟设计,含有后备电池,所以具有掉电走时功能!
DS1307价格低廉,走时准确,I2C总线,内部有08H~3FH共55个掉电保护RAM存储单元。
比DS1302之类的三总线的时钟芯片更节省I/O口线!
DS1307在各类电子、仪表,仪器、电子日历,等产品上得到广泛的应用。
显示:秒,分,时,星期,日,日期,月份,年。能显示:2000-2100年。润年自动调整。
备注:DS1307读和写都是BCD码,采用了十进制和BCD码之间的互换。
;********************************************************************************************/
#include "stc12c5410ad.h"//头文件
#include "intrins.h"//头文件
#define uchar unsigned char//宏定义
#define uint unsigned int//宏定义
sbit sda=P1^0;//;模拟I2C 数据传送位
sbit scl=P1^2;//;模拟I2C 时钟控制状态标志
sbit RS=P3^4;//LCD1602定义I/O的硬件接口
sbit E=P3^7;//LCD1602定义I/O的硬件接口
sbit A_B=P3^2;//74HC164接口
sbit CP=P3^3;//74HC164接口
uchar Hours;//定义小时
uchar Minutes;//定义分钟
uchar Seconds;//定义秒
uchar Year;//定义年
uchar Month;//定义月
uchar Date;//定义日期
uchar Weeks;//定义星期
uchar DispBuf[16]; //6字节的显示缓冲区
uchar code disp_tab[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char char_char_1[]={" www.aoyux.com "};//定义字符串
void delay_2(uint z)//1ms延时
{
uchar x,x1;
for(;z>0;z--)
{
for(x=0;x<114;x++)
{
for(x1=0;x1<1;x1++);
}
}
}
void delay()//5us延时
{
_nop_();
_nop_();
_nop_();
}
void write_Directive(uchar a)//写指令
{
uchar i,temp;
for(i=0;i<8;i++)
{
temp=a;
temp&=0x80;
if(temp==0x80)
A_B=1;
else
A_B=0;
a=a<<1;
delay();
CP=0;
delay();
CP=1;
delay();
CP=0;
}
RS=0;
delay_2(3);
E=0;
delay_2(3);
E=1;
delay_2(3);
E=0;
delay_2(3);
}
void write_Data(uchar a)//写数据
{
uchar i,temp;
for(i=0;i<8;i++)
{
temp=a;
temp&=0x80;
if(temp==0x80)
A_B=1;
else
A_B=0;
a=a<<1;
delay();
CP=0;
delay();
CP=1;
delay();
}
RS=1;
delay_2(3);
E=0;
delay_2(3);
E=1;
delay_2(3);
E=0;
delay_2(3);
}
void star()//开始
{
sda=1;
delay();//5us延时
scl=1;
delay();//5us延时
sda=0;
delay();//5us延时
}
void stop()//停止
{
sda=0;
delay();//5us延时
scl=1;
delay();//5us延时
sda=1;
delay();//5us延时
}
void ack()//应答
{ uchar z=0;
while((sda==1)&&(z<50))z++;//条件判断, sda=1,则没有应答。如果没有应答则延时:z<50,z++;后返回
scl=0;
delay();//5us延时
}
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
///写一个数据函数
//器件写地址 slave_write_address
//字节地址 byte_address
//待写入数据 data_data
void write(uchar slave_write_address,uchar byte_address,uchar data_data)//写一个数据
{
uchar temp,temp1,i,ii;
star();//开始
for(ii=0;ii<3;ii++)//根据 24CXX文档资料,和时序图,按顺序送:器件写地址,字节地址,数据
{
if(ii==0)
{
temp=slave_write_address;//送 器件写地址
temp1=slave_write_address;
}
else if(ii==1)
{
temp=byte_address;//送 字节地址
temp1=byte_address;
}
else if(ii==2)
{
temp=data_data;//送 数据
temp1=data_data;
}
for(i=0;i<8;i++)
{
scl=0;
delay();//5us延时
temp=temp1;
temp=temp&0x80;// 相 与 后,把不相关的位清零
if(temp==0x80)//根据前面 相 与 后,判断 temp是否等于0x80,是则该位为 1
sda=1;
else
sda=0;
delay();//5us延时
scl=1;
delay();//5us延时
scl=0;
delay();//5us延时
temp1=temp1<<1;//向左移出1位
}
sda=1;
delay();//5us延时
scl=1;
delay();//5us延时
ack();
}
stop();//停止
}
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
///读一个数据函数
//器件写地址 slave_write_address
//器件读地址 slave_read_address
//字节地址 byte_address
//读出的数据 data_data
read(uchar slave_write_address,uchar byte_address,uchar slave_read_address)//读一个数据
{
uchar temp,temp1,i,ii,x,data_data;
star();//开始
for(ii=0;ii<3;ii++)//根据 24CXX文档资料,和时序图,按顺序送:器件写地址,字节地址,器件读地址
{
if(ii==0)
{
temp=slave_write_address;//送 器件写地址
temp1=slave_write_address;
}
else if(ii==1)
{
temp=byte_address;//送 字节地址
temp1=byte_address;
}
else if(ii==2)
{
star();//开始
temp=slave_read_address;//送 器件读地址
temp1=slave_read_address;
}
for(i=0;i<8;i++)//开始读数据
{
scl=0;
delay();//5us延时
temp=temp1;
temp=temp&0x80;// 相 与 后,把不相关的位清零
if(temp==0x80)//根据前面 相 与 后,判断 temp是否等于0x80,是则该位为 1
sda=1;
else
sda=0;
delay();//5us延时
scl=1;
delay();//5us延时
scl=0;
delay();//5us延时
temp1=temp1<<1;//向左移出1位
}
sda=1;
delay();//5us延时
scl=1;
delay();//5us延时
ack();//应答
}
for(x=0;x<8;x++)
{
data_data=data_data<<1;//向左移入1位
sda=1;
delay();//5us延时
scl=0;
delay();//5us延时
scl=1;
delay();//5us延时
if(sda==1)//判断 数据线是否是高电平
data_data|=0x01;//把读到的数据 或 0X01
//else
//data_data|=0x00;
}
ack();//应答
stop();//停止
return data_data;//返回读到的数据
}
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
void init()//初始化
{
// uchar i;
CP=1;
A_B=1;
Hours=0;
Minutes=0;
Seconds=0;
Year=0;
Month=0;
Date=0;
Weeks=0;
delay_2(15);
write_Directive(0x38);
delay_2(5);
write_Directive(0x38);
delay_2(5);
write_Directive(0x38);
write_Directive(0x01);
write_Directive(0x02);///初始化后数据地址为0x80;即第一行,第一个位置
write_Directive(0x0c);
// write_Directive(0x80+0x40);//第二行第一位地址
// for(i=0;i<16;i++)
//{
// write_Data(char_char_1[i]);//显示字符串" www.aoyux.com "
// }
}
void Show()//显示
{
write_Directive(0x80+3);//第一行,第3个位置地址
DispBuf[0]=disp_tab[(Hours/10)];//
DispBuf[1]=disp_tab[(Hours%10)];//
write_Data(DispBuf[0]);//
write_Data(DispBuf[1]);//
write_Data(':');//
DispBuf[2]=disp_tab[(Minutes/10)];//
DispBuf[3]=disp_tab[(Minutes%10)];//
write_Data(DispBuf[2]);//
write_Data(DispBuf[3]);//
write_Data(':');//
DispBuf[4]=disp_tab[(Seconds/10)];//
DispBuf[5]=disp_tab[(Seconds%10)];//
write_Data(DispBuf[4]);//
write_Data(DispBuf[5]);//
write_Data(' ');//
write_Data(' ');//
write_Data(' ');//?
write_Data(' ');//
write_Directive(0x80+0x40);//
DispBuf[7]=disp_tab[(Year/10)];//
DispBuf[8]=disp_tab[(Year%10)];//
write_Data('2');//
write_Data('0');//
write_Data(DispBuf[7]);//
write_Data(DispBuf[8]);//
write_Data(' ');//
DispBuf[9]=disp_tab[(Month/10)];//
DispBuf[10]=disp_tab[(Month%10)];//
write_Data(DispBuf[9]);//
write_Data(DispBuf[10]);//
write_Data(' ');//
DispBuf[11]=disp_tab[(Date/10)];//
DispBuf[12]=disp_tab[(Date%10)];//
write_Data(DispBuf[11]);//
write_Data(DispBuf[12]);//
write_Data(' ');//
write_Data(' ');//
write_Data(' ');//
DispBuf[14]=disp_tab[Weeks];//
write_Data(DispBuf[14]);//
}
Decimal_to_BCD(uchar temp)//十进制转换成BCD码
{
uchar a,b,c;
a=temp;
b=0;
if(a>=10)
{
while(a>=10)
{
a=a-10;
b=b+16;
c=a+b;
temp=c;
}
}
return temp;
}
BCD_to_Decimal(uchar temp)//BCD码转换成十进制
{
uchar a,b,c;
a=temp;
b=0;
if(a>=16)
{
while(a>=16)
{
a=a-16;
b=b+10;
c=a+b;
temp=c;
}
}
return temp;
}
void main()
{
init();
//////////////////////////////////////////////////////////////////////////////////////////////
//向器件写一个数据:(0xd0 是器件写地址;0x01~06 是秒~年寄存器;Seconds~Year 是待写入的数据)//
Seconds=Decimal_to_BCD(Seconds);//十进制转换成BCD码
Minutes=Decimal_to_BCD(Minutes);//十进制转换成BCD码
Hours=Decimal_to_BCD(Hours);//十进制转换成BCD码
Date=Decimal_to_BCD(Date);//十进制转换成BCD码
Year=Decimal_to_BCD(Year);//十进制转换成BCD码
Month=Decimal_to_BCD(Month);//十进制转换成BCD码
write(0xd0,0x00,Seconds);//写入秒
write(0xd0,0x01,Minutes);//写入分
write(0xd0,0x02,Hours);//写入时
write(0xd0,0x03,Weeks);//写入星期
write(0xd0,0x04,Date);//写入日期
write(0xd0,0x05,Month);//写入月
write(0xd0,0x06,Year);//写入年
///////////////////////////////////////////////////////////////////////////////////////////////
while(1)
{
//向器件读一个数据:(0xd0 是 DS1307 器件写地址;0x01~06 是秒~年寄存器;0xd1 是 DS1307 器件读地址)
Seconds=read(0xd0,0x00,0xd1);
Seconds=BCD_to_Decimal(Seconds);//BCD码转换成十进制
Minutes=read(0xd0,0x01,0xd1);
Minutes=BCD_to_Decimal(Minutes);//BCD码转换成十进制
Hours=read(0xd0,0x02,0xd1);
Hours=BCD_to_Decimal(Hours);//BCD码转换成十进制
Weeks=read(0xd0,0x03,0xd1);//星期为:1~7 不需要进制的转换
Date=read(0xd0,0x04,0xd1);
Date=BCD_to_Decimal(Date);//BCD码转换成十进制
Month=read(0xd0,0x05,0xd1);
Month=BCD_to_Decimal(Month);//BCD码转换成十进制
Year=read(0xd0,0x06,0xd1);
Year=BCD_to_Decimal(Year);//BCD码转换成十进制
Show();//显示
delay_2(300);//每隔300mS读一次数据
}
}
随便一搜就有,稍微改改就可以用,试试吧!
good luck!
电子单片机团====步行者