📄 66.c
字号:
#include<reg52.h>
#include<intrins.h>
#include "string.h"
#define DelayTime 10 //DelayTime用于控制IIC的速度,有些器件可能并不支持高速的IIC通信
//可以调整DelayTime来调节IIC的速度
sbit speak=P1^4;
struct Time //时间结构体,包括了秒,分,时,日,周,月,年
{
unsigned char second;
unsigned char minute;
unsigned char hour;
unsigned char day;
unsigned char week;
unsigned char month;
unsigned char year;
};
extern struct Time time; //用来装时间数据,需要在外部定义
//函数声明
unsigned char P8563_Read_Time();
unsigned char P8563_Set_Time();
void delay1(unsigned int i)
{
while(i--);
}
void delay(unsigned int time)
{
while(time--);
}
unsigned char table[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //数字表
//端口定义
sbit SCL=P1^0; //IIC的时钟线
sbit SDA=P1^1; //IIC的数据线
//函数声明
void IIC_Start();
void IIC_Stop();
void IIC_Ack();
void IIC_NAck();
unsigned char IIC_Get_Ack();
unsigned char IIC_Write_Byte(unsigned char dat);
unsigned char IIC_Read_Byte();
struct Time time; //用于装载时间数据的结构体型的变量time
void IIC_Start()
{
SDA=1;
delay(DelayTime);
SCL=1;
delay(DelayTime);
SDA=0;
delay(DelayTime);
SCL=0;
delay(DelayTime);
}
/******************************************************************
- 功能描述:IIC结束
- 隶属模块:IIC模块
- 函数属性:外部,供用户使用
- 参数说明:无
- 返回说明:无
- 注:无
******************************************************************/
void IIC_Stop()
{
SDA=0;
delay(DelayTime);
SCL=1;
delay(DelayTime);
SDA=1;
delay(DelayTime);
SCL=0;
delay(DelayTime);
}
/*********************************************************************
- 功能描述:主设备发出应答
- 隶属模块:IIC模块
- 函数属性:外部,供用户使用
- 参数说明:无
- 返回说明:无
- 注:主设备(比如单片机),从从设备(比如PCF8563、AT24C64)读取字节后,如果
要继续读取,就要给从设备一个ACK(即所谓的“应答”,数据位SDA为0)
*********************************************************************/
void IIC_Ack()
{
SDA=0;
delay(DelayTime);
SCL=1;
delay(DelayTime);
SCL=0;
delay(DelayTime);
}
/*********************************************************************
- 功能描述:主设备发出无应答
- 隶属模块:IIC模块
- 函数属性:外部,供用户使用
- 参数说明:无
- 返回说明:无
- 注:主设备(比如单片机),从从设备(比如PCF8563、AT24C64)读取字节后,如果不再
进行读取,就要给从设备一个NACK(即所谓的“无应答”,数据位SDA为1)
*********************************************************************/
void IIC_NAck()
{
SDA=1;
delay(DelayTime);
SCL=1;
delay(DelayTime);
SCL=0;
delay(DelayTime);
}
/*********************************************************************
- 功能描述:主设备检测从设备应答
- 隶属模块:IIC模块
- 函数属性:外部,供用户使用
- 参数说明:无
- 返回说明:从设备的应答值
- 注:主设备(比如单片机),向从设备(比如PCF8563、AT24C64)写入字节后,要检测从
设备发出的应答,如果数据位SDA为0,说明向从设备成功写入了字节
*********************************************************************/
unsigned char IIC_Get_Ack()
{
unsigned char Error;
SDA=1;
delay(DelayTime);
SCL=1;
delay(DelayTime);
Error=SDA;
delay(DelayTime);
SCL=0;
delay(DelayTime);
return Error;
}
/*********************************************************************
- 功能描述:主设备向从设备写入一字节
- 隶属模块:IIC模块
- 函数属性:外部,供用户使用
- 参数说明:dat:将要写入的字节
- 返回说明:从设备的应答值
- 注:向从设备写入一个字节,并返回从设备的应答值
*********************************************************************/
unsigned char IIC_Write_Byte(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
SDA=((dat<<i)&0x80);
SCL=1;
delay(DelayTime);
SCL=0;
delay(DelayTime);
}
return IIC_Get_Ack();
}
/*********************************************************************
- 功能描述:主设备从从设备读取一字节
- 隶属模块:IIC模块
- 函数属性:外部,供用户使用
- 参数说明:无
- 返回说明:读到的字节
- 注:无
*********************************************************************/
unsigned char IIC_Read_Byte()
{
unsigned char i,rbyte=0;
SDA=1;
for(i=0;i<8;i++)
{
SCL=1;
delay(DelayTime);
if(SDA) rbyte|=(0x80>>i);
SCL=0;
delay(DelayTime);
}
return rbyte;
}
unsigned char PCF8563_Write_Bytes(unsigned char addr,unsigned char length,unsigned char *pbuf)
{
unsigned char i=0;
IIC_Start(); //IIC通信开始
if(IIC_Write_Byte(0xa2)) return 1; //写PCF8563的ID与读写控制位,通信有错误立即返回
if(IIC_Write_Byte(addr)) return 1; //写寄存器地址
for(i=0;i<length;i++) //写入length个字节
{
if(IIC_Write_Byte(pbuf[i])) return 1;//写数据
}
IIC_Stop();
return 0;
}
/******************************************************************
- 功能描述:从地址addr的寄存器读取多个字节
- 隶属模块:PCF8563驱动模块
- 函数属性:内部
- 参数说明:addr:寄存器地址
length:要读出的字节数
pbuf:指向数据缓冲区的指针
- 返回说明:操作结果,0表示成功,1表示失败
- 注:无
******************************************************************/
unsigned char PCF8563_Read_Bytes(unsigned char addr,unsigned char length,unsigned char *pbuf) //从地址addr连续读取length个字节到pbuf
{
unsigned char i=0,err=0;
IIC_Start(); //IIC通信开始
if(IIC_Write_Byte(0xa2)) return 1; //写PCF8563的ID与读写控制位,通信有错误立即返回
if(IIC_Write_Byte(addr)) return 1; //写寄存器地址
IIC_Start(); //IIC通信开始
if(IIC_Write_Byte(0xa3)) return 1; //写PCF8563的ID与读写控制位
for(i=0;i<length-1;i++) //写入前length-1个字节,并作出应答
{
pbuf[i]=IIC_Read_Byte();
IIC_Ack();
}
pbuf[i]=IIC_Read_Byte(); //写入最后一个字节,并作出无应答
IIC_NAck();
IIC_Stop();
return 0;
}
/******************************************************************
- 功能描述:将BCD码转换为十进制的数值
- 隶属模块:PCF8563驱动模块
- 函数属性:内部
- 参数说明:x:待转换的BCD码字节
- 返回说明:转换后的值
- 注:将BCD格式数据转为实际的值,如29的BCD格式为0x29,实际值为0x1d
******************************************************************/
unsigned char BCD2Val(unsigned char x)
{
return (x>>4)*10+(x&0x0f); //高4位乘以10,再加上低4位,即得到数值
}
/******************************************************************
- 功能描述:将十进制的数值转换为BCD码
- 隶属模块:PCF8563驱动模块
- 函数属性:内部
- 参数说明:x:待转换的数值
- 返回说明:转换后的值
- 注:将值转为BCD格式,如 23转为BCD格式为 0x23
******************************************************************/
unsigned char Val2BCD(unsigned char x)
{
return (x/10)*16+(x%10); //将十进制的数值十位乘以16,再加上个位,即得到BCD码
}
/******************************************************************
- 功能描述:读取时间
- 隶属模块:PCF8563驱动模块
- 函数属性:外部,供用户使用
- 参数说明:无
- 返回说明:操作结果,0表示成功,1表示失败
- 注:从PCF8563中读到的时间值,被装载到全局的外部结构体变量time中
******************************************************************/
unsigned char P8563_Read_Time()
{
unsigned char temp[7];
if(!PCF8563_Read_Bytes(0x02,7,temp)) //读取时间,即读取PCF8563的时间寄存器,地址从0x02开始
{
//以下对读取到temp数组中的时间数据进行截取
//并转换为十进制数值写入到time中去
time.second=BCD2Val(temp[0]&0x7f); //秒
time.minute=BCD2Val(temp[1]&0x7f); //分
time.hour =BCD2Val(temp[2]&0x3f); //小时
time.day =BCD2Val(temp[3]&0x3f); //日
time.week =BCD2Val(temp[4]&0x07); //星期
time.month =BCD2Val(temp[5]&0x1f); //月
time.year =BCD2Val(temp[6] ); //年
return 0;
}
else
return 1;
}
/******************************************************************
- 功能描述:设置时间
- 隶属模块:PCF8563驱动模块
- 函数属性:外部,供用户使用
- 参数说明:无
- 返回说明:操作结果,0表示成功,1表示失败
- 注:在设置时间前先将时间数据填充到time中去,随后调用此函数,时间
数据即被写入到PCF8563中,并以新设置的时间继续走时
******************************************************************/
unsigned char P8563_Set_Time()
{
unsigned char temp[7];
unsigned char i;
for(i=0;i<7;i++)
{
temp[i]=Val2BCD(((unsigned char *)(&time))[i]);//将time中的时间数据转换为BCD格式,并写入到temp数组中
}
return PCF8563_Write_Bytes(0x02,7,temp); //将temp数组的数据写入到PCF8563中
}
/******************************************************************
- 功能描述:设置倒计时寄存器
- 隶属模块:PCF8563驱动模块
- 函数属性:外部,供用户使用
- 参数说明:无
- 返回说明:操作结果,0表示成功,1表示失败
- 注:先将要写入到倒计时寄存器的数据装入全局外部结构体变量dcounter中
随后调动此函数将数据写入
******************************************************************/
/******************************************************************
- 功能描述:读取倒计时寄存器
- 隶属模块:PCF8563驱动模块
- 函数属性:外部,供用户使用
- 参数说明:无
- 返回说明:操作结果,0表示成功,1表示失败
- 注:将倒计时寄存器的值读回到dcounter中
******************************************************************/
/******************************************************************
- 功能描述:将一个字符串转为32位的变量,比如"1234"转为1234
- 隶属模块:公开函数模块
- 函数属性:外部,用户可调用
- 参数说明:str:指向待转换的字符串
- 返回说明:转换后的数值
******************************************************************/
unsigned long strtou32(char *str)
{
unsigned long temp=0;
unsigned long fact=1;
unsigned char len=strlen(str);
unsigned char i;
for(i=len;i>0;i--)
{
temp+=((str[i-1]-0x30)*fact);
fact*=10;
}
return temp;
}
void xianshi()
{
P0=0xfe;
P3=0xff;
P2=table[time.month/10];
delay1(12);
P2=0xff;
delay1(2);
P0=0xfd;
P3=0xff;
P2=table[time.month%10];
delay1(12);
P2=0xff;
delay1(2);
P0=0xfb;
P3=0xff;
P2=table[time.day/10];
delay1(12);
P2=0xff;
delay1(2);
P0=0xf7;
P3=0xff;
P2=table[time.day%10];
delay1(12);
P2=0xff;
delay1(2);
P0=0xef;
P3=0xff;
P2=table[0];
delay1(12);
P2=0xff;
delay1(2);
P0=0xdf;
P3=0xff;
P2=table[time.week%10];
delay1(12);
P2=0xff;
delay1(2);
P0=0xbf;
P3=0xff;
P2=table[time.second/10];
delay1(15);
P2=0xff;
delay1(2);
P0=0x7f;
P3=0xff;
P2=table[time.second%10];
delay1(12);
P2=0xff;
P3=0x7f;
P0=0xff;
P2=table[time.hour/10];
delay1(12);
P2=0xff;
delay(2);
P3=0xbf;
P0=0xff;
P2=table[time.hour%10];
delay1(12);
P2=0xff;
delay1(2);
P3=0xdf;
P0=0xff;
P2=table[time.minute/10];
delay1(12);
P2=0xff;
delay1(2);
P3=0xf7;
P0=0xff;
P2=table[time.minute%10];
delay1(12);
P2=0xff;
delay1(2);
P3=0xc7;
P0=0xff;
P2=0x7f;
delay1(12);
P2=0xff;
}
void main()
{
/*time.year =12; //向time中装入要设置的时间数据
time.month = 3;
time.day =6;
time.hour =21;
time.minute=7;
time.second=30;
time.week = 2;
P8563_Set_Time(); //设置时间,即将time中的时间数据写入PCF8563 */
while(1) //循环
{
P8563_Read_Time(); //读取时间
xianshi();
}
while(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -