⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 66.c

📁 IIC单片机时钟
💻 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 + -