仪器社区

请教一个单片机时钟计时器c语言程序和原理图 注:不要复制的

凌魂丿灬泣 2011-10-21
评论
全部评论
严小华2009
//------------------------------------------------------------------
//名称:DS1302时钟
//------------------------------------------------------------------
//说明:从DS1302 中读取时钟数据,在LCD上显示日期和时间
//------------------------------------------------------------------
#include
#include
#include
#define uchar unsigned char
#define uint unsigned int

sbit IO=P1^0; //DS1302数据线
sbit SCLK=P1^1; //DS1302时钟线a
sbit RST=P1^2; //DS1302复位线

uchar WEEK[][4]={ "***","SUN","MON","TUS","WEN","THU","FRI","SAT"}; //亦可定义成指针数组*WEEK[]
uchar LCD_DSY_BUFFER1[]={"DATE 00-00-00 "};
uchar LCD_DSY_BUFFER2[]={"TIME 00:00:00 "};
uchar DateTime[7];
void Initialize_LCD();
void Display_LCD_String(uchar p,uchar *s);
void DelayMS(uint ms);
//------------------------------------------------------------------
//函数名称:Write_A_Byte_TO_DS1302(uchar x)
//函数功能:向DS1302写入一个字节
//输入参数:x 将要写入的数据
//返回值:无
//时序原理:在控制指令字输入后的下一个SCLK时钟的上升沿时数据被写入DS1302,数据输入从第0位开始
//------------------------------------------------------------------
void Write_A_Byte_TO_DS1302(uchar x)
{
uchar i;
SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备
for (i=0;i<8;i++)
{
IO=x & 0x01; //取出x的第0位数据写入1302
SCLK=1; //上升沿写入数据
SCLK=0; //重新拉低SCLK,形成脉冲
x >>=1; //将x的各数据位右移1位,准备写入下一个数据位
}
}
//------------------------------------------------------------------
//函数名称:Get_A_Byte_FROM_DS1302()
//函数功能:从DS1302读取一个字节
//输入参数:无
//返回值:读取的数据
//时序原理:在紧跟8位的控制指令字后的下一个SCLK时钟的下降沿时读出DS1302的数据,读出数据时从低位0位到高位7
//注意:DS1302中所存放的数据是BCD码,在读写时要注意转换
//例如:00011000,当把它视为二进制数时,其值为24;但作为2位BCD码时,其值为18。
//------------------------------------------------------------------
uchar Get_A_Byte_FROM_DS1302()
{
uchar i,b=0x00;
for (i=0;i<8;i++)
{
b |= _crol_((uchar)IO,i);//将uchar类型的IO数据左移i位
SCLK=1; //将SCLK置于高电平,为下降沿读出
SCLK=0; //时钟下降沿读取
}
return (b/16)*10+b%16; //从二进制数返回BCD码
}
//------------------------------------------------------------------
//函数名称:Read_Data(uchar addr)
//函数功能:从DS1302的指定寄存器读数据
//输入参数:addr 为读寄存器的地址
//返回值:dat 读取的数据
//命令字:也即读寄存器的地址 Z高位位7必须为1,位6如果为0表示存取日历数据,位5至位1表示操作单元的地址,位0为1表示读操作
//------------------------------------------------------------------
uchar Read_Data(uchar addr)
{
uchar dat;
RST=0; //拉低RST
SCLK=0; //确保写数据前SCLK被拉低
RST=1; //启动数据传输,只有在SCLK为低电平时才能将RST置为高电平
Write_A_Byte_TO_DS1302(addr); //写入命令字
dat=Get_A_Byte_FROM_DS1302();
SCLK=1; //将时钟电平置于已知状态
RST=0; //禁止数据传递
return dat;
}

//------------------------------------------------------------------
//函数名称:GetTime()
//函数功能:读取当前日期时间,将秒、分钟、小时、日期、月份、周日、年份七个数值分//别存入数组DateTime[0]~ DateTime[6]
//输入参数:无
//返回值:无
//------------------------------------------------------------------
void GetTime()
{
uchar i,addr =0x81;
for (i=0;i<7;i++)
{
DateTime[i] = Read_Data(addr);
addr+=2;
}
}
//------------------------------------------------------------------
//日期与时间值转换为数字字符
//------------------------------------------------------------------
void Format_DataTime(uchar d,uchar *a)
{
a[0]=d/10+'0';
a[1]=d%10+'0';
}

//------------------------------------------------------------------
//主程序
//------------------------------------------------------------------
void main()
{
Initialize_LCD();
while(1)
{
GetTime();
Format_DataTime(DateTime[6],LCD_DSY_BUFFER1+5); //0x8D 年份寄存器
Format_DataTime(DateTime[4],LCD_DSY_BUFFER1+8); //0x89 月份寄存器
Format_DataTime(DateTime[3],LCD_DSY_BUFFER1+11); //0x87 日期寄存器
//星期
strcpy (LCD_DSY_BUFFER1+13,WEEK[DateTime[5]]);//将字符串WEEK[DateTime[5]]复制到字符数组LCD_DSY_BUFFER1+13中
//0x8B 周日寄存器
Format_DataTime(DateTime[2],LCD_DSY_BUFFER2+5); //0x85 小时寄存器
Format_DataTime(DateTime[1],LCD_DSY_BUFFER2+8); //0x83 分钟寄存器
Format_DataTime(DateTime[0],LCD_DSY_BUFFER2+11); //0x81 秒寄存器

Display_LCD_String(0x00,LCD_DSY_BUFFER1); //diyi行显示年、月、日、星期几
Display_LCD_String(0x40,LCD_DSY_BUFFER2); //第二行显示小时、分钟、秒
}
}

//--------------------------------------------------------
//注意:1.本例中DS1302的属性设置为:自动根据PC的时间初始化。
//可以编程写入某个自定的初始时间,然后由该时间开始显示时钟。
//
//
//--------------------------------------------------------
3 0 2011-10-22 0条评论 回复
您可能感兴趣的社区主题
加载中...
发布 评论